main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. * Copyright (c) 2014, 2018-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. #include <stdio.h>
  30. #include <stdint.h>
  31. #include <stdbool.h>
  32. #include <stdlib.h>
  33. #include <unistd.h>
  34. #include <libgen.h>
  35. #include <string.h>
  36. #include <sys/stat.h>
  37. #include <fcntl.h>
  38. #include <errno.h>
  39. #include "ipa_nat_test.h"
  40. #include "ipa_nat_map.h"
  41. #undef strcasesame
  42. #define strcasesame(x, y) \
  43. (! strcasecmp((x), (y)))
  44. static inline const char* legal_mem_type(
  45. const char* mt )
  46. {
  47. if ( strcasesame(mt, "DDR") ) return "DDR";
  48. if ( strcasesame(mt, "SRAM") ) return "SRAM";
  49. if ( strcasesame(mt, "HYBRID") ) return "HYBRID";
  50. return NULL;
  51. }
  52. static int nat_rule_loop_check(
  53. ipa_table* table_ptr,
  54. uint32_t rule_hdl,
  55. void* record_ptr,
  56. uint16_t record_index,
  57. void* meta_record_ptr,
  58. uint16_t meta_record_index,
  59. void* arb_data_ptr )
  60. {
  61. enum ipa3_nat_mem_in nmi;
  62. uint8_t is_expn_tbl;
  63. uint16_t rule_index;
  64. uint32_t tbl_hdl = (uint32_t) arb_data_ptr;
  65. struct ipa_nat_rule* rule_ptr =
  66. (struct ipa_nat_rule*) record_ptr;
  67. BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
  68. /*
  69. * By virtue of this function being called back by the walk, this
  70. * record_index is valid. Denote it as such in the map...
  71. */
  72. if ( ipa_nat_map_add(MAP_NUM_99, record_index, 1) )
  73. {
  74. IPAERR("ipa_nat_map_add(index(%u)) failed\n", record_index);
  75. return -EINVAL;
  76. }
  77. if ( rule_ptr->next_index == record_index )
  78. {
  79. IPAERR("Infinite loop detected in IPv4 %s table, entry %u\n",
  80. (is_expn_tbl) ? "expansion" : "base",
  81. record_index);
  82. ipa_nat_dump_ipv4_table(tbl_hdl);
  83. return -EINVAL;
  84. }
  85. return 0;
  86. }
  87. static int nat_rule_validity_check(
  88. ipa_table* table_ptr,
  89. uint32_t rule_hdl,
  90. void* record_ptr,
  91. uint16_t record_index,
  92. void* meta_record_ptr,
  93. uint16_t meta_record_index,
  94. void* arb_data_ptr )
  95. {
  96. enum ipa3_nat_mem_in nmi;
  97. uint8_t is_expn_tbl;
  98. uint16_t rule_index;
  99. uint16_t index;
  100. struct ipa_nat_rule* rule_ptr =
  101. (struct ipa_nat_rule*) record_ptr;
  102. BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
  103. index = rule_ptr->next_index;
  104. if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
  105. {
  106. IPAERR("Invalid next index %u found in IPv4 %s table entry %u\n",
  107. index,
  108. (is_expn_tbl) ? "expansion" : "base",
  109. rule_index);
  110. return -EINVAL;
  111. }
  112. if ( is_expn_tbl )
  113. {
  114. index = rule_ptr->prev_index;
  115. if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
  116. {
  117. IPAERR("Invalid previous index %u found in IPv4 %s table entry %u\n",
  118. index,
  119. "expansion",
  120. rule_index);
  121. return -EINVAL;
  122. }
  123. }
  124. return 0;
  125. }
  126. static int index_loop_check(
  127. ipa_table* table_ptr,
  128. uint32_t rule_hdl,
  129. void* record_ptr,
  130. uint16_t record_index,
  131. void* meta_record_ptr,
  132. uint16_t meta_record_index,
  133. void* arb_data_ptr )
  134. {
  135. enum ipa3_nat_mem_in nmi;
  136. uint8_t is_expn_tbl;
  137. uint16_t rule_index;
  138. uint32_t tbl_hdl = (uint32_t) arb_data_ptr;
  139. struct ipa_nat_indx_tbl_rule* itr_ptr =
  140. (struct ipa_nat_indx_tbl_rule*) record_ptr;
  141. BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
  142. /*
  143. * By virtue of this function being called back by the walk, this
  144. * record_index is valid. Denote it as such in the map...
  145. */
  146. if ( ipa_nat_map_add(MAP_NUM_99, record_index, 1) )
  147. {
  148. IPAERR("ipa_nat_map_add(index(%u)) failed\n", record_index);
  149. return -EINVAL;
  150. }
  151. if ( itr_ptr->next_index == record_index )
  152. {
  153. IPAERR("Infinite loop detected in IPv4 index %s table, entry %u\n",
  154. (is_expn_tbl) ? "expansion" : "base",
  155. record_index);
  156. ipa_nat_dump_ipv4_table(tbl_hdl);
  157. return -EINVAL;
  158. }
  159. return 0;
  160. }
  161. static int index_validity_check(
  162. ipa_table* table_ptr,
  163. uint32_t rule_hdl,
  164. void* record_ptr,
  165. uint16_t record_index,
  166. void* meta_record_ptr,
  167. uint16_t meta_record_index,
  168. void* arb_data_ptr )
  169. {
  170. enum ipa3_nat_mem_in nmi;
  171. uint8_t is_expn_tbl;
  172. uint16_t rule_index;
  173. uint16_t index;
  174. struct ipa_nat_indx_tbl_rule* itr_ptr =
  175. (struct ipa_nat_indx_tbl_rule*) record_ptr;
  176. BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
  177. index = itr_ptr->next_index;
  178. if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
  179. {
  180. IPAERR("Invalid next index %u found in IPv4 index %s table entry %u\n",
  181. index,
  182. (is_expn_tbl) ? "expansion" : "base",
  183. rule_index);
  184. return -EINVAL;
  185. }
  186. if ( is_expn_tbl )
  187. {
  188. struct ipa_nat_indx_tbl_meta_info* mi_ptr = meta_record_ptr;
  189. if ( ! mi_ptr )
  190. {
  191. IPAERR("Missing meta pointer for IPv4 index %s table entry %u\n",
  192. "expansion",
  193. rule_index);
  194. return -EINVAL;
  195. }
  196. index = mi_ptr->prev_index;
  197. if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
  198. {
  199. IPAERR("Invalid previous index %u found in IPv4 index %s table entry %u\n",
  200. index,
  201. "expansion",
  202. rule_index);
  203. return -EINVAL;
  204. }
  205. }
  206. return 0;
  207. }
  208. int ipa_nat_validate_ipv4_table(
  209. u32 tbl_hdl )
  210. {
  211. int ret;
  212. /*
  213. * Map MAP_NUM_99 will be used to keep, and to check for,
  214. * record validity.
  215. *
  216. * The first walk will fill it. The second walk will use it...
  217. */
  218. ipa_nat_map_clear(MAP_NUM_99);
  219. IPADBG("Checking IPv4 active rules:\n");
  220. ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_NAT_TABLE, nat_rule_loop_check, tbl_hdl);
  221. if ( ret != 0 )
  222. {
  223. return ret;
  224. }
  225. ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_NAT_TABLE, nat_rule_validity_check, 0);
  226. if ( ret != 0 )
  227. {
  228. return ret;
  229. }
  230. /*
  231. * Map MAP_NUM_99 will be used to keep, and to check for,
  232. * record validity.
  233. *
  234. * The first walk will fill it. The second walk will use it...
  235. */
  236. ipa_nat_map_clear(MAP_NUM_99);
  237. IPADBG("Checking IPv4 index active rules:\n");
  238. ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_INDEX_TABLE, index_loop_check, tbl_hdl);
  239. if ( ret != 0 )
  240. {
  241. return ret;
  242. }
  243. ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_INDEX_TABLE, index_validity_check, 0);
  244. if ( ret != 0 )
  245. {
  246. return ret;
  247. }
  248. return 0;
  249. }
  250. static void
  251. _dispUsage(
  252. const char* progNamePtr )
  253. {
  254. printf(
  255. "Usage: %s [-d -r N -i N -e N -m mt]\n"
  256. "Where:\n"
  257. " -d Each test is discrete (create table, add rules, destroy table)\n"
  258. " If not specified, only one table create and destroy for all tests\n"
  259. " -r N Where N is the number of times to run the inotify regression test\n"
  260. " -i N Where N is the number of times (iterations) to run test\n"
  261. " -e N Where N is the number of entries in the NAT\n"
  262. " -m mt Where mt is the type of memory to use for the NAT\n"
  263. " Legal mt's: DDR, SRAM, or HYBRID (ie. use SRAM and DDR)\n"
  264. " -g M-N Run tests M through N only\n",
  265. progNamePtr);
  266. fflush(stdout);
  267. }
  268. static NatTests nt_array[] = {
  269. NAT_TEST_ENTRY(ipa_nat_test000, 1, 0),
  270. NAT_TEST_ENTRY(ipa_nat_test001, 1, 0),
  271. NAT_TEST_ENTRY(ipa_nat_test002, 1, 0),
  272. NAT_TEST_ENTRY(ipa_nat_test003, 1, 0),
  273. NAT_TEST_ENTRY(ipa_nat_test004, 1, 0),
  274. NAT_TEST_ENTRY(ipa_nat_test005, 1, 0),
  275. NAT_TEST_ENTRY(ipa_nat_test006, 1, 0),
  276. NAT_TEST_ENTRY(ipa_nat_test007, 1, 0),
  277. NAT_TEST_ENTRY(ipa_nat_test008, 1, 0),
  278. NAT_TEST_ENTRY(ipa_nat_test009, 1, 0),
  279. NAT_TEST_ENTRY(ipa_nat_test010, IPA_NAT_TEST_PRE_COND_TE, 0),
  280. NAT_TEST_ENTRY(ipa_nat_test011, IPA_NAT_TEST_PRE_COND_TE, 0),
  281. NAT_TEST_ENTRY(ipa_nat_test012, IPA_NAT_TEST_PRE_COND_TE, 0),
  282. NAT_TEST_ENTRY(ipa_nat_test013, IPA_NAT_TEST_PRE_COND_TE, 0),
  283. NAT_TEST_ENTRY(ipa_nat_test014, IPA_NAT_TEST_PRE_COND_TE, 0),
  284. NAT_TEST_ENTRY(ipa_nat_test015, IPA_NAT_TEST_PRE_COND_TE, 0),
  285. NAT_TEST_ENTRY(ipa_nat_test016, IPA_NAT_TEST_PRE_COND_TE, 0),
  286. NAT_TEST_ENTRY(ipa_nat_test017, IPA_NAT_TEST_PRE_COND_TE, 0),
  287. NAT_TEST_ENTRY(ipa_nat_test018, IPA_NAT_TEST_PRE_COND_TE, 0),
  288. NAT_TEST_ENTRY(ipa_nat_test019, IPA_NAT_TEST_PRE_COND_TE, 0),
  289. NAT_TEST_ENTRY(ipa_nat_test020, IPA_NAT_TEST_PRE_COND_TE, 0),
  290. NAT_TEST_ENTRY(ipa_nat_test021, IPA_NAT_TEST_PRE_COND_TE, 0),
  291. NAT_TEST_ENTRY(ipa_nat_test022, IPA_NAT_TEST_PRE_COND_TE, 0),
  292. NAT_TEST_ENTRY(ipa_nat_test023, IPA_NAT_TEST_PRE_COND_TE, 0),
  293. NAT_TEST_ENTRY(ipa_nat_test024, IPA_NAT_TEST_PRE_COND_TE, 0),
  294. NAT_TEST_ENTRY(ipa_nat_test025, IPA_NAT_TEST_PRE_COND_TE, 0),
  295. /*
  296. * Add new tests just above this comment. Keep the following two
  297. * at the end...
  298. */
  299. NAT_TEST_ENTRY(ipa_nat_test999, 1, 0),
  300. NAT_TEST_ENTRY(ipa_nat_testREG, 1, 0),
  301. };
  302. int main(
  303. int argc,
  304. char* argv[] )
  305. {
  306. int sep = 0;
  307. int ireg = 0;
  308. uint32_t nt = 1;
  309. int total_ents = 100;
  310. uint32_t ht = 0;
  311. uint32_t start = 0, end = 0;
  312. char* nat_mem_type = "DDR";
  313. uint32_t tbl_hdl = 0;
  314. uint32_t pub_ip_addr;
  315. uint32_t i, ub, cnt, exec, pass;
  316. void* adp;
  317. time_t t;
  318. int c, ret;
  319. IPADBG("Testing user space nat driver\n");
  320. while ( (c = getopt(argc, argv, "dr:i:e:m:h:g:?")) != -1 )
  321. {
  322. switch (c)
  323. {
  324. case 'd':
  325. sep = 1;
  326. break;
  327. case 'r':
  328. ireg = atoi(optarg);
  329. break;
  330. case 'i':
  331. nt = atoi(optarg);
  332. break;
  333. case 'e':
  334. total_ents = atoi(optarg);
  335. break;
  336. case 'm':
  337. if ( ! (nat_mem_type = legal_mem_type(optarg)) )
  338. {
  339. fprintf(stderr, "Illegal: -m %s\n", optarg);
  340. _dispUsage(basename(argv[0]));
  341. exit(0);
  342. }
  343. break;
  344. case 'h':
  345. ht = atoi(optarg);
  346. break;
  347. case 'g':
  348. if ( sscanf(optarg, "%u-%u", &start, &end) != 2
  349. ||
  350. ( start >= end || end >= array_sz(nt_array) - 1 ) )
  351. {
  352. fprintf(stderr, "Illegal: -f %s\n", optarg);
  353. _dispUsage(basename(argv[0]));
  354. exit(0);
  355. }
  356. break;
  357. case '?':
  358. default:
  359. _dispUsage(basename(argv[0]));
  360. exit(0);
  361. break;
  362. }
  363. }
  364. srand(time(&t));
  365. pub_ip_addr = RAN_ADDR;
  366. exec = pass = 0;
  367. for ( cnt = ret = 0; cnt < nt && ret == 0; cnt++ )
  368. {
  369. IPADBG("ITERATION [%u] OF TESING\n", cnt + 1);
  370. if ( ireg )
  371. {
  372. adp = &ireg;
  373. i = array_sz(nt_array) - 1;
  374. ub = array_sz(nt_array);
  375. }
  376. else
  377. {
  378. adp = &tbl_hdl;
  379. i = ( end ) ? start : 0;
  380. ub = ( end ) ? end : array_sz(nt_array) - 1;
  381. if ( i != 0 && ! sep )
  382. {
  383. ipa_nat_test000(
  384. nat_mem_type, pub_ip_addr, total_ents, tbl_hdl, 0, adp);
  385. }
  386. }
  387. for ( ; i < ub && ret == 0; i++ )
  388. {
  389. if ( total_ents >= nt_array[i].num_ents_trigger )
  390. {
  391. IPADBG("+------------------------------------------------+\n");
  392. IPADBG("| Executing test: %s |\n", nt_array[i].func_name);
  393. IPADBG("+------------------------------------------------+\n");
  394. ret = nt_array[i].func(
  395. nat_mem_type, pub_ip_addr, total_ents, tbl_hdl, sep, adp);
  396. exec++;
  397. if ( ret == 0 )
  398. {
  399. IPADBG("<<<<< Test %s SUCCEEDED >>>>>\n", nt_array[i].func_name);
  400. pass++;
  401. if ( ht || nt_array[i].test_hold_time_in_secs )
  402. {
  403. ht = (ht) ? ht : nt_array[i].test_hold_time_in_secs;
  404. sleep(ht);
  405. }
  406. }
  407. else
  408. {
  409. IPAERR("<<<<< Test %s FAILED >>>>>\n", nt_array[i].func_name);
  410. }
  411. }
  412. }
  413. }
  414. if ( ret && tbl_hdl )
  415. {
  416. ipa_nat_test999(
  417. nat_mem_type, pub_ip_addr, total_ents, tbl_hdl, 0, &tbl_hdl);
  418. }
  419. IPADBG("Total NAT Tests Run:%u, Pass:%u, Fail:%u\n",
  420. exec, pass, exec - pass);
  421. return 0;
  422. }