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