• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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