1 /* 2 Copyright (c) 2013 - 2019, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef IPA_NAT_DRVI_H 31 #define IPA_NAT_DRVI_H 32 33 #include <stdio.h> 34 #include <sys/ioctl.h> 35 #include <sys/types.h> 36 #include <fcntl.h> 37 #include <sys/mman.h> 38 #include <linux/msm_ipa.h> 39 #include <netinet/in.h> 40 #include <sys/inotify.h> 41 #include <errno.h> 42 #include <pthread.h> 43 #include <unistd.h> 44 45 #include "ipa_nat_logi.h" 46 47 #define NAT_DUMP 48 49 /*======= IMPLEMENTATION related data structures and functions ======= */ 50 #ifdef IPA_ON_R3PC 51 #define NAT_MMAP_MEM_SIZE (2 * 1024UL * 1024UL - 1) 52 #endif 53 54 #define IPA_DEV_NAME "/dev/ipa" 55 #define NAT_DEV_DIR "/dev" 56 #define NAT_DEV_NAME "ipaNatTable" 57 #define NAT_DEV_FULL_NAME "/dev/ipaNatTable" 58 59 #define IPA_NAT_TABLE_VALID 1 60 #define IPA_NAT_MAX_IP4_TBLS 1 61 #define IPA_NAT_BASE_TABLE_PERCENTAGE .8 62 #define IPA_NAT_EXPANSION_TABLE_PERCENTAGE .2 63 64 #define IPA_NAT_NUM_OF_BASE_TABLES 2 65 #define IPA_NAT_UNUSED_BASE_ENTRIES 2 66 67 #define IPA_NAT_RULE_FLAG_FIELD_OFFSET 18 68 #define IPA_NAT_RULE_NEXT_FIELD_OFFSET 8 69 #define IPA_NAT_RULE_PROTO_FIELD_OFFSET 22 70 71 #define IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET 2 72 #define IPA_NAT_INDEX_RULE_NAT_INDEX_FIELD_OFFSET 0 73 74 #define IPA_NAT_RULE_FLAG_FIELD_SIZE 2 75 #define IPA_NAT_RULE_NEXTFIELD_FIELD_SIZE 2 76 77 #define IPA_NAT_FLAG_ENABLE_BIT_MASK 0x8000 78 #define IPA_NAT_FLAG_DISABLE_BIT_MASK 0x0000 79 80 #define IPA_NAT_FLAG_ENABLE_BIT 1 81 #define IPA_NAT_FLAG_DISABLE_BIT 0 82 83 #define IPA_NAT_INVALID_PROTO_FIELD_VALUE 0xFF00 84 85 #define IPA_NAT_INVALID_INDEX 0xFF 86 #define IPA_NAT_INVALID_NAT_ENTRY 0x0 87 88 #define INDX_TBL_ENTRY_SIZE_IN_BITS 16 89 90 /* ----------- Rule id ----------------------- 91 92 ------------------------------------------------ 93 | 3bits | 12 bits | 1 bit | 94 ------------------------------------------------ 95 | reserved | index into table | 0 - base | 96 | | | 1 - expansion | 97 ------------------------------------------------ 98 99 */ 100 #define IPA_NAT_RULE_HDL_TBL_TYPE_BITS 0x1 101 #define IPA_NAT_RULE_HDL_TBL_TYPE_MASK 0x1 102 103 /* ----------- sw specif parameter ----- 104 ------------------------------------ 105 | 16 bits | 16 bits | 106 ------------------------------------ 107 | index table | prev index | 108 | entry | | 109 ------------------------------------ 110 -----------------------------------------*/ 111 #define IPA_NAT_SW_PARAM_PREV_INDX_BYTE 0 112 #define IPA_NAT_SW_PARAM_INDX_TBL_ENTRY_BYTE 1 113 114 typedef enum { 115 IPA_NAT_BASE_TBL = 0, 116 IPA_NAT_EXPN_TBL = 1, 117 IPA_NAT_INDX_TBL = 2, 118 IPA_NAT_INDEX_EXPN_TBL = 3, 119 } nat_table_type; 120 121 typedef enum { 122 NEXT_INDEX_FIELD, 123 PUBLIC_PORT_FILED, 124 PRIVATE_PORT_FIELD, 125 TARGET_PORT_FIELD, 126 IP_CHKSUM_FIELD, 127 ENABLE_FIELD, 128 TIME_STAMP_FIELD, 129 PROTOCOL_FIELD, 130 TCP_UDP_CHKSUM_FIELD, 131 SW_SPEC_PARAM_PREV_INDEX_FIELD, 132 SW_SPEC_PARAM_INDX_TBL_ENTRY_FIELD, 133 INDX_TBL_TBL_ENTRY_FIELD, 134 INDX_TBL_NEXT_INDEX_FILED 135 } ipa_nat_rule_field_type; 136 137 /* 138 --------------------------------------------- 139 | 3 | 2 | 1 | 0 | 140 --------------------------------------------- 141 | Public Port(2B) | Next Index(2B) | 142 --------------------------------------------- 143 */ 144 typedef struct { 145 uint32_t next_index:16; 146 uint32_t public_port:16; 147 } next_index_pub_port; 148 149 150 /* 151 --------------------------------------------- 152 | 3 | 2 | 1 | 0 | 153 --------------------------------------------- 154 | Flags(2B) | IP check sum Diff(2B)| 155 |EN|FIN|Resv | | | 156 --------------------------------------------- 157 */ 158 typedef struct { 159 uint32_t ip_chksum:16; 160 uint32_t rsvd1:14; 161 uint32_t redirect:1; 162 uint32_t enable:1; 163 } ipcksum_enbl; 164 165 166 /* 167 --------------------------------------- 168 | 7 | 6 | 5 | 4 | 169 --------------------------------------- 170 | Proto | TimeStamp(3B) | 171 | (1B) | | 172 --------------------------------------- 173 */ 174 typedef struct { 175 uint32_t time_stamp:24; 176 uint32_t protocol:8; 177 } time_stamp_proto; 178 179 180 /* 181 --------------------------------------------- 182 | 3 | 2 | 1 | 0 | 183 --------------------------------------------- 184 | next_index | Table entry | 185 ---------------------------------------------- 186 */ 187 typedef struct { 188 uint16_t tbl_entry; 189 uint16_t next_index; 190 } tbl_ent_nxt_indx; 191 192 /*-------------------------------------------------- 193 32 bit sw_spec_params is interpreted as follows 194 ------------------------------------ 195 | 16 bits | 16 bits | 196 ------------------------------------ 197 | index table | prev index | 198 | entry | | 199 ------------------------------------ 200 --------------------------------------------------*/ 201 typedef struct { 202 uint16_t prev_index; 203 uint16_t index_table_entry; 204 } sw_spec_params; 205 206 /*------------------------ NAT Table Entry --------------------------------------- 207 208 ----------------------------------------------------------------------------------- 209 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 210 ----------------------------------------------------------------------------------- 211 | Target IP(4B) | Private IP(4B) | 212 ----------------------------------------------------------------------------------- 213 |Target Port(2B) | Private Port(2B) | Public Port(2B) | Next Index(2B) | 214 ----------------------------------------------------------------------------------- 215 | Proto | TimeStamp(3B) | Flags(2B) | IP check sum Diff(2B)| 216 | (1B) | |EN|FIN|Resv | | | 217 ----------------------------------------------------------------------------------- 218 | TCP/UDP checksum |PDN info| Reserved| SW Specific Parameters(4B) | 219 | diff (2B) | (1B) | (1B) | | 220 ----------------------------------------------------------------------------------- 221 222 Dont change below structure definition. 223 It should be same as above(little endian order) 224 -------------------------------------------------------------------------------*/ 225 struct ipa_nat_rule { 226 uint64_t private_ip:32; 227 uint64_t target_ip:32; 228 229 uint64_t nxt_indx_pub_port:32; 230 uint64_t private_port:16; 231 uint64_t target_port:16; 232 233 uint64_t ip_cksm_enbl:32; 234 uint64_t ts_proto:32; 235 236 /*-------------------------------------------------- 237 32 bit sw_spec_params is interpreted as follows 238 ------------------------------------ 239 | 16 bits | 16 bits | 240 ------------------------------------ 241 | index table | prev index | 242 | entry | | 243 ------------------------------------ 244 --------------------------------------------------*/ 245 uint64_t sw_spec_params:32; 246 247 uint64_t rsvd2:8; 248 249 /*----------------------------------------- 250 8 bit PDN info is interpreted as following 251 ------------------------------------ 252 | 4 bits | 4 bits | 253 ------------------------------------ 254 | PDN index | reserved | 255 | | | 256 ------------------------------------ 257 -------------------------------------------*/ 258 uint64_t rsvd3:4; 259 uint64_t pdn_index:4; 260 uint64_t tcp_udp_chksum:16; 261 }; 262 263 struct ipa_nat_sw_rule { 264 uint64_t private_ip:32; 265 uint64_t target_ip:32; 266 267 uint64_t next_index:16; 268 uint64_t public_port:16; 269 uint64_t private_port:16; 270 uint64_t target_port:16; 271 272 uint64_t ip_chksum:16; 273 uint64_t rsvd1:14; 274 uint64_t redirect:1; 275 uint64_t enable:1; 276 uint64_t time_stamp:24; 277 uint64_t protocol:8; 278 279 /*-------------------------------------------------- 280 32 bit sw_spec_params is interpreted as follows 281 ------------------------------------ 282 | 16 bits | 16 bits | 283 ------------------------------------ 284 | index table | prev index | 285 | entry | | 286 ------------------------------------ 287 --------------------------------------------------*/ 288 uint64_t prev_index:16; 289 uint64_t indx_tbl_entry:16; 290 uint64_t rsvd2 :8; 291 /*----------------------------------------- 292 8 bit PDN info is interpreted as following 293 ------------------------------------ 294 | 4 bits | 4 bits | 295 ------------------------------------ 296 | PDN index | reserved | 297 | | | 298 ------------------------------------ 299 -------------------------------------------*/ 300 uint64_t rsvd3 :4; 301 uint64_t pdn_index :4; 302 uint64_t tcp_udp_chksum:16; 303 }; 304 #define IPA_NAT_TABLE_ENTRY_SIZE 32 305 #define IPA_NAT_INDEX_TABLE_ENTRY_SIZE 4 306 307 struct ipa_nat_indx_tbl_rule { 308 uint32_t tbl_entry_nxt_indx; 309 }; 310 311 struct ipa_nat_sw_indx_tbl_rule { 312 uint16_t tbl_entry; 313 uint16_t next_index; 314 }; 315 316 struct ipa_nat_indx_tbl_meta_info { 317 uint16_t prev_index; 318 }; 319 320 struct ipa_nat_ip4_table_cache { 321 uint8_t valid; 322 uint32_t public_addr; 323 324 int nat_fd; 325 int size; 326 uint32_t tbl_addr_offset; 327 char table_name[IPA_RESOURCE_NAME_MAX]; 328 329 char *ipv4_rules_addr; 330 char *index_table_addr; 331 uint16_t table_entries; 332 333 char *ipv4_expn_rules_addr; 334 char *index_table_expn_addr; 335 uint16_t expn_table_entries; 336 337 struct ipa_nat_indx_tbl_meta_info *index_expn_table_meta; 338 339 uint16_t *rule_id_array; 340 #ifdef IPA_ON_R3PC 341 uint32_t mmap_offset; 342 #endif 343 344 uint16_t cur_tbl_cnt; 345 uint16_t cur_expn_tbl_cnt; 346 }; 347 348 struct ipa_nat_cache { 349 struct ipa_nat_ip4_table_cache ip4_tbl[IPA_NAT_MAX_IP4_TBLS]; 350 int ipa_fd; 351 uint8_t table_cnt; 352 enum ipa_hw_type ver; 353 }; 354 355 struct ipa_nat_indx_tbl_sw_rule { 356 uint16_t tbl_entry; 357 uint16_t next_index; 358 uint16_t prev_index; 359 }; 360 361 typedef enum { 362 IPA_NAT_DEL_TYPE_ONLY_ONE, 363 IPA_NAT_DEL_TYPE_HEAD, 364 IPA_NAT_DEL_TYPE_MIDDLE, 365 IPA_NAT_DEL_TYPE_LAST, 366 } del_type; 367 368 /** 369 * ipa_nati_parse_ipv4_rule_hdl() - prase rule handle 370 * @tbl_hdl: [in] nat table rule 371 * @rule_hdl: [in] nat rule handle 372 * @expn_tbl: [out] expansion table or not 373 * @tbl_entry: [out] index into table 374 * 375 * Parse the rule handle to retrieve the nat table 376 * type and entry of nat table 377 * 378 * Returns: None 379 */ 380 void ipa_nati_parse_ipv4_rule_hdl(uint8_t tbl_hdl, 381 uint16_t rule_hdl, 382 uint8_t *expn_tbl, 383 uint16_t *tbl_entry); 384 385 /** 386 * ipa_nati_make_rule_hdl() - makes nat rule handle 387 * @tbl_hdl: [in] nat table handle 388 * @tbl_entry: [in] nat table entry 389 * 390 * Calculate the nat rule handle which from 391 * nat entry which will be returned to client of 392 * nat driver 393 * 394 * Returns: >0 nat rule handle 395 */ 396 uint16_t ipa_nati_make_rule_hdl(uint16_t tbl_hdl, 397 uint16_t tbl_entry); 398 399 uint32_t ipa_nati_get_index_entry_offset( 400 struct ipa_nat_ip4_table_cache*, 401 nat_table_type tbl_type, 402 uint16_t indx_tbl_entry); 403 uint32_t ipa_nati_get_entry_offset( 404 struct ipa_nat_ip4_table_cache*, 405 nat_table_type tbl_type, 406 uint16_t tbl_entry); 407 408 int ipa_nati_add_ipv4_tbl(uint32_t public_ip_addr, 409 uint16_t number_of_entries, 410 uint32_t *table_hanle); 411 412 int ipa_nati_alloc_table(uint16_t number_of_entries, 413 struct ipa_ioc_nat_alloc_mem *mem, 414 uint16_t*, uint16_t*); 415 416 int ipa_nati_update_cache(struct ipa_ioc_nat_alloc_mem *, 417 uint32_t public_ip_addr, 418 uint16_t tbl_entries, 419 uint16_t expn_tbl_entries); 420 421 int ipa_nati_del_ipv4_table(uint32_t tbl_hdl); 422 int ipa_nati_reset_ipv4_table(uint32_t tbl_hdl); 423 int ipa_nati_post_ipv4_init_cmd(uint8_t tbl_index); 424 425 int ipa_nati_query_timestamp(uint32_t tbl_hdl, 426 uint32_t rule_hdl, 427 uint32_t *time_stamp); 428 429 int ipa_nati_modify_pdn(struct ipa_ioc_nat_pdn_entry *entry); 430 431 int ipa_nati_add_ipv4_rule(uint32_t tbl_hdl, 432 const ipa_nat_ipv4_rule *clnt_rule, 433 uint32_t *rule_hdl); 434 435 int ipa_nati_generate_rule(uint32_t tbl_hdl, 436 const ipa_nat_ipv4_rule *clnt_rule, 437 struct ipa_nat_sw_rule *rule, 438 struct ipa_nat_indx_tbl_sw_rule *index_sw_rule, 439 uint16_t *tbl_entry, 440 uint16_t *indx_tbl_entry); 441 442 uint16_t ipa_nati_expn_tbl_free_entry(struct ipa_nat_rule *expn_tbl, 443 uint16_t size); 444 445 uint16_t ipa_nati_generate_tbl_rule(const ipa_nat_ipv4_rule *clnt_rule, 446 struct ipa_nat_sw_rule *sw_rule, 447 struct ipa_nat_ip4_table_cache *tbl_ptr); 448 449 uint16_t ipa_nati_generate_index_rule(const ipa_nat_ipv4_rule *clnt_rule, 450 struct ipa_nat_indx_tbl_sw_rule *sw_rule, 451 struct ipa_nat_ip4_table_cache *tbl_ptr); 452 453 uint16_t ipa_nati_index_expn_get_free_entry(struct ipa_nat_indx_tbl_rule *tbl, 454 uint16_t size); 455 456 void ipa_nati_copy_ipv4_rule_to_hw( 457 struct ipa_nat_ip4_table_cache *ipv4_cache, 458 struct ipa_nat_sw_rule *rule, 459 uint16_t entry, uint8_t tbl_index); 460 461 void ipa_nati_copy_ipv4_index_rule_to_hw( 462 struct ipa_nat_ip4_table_cache *ipv4_cache, 463 struct ipa_nat_indx_tbl_sw_rule *indx_sw_rule, 464 uint16_t entry, uint8_t tbl_index); 465 466 void ipa_nati_write_next_index(uint8_t tbl_indx, 467 nat_table_type tbl_type, 468 uint16_t value, 469 uint32_t offset); 470 471 int ipa_nati_post_ipv4_dma_cmd(uint8_t tbl_indx, 472 uint16_t entry); 473 474 int ipa_nati_del_ipv4_rule(uint32_t tbl_hdl, 475 uint32_t rule_hdl); 476 477 int ipa_nati_post_del_dma_cmd(uint8_t tbl_indx, 478 uint16_t tbl_entry, 479 uint8_t expn_tbl, 480 del_type rule_pos); 481 482 void ipa_nati_find_index_rule_pos( 483 struct ipa_nat_ip4_table_cache *cache_ptr, 484 uint16_t tbl_entry, 485 del_type *rule_pos); 486 487 void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx); 488 void ipa_nati_find_rule_pos(struct ipa_nat_ip4_table_cache *cache_ptr, 489 uint8_t expn_tbl, 490 uint16_t tbl_entry, 491 del_type *rule_pos); 492 void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx); 493 494 uint16_t Read16BitFieldValue(uint32_t param, 495 ipa_nat_rule_field_type fld_type); 496 497 /* ======================================================== 498 Debug functions 499 ========================================================*/ 500 #ifdef NAT_DUMP 501 void ipa_nati_print_rule(struct ipa_nat_rule*, uint32_t); 502 void ipa_nat_dump_ipv4_table(uint32_t); 503 void ipa_nati_print_index_rule(struct ipa_nat_indx_tbl_rule*, 504 uint32_t, uint16_t); 505 int ipa_nati_query_nat_rules(uint32_t, nat_table_type); 506 #endif 507 508 #endif /* #ifndef IPA_NAT_DRVI_H */ 509