Home | History | Annotate | Download | only in inc
      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