123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- /*
- * Copyright (c) 2014, 2018-2019 The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <libgen.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #include "ipa_nat_test.h"
- #include "ipa_nat_map.h"
- #undef strcasesame
- #define strcasesame(x, y) \
- (! strcasecmp((x), (y)))
- static inline const char* legal_mem_type(
- const char* mt )
- {
- if ( strcasesame(mt, "DDR") ) return "DDR";
- if ( strcasesame(mt, "SRAM") ) return "SRAM";
- if ( strcasesame(mt, "HYBRID") ) return "HYBRID";
- return NULL;
- }
- static int nat_rule_loop_check(
- ipa_table* table_ptr,
- uint32_t rule_hdl,
- void* record_ptr,
- uint16_t record_index,
- void* meta_record_ptr,
- uint16_t meta_record_index,
- void* arb_data_ptr )
- {
- enum ipa3_nat_mem_in nmi;
- uint8_t is_expn_tbl;
- uint16_t rule_index;
- uint32_t tbl_hdl = (uint32_t) arb_data_ptr;
- struct ipa_nat_rule* rule_ptr =
- (struct ipa_nat_rule*) record_ptr;
- BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
- /*
- * By virtue of this function being called back by the walk, this
- * record_index is valid. Denote it as such in the map...
- */
- if ( ipa_nat_map_add(MAP_NUM_99, record_index, 1) )
- {
- IPAERR("ipa_nat_map_add(index(%u)) failed\n", record_index);
- return -EINVAL;
- }
- if ( rule_ptr->next_index == record_index )
- {
- IPAERR("Infinite loop detected in IPv4 %s table, entry %u\n",
- (is_expn_tbl) ? "expansion" : "base",
- record_index);
- ipa_nat_dump_ipv4_table(tbl_hdl);
- return -EINVAL;
- }
- return 0;
- }
- static int nat_rule_validity_check(
- ipa_table* table_ptr,
- uint32_t rule_hdl,
- void* record_ptr,
- uint16_t record_index,
- void* meta_record_ptr,
- uint16_t meta_record_index,
- void* arb_data_ptr )
- {
- enum ipa3_nat_mem_in nmi;
- uint8_t is_expn_tbl;
- uint16_t rule_index;
- uint16_t index;
- struct ipa_nat_rule* rule_ptr =
- (struct ipa_nat_rule*) record_ptr;
- BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
- index = rule_ptr->next_index;
- if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
- {
- IPAERR("Invalid next index %u found in IPv4 %s table entry %u\n",
- index,
- (is_expn_tbl) ? "expansion" : "base",
- rule_index);
- return -EINVAL;
- }
- if ( is_expn_tbl )
- {
- index = rule_ptr->prev_index;
- if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
- {
- IPAERR("Invalid previous index %u found in IPv4 %s table entry %u\n",
- index,
- "expansion",
- rule_index);
- return -EINVAL;
- }
- }
- return 0;
- }
- static int index_loop_check(
- ipa_table* table_ptr,
- uint32_t rule_hdl,
- void* record_ptr,
- uint16_t record_index,
- void* meta_record_ptr,
- uint16_t meta_record_index,
- void* arb_data_ptr )
- {
- enum ipa3_nat_mem_in nmi;
- uint8_t is_expn_tbl;
- uint16_t rule_index;
- uint32_t tbl_hdl = (uint32_t) arb_data_ptr;
- struct ipa_nat_indx_tbl_rule* itr_ptr =
- (struct ipa_nat_indx_tbl_rule*) record_ptr;
- BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
- /*
- * By virtue of this function being called back by the walk, this
- * record_index is valid. Denote it as such in the map...
- */
- if ( ipa_nat_map_add(MAP_NUM_99, record_index, 1) )
- {
- IPAERR("ipa_nat_map_add(index(%u)) failed\n", record_index);
- return -EINVAL;
- }
- if ( itr_ptr->next_index == record_index )
- {
- IPAERR("Infinite loop detected in IPv4 index %s table, entry %u\n",
- (is_expn_tbl) ? "expansion" : "base",
- record_index);
- ipa_nat_dump_ipv4_table(tbl_hdl);
- return -EINVAL;
- }
- return 0;
- }
- static int index_validity_check(
- ipa_table* table_ptr,
- uint32_t rule_hdl,
- void* record_ptr,
- uint16_t record_index,
- void* meta_record_ptr,
- uint16_t meta_record_index,
- void* arb_data_ptr )
- {
- enum ipa3_nat_mem_in nmi;
- uint8_t is_expn_tbl;
- uint16_t rule_index;
- uint16_t index;
- struct ipa_nat_indx_tbl_rule* itr_ptr =
- (struct ipa_nat_indx_tbl_rule*) record_ptr;
- BREAK_RULE_HDL(table_ptr, rule_hdl, nmi, is_expn_tbl, rule_index);
- index = itr_ptr->next_index;
- if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
- {
- IPAERR("Invalid next index %u found in IPv4 index %s table entry %u\n",
- index,
- (is_expn_tbl) ? "expansion" : "base",
- rule_index);
- return -EINVAL;
- }
- if ( is_expn_tbl )
- {
- struct ipa_nat_indx_tbl_meta_info* mi_ptr = meta_record_ptr;
- if ( ! mi_ptr )
- {
- IPAERR("Missing meta pointer for IPv4 index %s table entry %u\n",
- "expansion",
- rule_index);
- return -EINVAL;
- }
- index = mi_ptr->prev_index;
- if ( index && ipa_nat_map_find(MAP_NUM_99, index, NULL) )
- {
- IPAERR("Invalid previous index %u found in IPv4 index %s table entry %u\n",
- index,
- "expansion",
- rule_index);
- return -EINVAL;
- }
- }
- return 0;
- }
- int ipa_nat_validate_ipv4_table(
- u32 tbl_hdl )
- {
- int ret;
- /*
- * Map MAP_NUM_99 will be used to keep, and to check for,
- * record validity.
- *
- * The first walk will fill it. The second walk will use it...
- */
- ipa_nat_map_clear(MAP_NUM_99);
- IPADBG("Checking IPv4 active rules:\n");
- ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_NAT_TABLE, nat_rule_loop_check, tbl_hdl);
- if ( ret != 0 )
- {
- return ret;
- }
- ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_NAT_TABLE, nat_rule_validity_check, 0);
- if ( ret != 0 )
- {
- return ret;
- }
- /*
- * Map MAP_NUM_99 will be used to keep, and to check for,
- * record validity.
- *
- * The first walk will fill it. The second walk will use it...
- */
- ipa_nat_map_clear(MAP_NUM_99);
- IPADBG("Checking IPv4 index active rules:\n");
- ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_INDEX_TABLE, index_loop_check, tbl_hdl);
- if ( ret != 0 )
- {
- return ret;
- }
- ret = ipa_nati_walk_ipv4_tbl(tbl_hdl, USE_INDEX_TABLE, index_validity_check, 0);
- if ( ret != 0 )
- {
- return ret;
- }
- return 0;
- }
- static void
- _dispUsage(
- const char* progNamePtr )
- {
- printf(
- "Usage: %s [-d -r N -i N -e N -m mt]\n"
- "Where:\n"
- " -d Each test is discrete (create table, add rules, destroy table)\n"
- " If not specified, only one table create and destroy for all tests\n"
- " -r N Where N is the number of times to run the inotify regression test\n"
- " -i N Where N is the number of times (iterations) to run test\n"
- " -e N Where N is the number of entries in the NAT\n"
- " -m mt Where mt is the type of memory to use for the NAT\n"
- " Legal mt's: DDR, SRAM, or HYBRID (ie. use SRAM and DDR)\n"
- " -g M-N Run tests M through N only\n",
- progNamePtr);
- fflush(stdout);
- }
- static NatTests nt_array[] = {
- NAT_TEST_ENTRY(ipa_nat_test000, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test001, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test002, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test003, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test004, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test005, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test006, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test007, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test008, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test009, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_test010, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test011, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test012, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test013, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test014, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test015, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test016, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test017, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test018, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test019, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test020, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test021, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test022, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test023, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test024, IPA_NAT_TEST_PRE_COND_TE, 0),
- NAT_TEST_ENTRY(ipa_nat_test025, IPA_NAT_TEST_PRE_COND_TE, 0),
- /*
- * Add new tests just above this comment. Keep the following two
- * at the end...
- */
- NAT_TEST_ENTRY(ipa_nat_test999, 1, 0),
- NAT_TEST_ENTRY(ipa_nat_testREG, 1, 0),
- };
- int main(
- int argc,
- char* argv[] )
- {
- int sep = 0;
- int ireg = 0;
- uint32_t nt = 1;
- int total_ents = 100;
- uint32_t ht = 0;
- uint32_t start = 0, end = 0;
- char* nat_mem_type = "DDR";
- uint32_t tbl_hdl = 0;
- uint32_t pub_ip_addr;
- uint32_t i, ub, cnt, exec, pass;
- void* adp;
- time_t t;
- int c, ret;
- IPADBG("Testing user space nat driver\n");
- while ( (c = getopt(argc, argv, "dr:i:e:m:h:g:?")) != -1 )
- {
- switch (c)
- {
- case 'd':
- sep = 1;
- break;
- case 'r':
- ireg = atoi(optarg);
- break;
- case 'i':
- nt = atoi(optarg);
- break;
- case 'e':
- total_ents = atoi(optarg);
- break;
- case 'm':
- if ( ! (nat_mem_type = legal_mem_type(optarg)) )
- {
- fprintf(stderr, "Illegal: -m %s\n", optarg);
- _dispUsage(basename(argv[0]));
- exit(0);
- }
- break;
- case 'h':
- ht = atoi(optarg);
- break;
- case 'g':
- if ( sscanf(optarg, "%u-%u", &start, &end) != 2
- ||
- ( start >= end || end >= array_sz(nt_array) - 1 ) )
- {
- fprintf(stderr, "Illegal: -f %s\n", optarg);
- _dispUsage(basename(argv[0]));
- exit(0);
- }
- break;
- case '?':
- default:
- _dispUsage(basename(argv[0]));
- exit(0);
- break;
- }
- }
- srand(time(&t));
- pub_ip_addr = RAN_ADDR;
- exec = pass = 0;
- for ( cnt = ret = 0; cnt < nt && ret == 0; cnt++ )
- {
- IPADBG("ITERATION [%u] OF TESING\n", cnt + 1);
- if ( ireg )
- {
- adp = &ireg;
- i = array_sz(nt_array) - 1;
- ub = array_sz(nt_array);
- }
- else
- {
- adp = &tbl_hdl;
- i = ( end ) ? start : 0;
- ub = ( end ) ? end : array_sz(nt_array) - 1;
- if ( i != 0 && ! sep )
- {
- ipa_nat_test000(
- nat_mem_type, pub_ip_addr, total_ents, tbl_hdl, 0, adp);
- }
- }
- for ( ; i < ub && ret == 0; i++ )
- {
- if ( total_ents >= nt_array[i].num_ents_trigger )
- {
- IPADBG("+------------------------------------------------+\n");
- IPADBG("| Executing test: %s |\n", nt_array[i].func_name);
- IPADBG("+------------------------------------------------+\n");
- ret = nt_array[i].func(
- nat_mem_type, pub_ip_addr, total_ents, tbl_hdl, sep, adp);
- exec++;
- if ( ret == 0 )
- {
- IPADBG("<<<<< Test %s SUCCEEDED >>>>>\n", nt_array[i].func_name);
- pass++;
- if ( ht || nt_array[i].test_hold_time_in_secs )
- {
- ht = (ht) ? ht : nt_array[i].test_hold_time_in_secs;
- sleep(ht);
- }
- }
- else
- {
- IPAERR("<<<<< Test %s FAILED >>>>>\n", nt_array[i].func_name);
- }
- }
- }
- }
- if ( ret && tbl_hdl )
- {
- ipa_nat_test999(
- nat_mem_type, pub_ip_addr, total_ents, tbl_hdl, 0, &tbl_hdl);
- }
- IPADBG("Total NAT Tests Run:%u, Pass:%u, Fail:%u\n",
- exec, pass, exec - pass);
- return 0;
- }
|