1 /* 2 Copyright (c) 2013, 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 <unistd.h> 34 #include <stdio.h> 35 #include <sys/ioctl.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 44 #include "ipa_nat_logi.h" 45 46 #define NAT_DUMP 47 48 /*======= IMPLEMENTATION related data structures and functions ======= */ 49 #ifdef IPA_ON_R3PC 50 #define NAT_MMAP_MEM_SIZE (2 * 1024UL * 1024UL - 1) 51 #endif 52 53 #define IPA_DEV_NAME "/dev/ipa" 54 #define NAT_DEV_DIR "/dev" 55 #define NAT_DEV_NAME "ipaNatTable" 56 #define NAT_DEV_FULL_NAME "/dev/ipaNatTable" 57 58 #define IPA_NAT_TABLE_VALID 1 59 #define IPA_NAT_MAX_IP4_TBLS 1 60 #define IPA_NAT_BASE_TABLE_PERCENTAGE .8 61 #define IPA_NAT_EXPANSION_TABLE_PERCENTAGE .2 62 63 #define IPA_NAT_NUM_OF_BASE_TABLES 2 64 #define IPA_NAT_UNUSED_BASE_ENTRIES 2 65 66 #define IPA_NAT_RULE_FLAG_FIELD_OFFSET 18 67 #define IPA_NAT_RULE_NEXT_FIELD_OFFSET 8 68 #define IPA_NAT_RULE_PROTO_FIELD_OFFSET 22 69 70 #define IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET 2 71 #define IPA_NAT_INDEX_RULE_NAT_INDEX_FIELD_OFFSET 0 72 73 #define IPA_NAT_RULE_FLAG_FIELD_SIZE 2 74 #define IPA_NAT_RULE_NEXTFIELD_FIELD_SIZE 2 75 76 #define IPA_NAT_FLAG_ENABLE_BIT_MASK 0x8000 77 #define IPA_NAT_FLAG_DISABLE_BIT_MASK 0x0000 78 79 #define IPA_NAT_FLAG_ENABLE_BIT 1 80 #define IPA_NAT_FLAG_DISABLE_BIT 0 81 82 #define IPA_NAT_INVALID_PROTO_FIELD_VALUE 0xFF00 83 #define IPA_NAT_INVALID_PROTO_FIELD_CMP 0xFF 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 | Reserved(2B) | SW Specific Parameters(4B) | 219 | diff (2B) | | 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:16; 248 uint64_t tcp_udp_chksum:16; 249 }; 250 251 struct ipa_nat_sw_rule { 252 uint64_t private_ip:32; 253 uint64_t target_ip:32; 254 255 uint64_t next_index:16; 256 uint64_t public_port:16; 257 uint64_t private_port:16; 258 uint64_t target_port:16; 259 260 uint64_t ip_chksum:16; 261 uint64_t rsvd1:14; 262 uint64_t redirect:1; 263 uint64_t enable:1; 264 uint64_t time_stamp:24; 265 uint64_t protocol:8; 266 267 /*-------------------------------------------------- 268 32 bit sw_spec_params is interpreted as follows 269 ------------------------------------ 270 | 16 bits | 16 bits | 271 ------------------------------------ 272 | index table | prev index | 273 | entry | | 274 ------------------------------------ 275 --------------------------------------------------*/ 276 uint64_t prev_index:16; 277 uint64_t indx_tbl_entry:16; 278 uint64_t rsvd2:16; 279 uint64_t tcp_udp_chksum:16; 280 }; 281 #define IPA_NAT_TABLE_ENTRY_SIZE 32 282 #define IPA_NAT_INDEX_TABLE_ENTRY_SIZE 4 283 284 struct ipa_nat_indx_tbl_rule { 285 uint32_t tbl_entry_nxt_indx; 286 }; 287 288 struct ipa_nat_sw_indx_tbl_rule { 289 uint16_t tbl_entry; 290 uint16_t next_index; 291 }; 292 293 struct ipa_nat_indx_tbl_meta_info { 294 uint16_t prev_index; 295 }; 296 297 struct ipa_nat_ip4_table_cache { 298 uint8_t valid; 299 uint32_t public_addr; 300 301 int nat_fd; 302 int size; 303 uint32_t tbl_addr_offset; 304 char table_name[IPA_RESOURCE_NAME_MAX]; 305 306 char *ipv4_rules_addr; 307 char *index_table_addr; 308 uint16_t table_entries; 309 310 char *ipv4_expn_rules_addr; 311 char *index_table_expn_addr; 312 uint16_t expn_table_entries; 313 314 struct ipa_nat_indx_tbl_meta_info *index_expn_table_meta; 315 316 uint16_t *rule_id_array; 317 #ifdef IPA_ON_R3PC 318 uint32_t mmap_offset; 319 #endif 320 321 uint16_t cur_tbl_cnt; 322 uint16_t cur_expn_tbl_cnt; 323 }; 324 325 struct ipa_nat_cache { 326 struct ipa_nat_ip4_table_cache ip4_tbl[IPA_NAT_MAX_IP4_TBLS]; 327 int ipa_fd; 328 uint8_t table_cnt; 329 }; 330 331 struct ipa_nat_indx_tbl_sw_rule { 332 uint16_t tbl_entry; 333 uint16_t next_index; 334 uint16_t prev_index; 335 }; 336 337 typedef enum { 338 IPA_NAT_DEL_TYPE_ONLY_ONE, 339 IPA_NAT_DEL_TYPE_HEAD, 340 IPA_NAT_DEL_TYPE_MIDDLE, 341 IPA_NAT_DEL_TYPE_LAST, 342 } del_type; 343 344 /** 345 * ipa_nati_parse_ipv4_rule_hdl() - prase rule handle 346 * @tbl_hdl: [in] nat table rule 347 * @rule_hdl: [in] nat rule handle 348 * @expn_tbl: [out] expansion table or not 349 * @tbl_entry: [out] index into table 350 * 351 * Parse the rule handle to retrieve the nat table 352 * type and entry of nat table 353 * 354 * Returns: None 355 */ 356 void ipa_nati_parse_ipv4_rule_hdl(uint8_t tbl_hdl, 357 uint16_t rule_hdl, 358 uint8_t *expn_tbl, 359 uint16_t *tbl_entry); 360 361 /** 362 * ipa_nati_make_rule_hdl() - makes nat rule handle 363 * @tbl_hdl: [in] nat table handle 364 * @tbl_entry: [in] nat table entry 365 * 366 * Calculate the nat rule handle which from 367 * nat entry which will be returned to client of 368 * nat driver 369 * 370 * Returns: >0 nat rule handle 371 */ 372 uint16_t ipa_nati_make_rule_hdl(uint16_t tbl_hdl, 373 uint16_t tbl_entry); 374 375 uint32_t ipa_nati_get_index_entry_offset( 376 struct ipa_nat_ip4_table_cache*, 377 nat_table_type tbl_type, 378 uint16_t indx_tbl_entry); 379 uint32_t ipa_nati_get_entry_offset( 380 struct ipa_nat_ip4_table_cache*, 381 nat_table_type tbl_type, 382 uint16_t tbl_entry); 383 384 int ipa_nati_add_ipv4_tbl(uint32_t public_ip_addr, 385 uint16_t number_of_entries, 386 uint32_t *table_hanle); 387 388 int ipa_nati_alloc_table(uint16_t number_of_entries, 389 struct ipa_ioc_nat_alloc_mem *mem, 390 uint16_t*, uint16_t*); 391 392 int ipa_nati_update_cache(struct ipa_ioc_nat_alloc_mem *, 393 uint32_t public_ip_addr, 394 uint16_t tbl_entries, 395 uint16_t expn_tbl_entries); 396 397 int ipa_nati_del_ipv4_table(uint32_t tbl_hdl); 398 int ipa_nati_reset_ipv4_table(uint32_t tbl_hdl); 399 int ipa_nati_post_ipv4_init_cmd(uint8_t tbl_index); 400 401 int ipa_nati_query_timestamp(uint32_t tbl_hdl, 402 uint32_t rule_hdl, 403 uint32_t *time_stamp); 404 405 int ipa_nati_add_ipv4_rule(uint32_t tbl_hdl, 406 const ipa_nat_ipv4_rule *clnt_rule, 407 uint32_t *rule_hdl); 408 409 int ipa_nati_generate_rule(uint32_t tbl_hdl, 410 const ipa_nat_ipv4_rule *clnt_rule, 411 struct ipa_nat_sw_rule *rule, 412 struct ipa_nat_indx_tbl_sw_rule *index_sw_rule, 413 uint16_t *tbl_entry, 414 uint16_t *indx_tbl_entry); 415 416 uint16_t ipa_nati_expn_tbl_free_entry(struct ipa_nat_rule *expn_tbl, 417 uint16_t size); 418 419 uint16_t ipa_nati_generate_tbl_rule(const ipa_nat_ipv4_rule *clnt_rule, 420 struct ipa_nat_sw_rule *sw_rule, 421 struct ipa_nat_ip4_table_cache *tbl_ptr); 422 423 uint16_t ipa_nati_generate_index_rule(const ipa_nat_ipv4_rule *clnt_rule, 424 struct ipa_nat_indx_tbl_sw_rule *sw_rule, 425 struct ipa_nat_ip4_table_cache *tbl_ptr); 426 427 uint16_t ipa_nati_index_expn_get_free_entry(struct ipa_nat_indx_tbl_rule *tbl, 428 uint16_t size); 429 430 void ipa_nati_copy_ipv4_rule_to_hw( 431 struct ipa_nat_ip4_table_cache *ipv4_cache, 432 struct ipa_nat_sw_rule *rule, 433 uint16_t entry, uint8_t tbl_index); 434 435 void ipa_nati_copy_ipv4_index_rule_to_hw( 436 struct ipa_nat_ip4_table_cache *ipv4_cache, 437 struct ipa_nat_indx_tbl_sw_rule *indx_sw_rule, 438 uint16_t entry, uint8_t tbl_index); 439 440 void ipa_nati_write_next_index(uint8_t tbl_indx, 441 nat_table_type tbl_type, 442 uint16_t value, 443 uint32_t offset); 444 445 int ipa_nati_post_ipv4_dma_cmd(uint8_t tbl_indx, 446 uint16_t entry); 447 448 int ipa_nati_del_ipv4_rule(uint32_t tbl_hdl, 449 uint32_t rule_hdl); 450 451 int ipa_nati_post_del_dma_cmd(uint8_t tbl_indx, 452 uint16_t tbl_entry, 453 uint8_t expn_tbl, 454 del_type rule_pos); 455 456 void ipa_nati_find_index_rule_pos( 457 struct ipa_nat_ip4_table_cache *cache_ptr, 458 uint16_t tbl_entry, 459 del_type *rule_pos); 460 461 void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx); 462 void ipa_nati_find_rule_pos(struct ipa_nat_ip4_table_cache *cache_ptr, 463 uint8_t expn_tbl, 464 uint16_t tbl_entry, 465 del_type *rule_pos); 466 void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx); 467 468 uint16_t Read16BitFieldValue(uint32_t param, 469 ipa_nat_rule_field_type fld_type); 470 471 /* ======================================================== 472 Debug functions 473 ========================================================*/ 474 #ifdef NAT_DUMP 475 void ipa_nati_print_rule(struct ipa_nat_rule*, uint32_t); 476 void ipa_nat_dump_ipv4_table(uint32_t); 477 void ipa_nati_print_index_rule(struct ipa_nat_indx_tbl_rule*, 478 uint32_t, uint16_t); 479 int ipa_nati_query_nat_rules(uint32_t, nat_table_type); 480 #endif 481 482 #endif /* #ifndef IPA_NAT_DRVI_H */ 483