1 /*
2 * Copyright (c) 2014, 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
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37
38 #include "ipa_nat_drv.h"
39 #include "ipa_nat_drvi.h"
40 #include "ipa_nat_test.h"
41
42 extern struct ipa_nat_cache ipv4_nat_cache;
43
chk_for_loop(u32 tbl_hdl)44 int chk_for_loop(u32 tbl_hdl)
45 {
46 struct ipa_nat_rule *tbl_ptr;
47 struct ipa_nat_indx_tbl_rule *indx_tbl_ptr;
48 int cnt;
49 uint16_t cur_entry;
50
51 if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl ||
52 tbl_hdl > IPA_NAT_MAX_IP4_TBLS) {
53 IPAERR("invalid table handle passed \n");
54 return -EINVAL;
55 }
56
57 IPADBG("checking ipv4 rules:\n");
58 tbl_ptr = (struct ipa_nat_rule *)
59 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr;
60 for (cnt = 0;
61 cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
62 cnt++) {
63 if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl,ENABLE_FIELD)) {
64 if(Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port,
65 NEXT_INDEX_FIELD) == cnt)
66 {
67 IPAERR("Infinite loop detected, entry\n");
68 ipa_nati_print_rule(&tbl_ptr[cnt], cnt);
69 return -EINVAL;
70 }
71 }
72 }
73
74 /* Print ipv4 expansion rules */
75 IPADBG("checking ipv4 active expansion rules:\n");
76 tbl_ptr = (struct ipa_nat_rule *)
77 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr;
78 for (cnt = 0;
79 cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries;
80 cnt++) {
81 if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl,
82 ENABLE_FIELD)) {
83 cur_entry =
84 cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
85 if (Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port,
86 NEXT_INDEX_FIELD) == cur_entry)
87 {
88 IPAERR("Infinite loop detected\n");
89 ipa_nati_print_rule(&tbl_ptr[cnt],
90 (cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries));
91 return -EINVAL;
92 }
93 }
94 }
95
96 /* Print ipv4 index rules */
97 IPADBG("checking ipv4 index active rules: \n");
98 indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)
99 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr;
100 for (cnt = 0;
101 cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
102 cnt++) {
103 if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
104 INDX_TBL_TBL_ENTRY_FIELD)) {
105 if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
106 INDX_TBL_NEXT_INDEX_FILED) == cnt)
107 {
108 IPAERR("Infinite loop detected\n");
109 ipa_nati_print_index_rule(&indx_tbl_ptr[cnt], cnt, 0);
110 return -EINVAL;
111 }
112 }
113 }
114
115 /* Print ipv4 index expansion rules */
116 IPADBG("Checking ipv4 index expansion active rules: \n");
117 indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)
118 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr;
119 for (cnt = 0;
120 cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries;
121 cnt++) {
122 if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
123 INDX_TBL_TBL_ENTRY_FIELD)) {
124 cur_entry =
125 cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
126 if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
127 INDX_TBL_NEXT_INDEX_FILED) == cur_entry)
128 {
129 IPAERR("Infinite loop detected\n");
130 ipa_nati_print_index_rule(&indx_tbl_ptr[cnt],
131 (cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries),
132 ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].index_expn_table_meta[cnt].prev_index);
133 return -EINVAL;
134 }
135 }
136 }
137 return 0;
138 }
139
is_base_entry_valid(u32 tbl_hdl,u16 entry)140 uint8_t is_base_entry_valid(u32 tbl_hdl, u16 entry)
141 {
142 struct ipa_nat_rule *tbl_ptr;
143
144 if (entry >
145 ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries)
146 {
147 tbl_ptr = (struct ipa_nat_rule *)
148 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr;
149 entry -=
150 ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
151 }
152 else
153 {
154 tbl_ptr = (struct ipa_nat_rule *)
155 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr;
156 }
157 return (Read16BitFieldValue(tbl_ptr[entry].ip_cksm_enbl,
158 ENABLE_FIELD));
159 }
160
is_index_entry_valid(u32 tbl_hdl,u16 entry)161 uint8_t is_index_entry_valid(u32 tbl_hdl, u16 entry)
162 {
163 struct ipa_nat_indx_tbl_rule *tbl_ptr;
164
165 if (entry >
166 ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries)
167 {
168 tbl_ptr = (struct ipa_nat_indx_tbl_rule *)
169 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr;
170 entry -=
171 ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
172 }
173 else
174 {
175 tbl_ptr = (struct ipa_nat_indx_tbl_rule *)
176 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr;
177 }
178 if (Read16BitFieldValue(tbl_ptr[entry].tbl_entry_nxt_indx,
179 INDX_TBL_TBL_ENTRY_FIELD)) {
180 return 1;
181 }
182 else
183 {
184 return 0;
185 }
186 }
187
chk_for_validity(u32 tbl_hdl)188 int chk_for_validity(u32 tbl_hdl)
189 {
190 struct ipa_nat_rule *tbl_ptr;
191 struct ipa_nat_indx_tbl_rule *indx_tbl_ptr;
192 uint16_t nxt_index, prv_index;
193 int cnt;
194
195 if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl ||
196 tbl_hdl > IPA_NAT_MAX_IP4_TBLS) {
197 IPAERR("invalid table handle passed \n");
198 return -EINVAL;
199 }
200
201 /* Validate base table next_indx and prev_indx values */
202 IPADBG("Validating ipv4 active rules: \n");
203 tbl_ptr = (struct ipa_nat_rule *)
204 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr;
205 for (cnt = 0;
206 cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
207 cnt++) {
208 if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl,
209 ENABLE_FIELD)) {
210 nxt_index =
211 Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port,
212 NEXT_INDEX_FIELD);
213 if (!is_base_entry_valid(tbl_hdl, nxt_index)) {
214 IPAERR("Invalid next index found, entry:%d\n", cnt);
215 }
216 }
217 }
218
219 IPADBG("Validating ipv4 expansion active rules: \n");
220 tbl_ptr = (struct ipa_nat_rule *)
221 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr;
222 for (cnt = 0;
223 cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries;
224 cnt++) {
225 if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl,
226 ENABLE_FIELD)) {
227 /* Validate next index */
228 nxt_index =
229 Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port,
230 NEXT_INDEX_FIELD);
231 if (!is_base_entry_valid(tbl_hdl, nxt_index)) {
232 IPAERR("Invalid next index found, entry:%d\n", cnt);
233 }
234 /* Validate previous index */
235 prv_index =
236 Read16BitFieldValue(tbl_ptr[cnt].sw_spec_params,
237 SW_SPEC_PARAM_PREV_INDEX_FIELD);
238 if (!is_base_entry_valid(tbl_hdl, prv_index)) {
239 IPAERR("Invalid Previous index found, entry:%d\n", cnt);
240 }
241 }
242 }
243
244 IPADBG("Validating ipv4 index active rules: \n");
245 indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)
246 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr;
247 for (cnt = 0;
248 cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries;
249 cnt++) {
250 if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
251 INDX_TBL_TBL_ENTRY_FIELD)) {
252 nxt_index =
253 Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
254 INDX_TBL_NEXT_INDEX_FILED);
255 if (!is_index_entry_valid(tbl_hdl, nxt_index)) {
256 IPAERR("Invalid next index found, entry:%d\n", cnt);
257 }
258 }
259 }
260
261 IPADBG("Validating ipv4 index expansion active rules: \n");
262 indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)
263 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr;
264 for (cnt = 0;
265 cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries;
266 cnt++) {
267 if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
268 INDX_TBL_TBL_ENTRY_FIELD)) {
269 /* Validate next index*/
270 nxt_index =
271 Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx,
272 INDX_TBL_NEXT_INDEX_FILED);
273 if (!is_index_entry_valid(tbl_hdl, nxt_index)) {
274 IPAERR("Invalid next index found, entry:%d\n", cnt);
275 }
276
277 /* Validate previous index*/
278 prv_index =
279 ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_expn_table_meta[cnt].prev_index;
280
281 if (!is_index_entry_valid(tbl_hdl, prv_index)) {
282 IPAERR("Invalid Previous index found, entry:%d\n", cnt);
283 }
284 }
285 }
286
287 return 0;
288 }
289
ipa_nat_validate_ipv4_table(u32 tbl_hdl)290 int ipa_nat_validate_ipv4_table(u32 tbl_hdl)
291 {
292 int ret = 0;
293
294 ret = chk_for_loop(tbl_hdl);
295 if (ret)
296 return ret;
297 ret = chk_for_validity(tbl_hdl);
298
299 return ret;
300 }
301
main(int argc,char * argv[])302 int main(int argc, char* argv[])
303 {
304 int exec = 0, pass = 0, ret;
305 int cnt, nt=1;
306 int total_entries = 100;
307 u8 sep = 0;
308 u32 tbl_hdl = 0;
309 u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */
310
311 IPADBG("ipa_nat_testing user space nat driver\n");
312
313 if (argc == 4)
314 {
315 if (!strncmp(argv[1], "reg", 3))
316 {
317 nt = atoi(argv[2]);
318 total_entries = atoi(argv[3]);
319 IPADBG("Reg: %d, Nat Entries: %d\n", nt, total_entries);
320 }
321 else if (!strncmp(argv[1], "sep", 3))
322 {
323 sep = 1;
324 nt = atoi(argv[2]);
325 total_entries = atoi(argv[3]);
326 }
327 }
328 else if (argc == 3)
329 {
330 if (!strncmp(argv[1], "inotify", 7))
331 {
332 ipa_nat_test021(total_entries, atoi(argv[2]));
333 return 0;
334 }
335 else if (!strncmp(argv[1], "sep", 3))
336 {
337 sep = 1;
338 total_entries = atoi(argv[2]);
339 }
340 }
341 else if (argc == 2)
342 {
343 total_entries = atoi(argv[1]);
344 IPADBG("Nat Entries: %d\n", total_entries);
345 }
346
347
348 for (cnt=0; cnt<nt; cnt++)
349 {
350 IPADBG("%s():Executing %d time \n",__FUNCTION__, cnt);
351
352 if (!sep)
353 {
354 ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl);
355 CHECK_ERR(ret);
356 }
357
358 if (sep)
359 {
360 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
361 ret = ipa_nat_test000(total_entries, tbl_hdl, sep);
362 if (!ret)
363 {
364 pass++;
365 }
366 else
367 {
368 IPAERR("ipa_nat_test00%d Fail\n", exec);
369 }
370 exec++;
371
372 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
373 ret = ipa_nat_test001(total_entries, tbl_hdl, sep);
374 if (!ret)
375 {
376 pass++;
377 }
378 else
379 {
380 IPAERR("ipa_nat_test00%d Fail\n", exec);
381 }
382 exec++;
383 }
384
385 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
386 ret = ipa_nat_test002(total_entries, tbl_hdl, sep);
387 if (!ret)
388 {
389 pass++;
390 }
391 else
392 {
393 IPAERR("ipa_nat_test00%d Fail\n", exec);
394 }
395 exec++;
396
397 if (sep)
398 {
399 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
400 ret = ipa_nat_test003(total_entries, tbl_hdl, sep);
401 if (!ret)
402 {
403 pass++;
404 }
405 else
406 {
407 IPAERR("ipa_nat_test00%d Fail\n", exec);
408 }
409 exec++;
410
411 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
412 ret = ipa_nat_test004(total_entries, tbl_hdl, sep);
413 if (!ret)
414 {
415 pass++;
416 }
417 else
418 {
419 IPAERR("ipa_nat_test00%d Fail\n", exec);
420 }
421 exec++;
422
423 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
424 ret = ipa_nat_test005(total_entries, tbl_hdl, sep);
425 if (!ret)
426 {
427 pass++;
428 }
429 else
430 {
431 IPAERR("ipa_nat_test00%d Fail\n", exec);
432 }
433 exec++;
434 }
435
436 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
437 ret = ipa_nat_test006(total_entries, tbl_hdl, sep);
438 if (!ret)
439 {
440 pass++;
441 }
442 else
443 {
444 IPAERR("ipa_nat_test00%d Fail\n", exec);
445 }
446 exec++;
447
448 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
449 ret = ipa_nat_test007(total_entries, tbl_hdl, sep);
450 if (!ret)
451 {
452 pass++;
453 }
454 else
455 {
456 IPAERR("ipa_nat_test00%d Fail\n", exec);
457 }
458 exec++;
459
460 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
461 ret = ipa_nat_test008(total_entries, tbl_hdl, sep);
462 if (!ret)
463 {
464 pass++;
465 }
466 else
467 {
468 IPAERR("ipa_nat_test00%d Fail\n", exec);
469 }
470 exec++;
471
472 IPADBG("\n\nExecuting ipa_nat_test00%d\n", exec);
473 ret = ipa_nat_test009(total_entries, tbl_hdl, sep);
474 if (!ret)
475 {
476 pass++;
477 }
478 else
479 {
480 IPAERR("ipa_nat_test00%d Fail\n", exec);
481 }
482 exec++;
483
484 if (total_entries >= IPA_NAT_TEST_PRE_COND_TE)
485 {
486 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
487 ret = ipa_nat_test010(total_entries, tbl_hdl, sep);
488 if (!ret)
489 {
490 pass++;
491 }
492 else
493 {
494 IPAERR("ipa_nat_test0%d Fail\n", exec);
495 }
496 exec++;
497
498 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
499 ret = ipa_nat_test011(total_entries, tbl_hdl, sep);
500 if (!ret)
501 {
502 pass++;
503 }
504 else
505 {
506 IPAERR("ipa_nat_test0%d Fail\n", exec);
507 }
508 exec++;
509
510 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
511 ret = ipa_nat_test012(total_entries, tbl_hdl, sep);
512 if (!ret)
513 {
514 pass++;
515 }
516 else
517 {
518 IPAERR("ipa_nat_test0%d Fail\n", exec);
519 }
520 exec++;
521
522 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
523 ret = ipa_nat_test013(total_entries, tbl_hdl, sep);
524 if (!ret)
525 {
526 pass++;
527 }
528 else
529 {
530 IPAERR("ipa_nat_test0%d Fail\n", exec);
531 }
532 exec++;
533
534 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
535 ret = ipa_nat_test014(total_entries, tbl_hdl, sep);
536 if (!ret)
537 {
538 pass++;
539 }
540 else
541 {
542 IPAERR("ipa_nat_test0%d Fail\n", exec);
543 }
544 exec++;
545
546 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
547 ret = ipa_nat_test015(total_entries, tbl_hdl, sep);
548 if (!ret)
549 {
550 pass++;
551 }
552 else
553 {
554 IPAERR("ipa_nat_test0%d Fail\n", exec);
555 }
556 exec++;
557
558 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
559 ret = ipa_nat_test016(total_entries, tbl_hdl, sep);
560 if (!ret)
561 {
562 pass++;
563 }
564 else
565 {
566 IPAERR("ipa_nat_test0%d Fail\n", exec);
567 }
568 exec++;
569
570 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
571 ret = ipa_nat_test017(total_entries, tbl_hdl, sep);
572 if (!ret)
573 {
574 pass++;
575 }
576 else
577 {
578 IPAERR("ipa_nat_test0%d Fail\n", exec);
579 }
580 exec++;
581
582 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
583 ret = ipa_nat_test018(total_entries, tbl_hdl, sep);
584 if (!ret)
585 {
586 pass++;
587 }
588 else
589 {
590 IPAERR("ipa_nat_test0%d Fail\n", exec);
591 }
592 exec++;
593
594 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
595 ret = ipa_nat_test019(total_entries, tbl_hdl, sep);
596 if (!ret)
597 {
598 pass++;
599 }
600 else
601 {
602 IPAERR("ipa_nat_test0%d Fail\n", exec);
603 }
604 exec++;
605
606 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
607 ret = ipa_nat_test020(total_entries, tbl_hdl, sep);
608 if (!ret)
609 {
610 pass++;
611 }
612 else
613 {
614 IPAERR("ipa_nat_test0%d Fail\n", exec);
615 }
616 exec++;
617
618 IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec);
619 ret = ipa_nat_test022(total_entries, tbl_hdl, sep);
620 if (!ret)
621 {
622 pass++;
623 }
624 else
625 {
626 IPAERR("ipa_nat_test0%d Fail\n", exec);
627 }
628 exec++;
629 }
630
631 if (!sep)
632 {
633 ret = ipa_nat_del_ipv4_tbl(tbl_hdl);
634 CHECK_ERR(ret);
635 }
636 }
637 /*======= Printing Results ==========*/
638 IPADBG("Total ipa_nat Tests Run:%d, Pass:%d, Fail:%d\n",exec, pass, exec-pass);
639 return 0;
640 }
641