15129044dSC.J. Collier/*-
25129044dSC.J. Collier *   BSD LICENSE
35129044dSC.J. Collier *
45129044dSC.J. Collier *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
55129044dSC.J. Collier *   All rights reserved.
65129044dSC.J. Collier *
75129044dSC.J. Collier *   Redistribution and use in source and binary forms, with or without
85129044dSC.J. Collier *   modification, are permitted provided that the following conditions
95129044dSC.J. Collier *   are met:
105129044dSC.J. Collier *
115129044dSC.J. Collier *     * Redistributions of source code must retain the above copyright
125129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer.
135129044dSC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
145129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer in
155129044dSC.J. Collier *       the documentation and/or other materials provided with the
165129044dSC.J. Collier *       distribution.
175129044dSC.J. Collier *     * Neither the name of Intel Corporation nor the names of its
185129044dSC.J. Collier *       contributors may be used to endorse or promote products derived
195129044dSC.J. Collier *       from this software without specific prior written permission.
205129044dSC.J. Collier *
215129044dSC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
225129044dSC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
235129044dSC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
245129044dSC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
255129044dSC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
265129044dSC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
275129044dSC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
285129044dSC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
295129044dSC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
305129044dSC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
315129044dSC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
325129044dSC.J. Collier */
33809f0800SChristian Ehrhardt
345129044dSC.J. Collier#include <stdio.h>
355129044dSC.J. Collier#include <stdint.h>
365129044dSC.J. Collier#include <stdlib.h>
375129044dSC.J. Collier#include <string.h>
385129044dSC.J. Collier
395129044dSC.J. Collier#include <rte_memory.h>
40809f0800SChristian Ehrhardt#include <rte_lpm6.h>
415129044dSC.J. Collier
42809f0800SChristian Ehrhardt#include "test.h"
433d9b7210SChristian Ehrhardt#include "test_lpm6_data.h"
445129044dSC.J. Collier
455129044dSC.J. Collier#define TEST_LPM_ASSERT(cond) do {                                            \
465129044dSC.J. Collier	if (!(cond)) {                                                        \
475129044dSC.J. Collier		printf("Error at line %d: \n", __LINE__);                     \
485129044dSC.J. Collier		return -1;                                                    \
495129044dSC.J. Collier	}                                                                     \
505129044dSC.J. Collier} while(0)
515129044dSC.J. Collier
525129044dSC.J. Colliertypedef int32_t (* rte_lpm6_test)(void);
535129044dSC.J. Collier
545129044dSC.J. Collierstatic int32_t test0(void);
555129044dSC.J. Collierstatic int32_t test1(void);
565129044dSC.J. Collierstatic int32_t test2(void);
575129044dSC.J. Collierstatic int32_t test3(void);
585129044dSC.J. Collierstatic int32_t test4(void);
595129044dSC.J. Collierstatic int32_t test5(void);
605129044dSC.J. Collierstatic int32_t test6(void);
615129044dSC.J. Collierstatic int32_t test7(void);
625129044dSC.J. Collierstatic int32_t test8(void);
635129044dSC.J. Collierstatic int32_t test9(void);
645129044dSC.J. Collierstatic int32_t test10(void);
655129044dSC.J. Collierstatic int32_t test11(void);
665129044dSC.J. Collierstatic int32_t test12(void);
675129044dSC.J. Collierstatic int32_t test13(void);
685129044dSC.J. Collierstatic int32_t test14(void);
695129044dSC.J. Collierstatic int32_t test15(void);
705129044dSC.J. Collierstatic int32_t test16(void);
715129044dSC.J. Collierstatic int32_t test17(void);
725129044dSC.J. Collierstatic int32_t test18(void);
735129044dSC.J. Collierstatic int32_t test19(void);
745129044dSC.J. Collierstatic int32_t test20(void);
755129044dSC.J. Collierstatic int32_t test21(void);
765129044dSC.J. Collierstatic int32_t test22(void);
775129044dSC.J. Collierstatic int32_t test23(void);
785129044dSC.J. Collierstatic int32_t test24(void);
795129044dSC.J. Collierstatic int32_t test25(void);
805129044dSC.J. Collierstatic int32_t test26(void);
815129044dSC.J. Collierstatic int32_t test27(void);
825129044dSC.J. Collier
835129044dSC.J. Collierrte_lpm6_test tests6[] = {
845129044dSC.J. Collier/* Test Cases */
855129044dSC.J. Collier	test0,
865129044dSC.J. Collier	test1,
875129044dSC.J. Collier	test2,
885129044dSC.J. Collier	test3,
895129044dSC.J. Collier	test4,
905129044dSC.J. Collier	test5,
915129044dSC.J. Collier	test6,
925129044dSC.J. Collier	test7,
935129044dSC.J. Collier	test8,
945129044dSC.J. Collier	test9,
955129044dSC.J. Collier	test10,
965129044dSC.J. Collier	test11,
975129044dSC.J. Collier	test12,
985129044dSC.J. Collier	test13,
995129044dSC.J. Collier	test14,
1005129044dSC.J. Collier	test15,
1015129044dSC.J. Collier	test16,
1025129044dSC.J. Collier	test17,
1035129044dSC.J. Collier	test18,
1045129044dSC.J. Collier	test19,
1055129044dSC.J. Collier	test20,
1065129044dSC.J. Collier	test21,
1075129044dSC.J. Collier	test22,
1085129044dSC.J. Collier	test23,
1095129044dSC.J. Collier	test24,
1105129044dSC.J. Collier	test25,
1115129044dSC.J. Collier	test26,
1125129044dSC.J. Collier	test27,
1135129044dSC.J. Collier};
1145129044dSC.J. Collier
1155129044dSC.J. Collier#define NUM_LPM6_TESTS                (sizeof(tests6)/sizeof(tests6[0]))
1165129044dSC.J. Collier#define MAX_DEPTH                                                    128
1175129044dSC.J. Collier#define MAX_RULES                                                1000000
1185129044dSC.J. Collier#define NUMBER_TBL8S                                           (1 << 16)
1195129044dSC.J. Collier#define MAX_NUM_TBL8S                                          (1 << 21)
1205129044dSC.J. Collier#define PASS 0
1215129044dSC.J. Collier
1225129044dSC.J. Collierstatic void
1235129044dSC.J. CollierIPv6(uint8_t *ip, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5,
1245129044dSC.J. Collier		uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10,
1255129044dSC.J. Collier		uint8_t b11, uint8_t b12, uint8_t b13, uint8_t b14, uint8_t b15,
1265129044dSC.J. Collier		uint8_t b16)
1275129044dSC.J. Collier{
1285129044dSC.J. Collier	ip[0] = b1;
1295129044dSC.J. Collier	ip[1] = b2;
1305129044dSC.J. Collier	ip[2] = b3;
1315129044dSC.J. Collier	ip[3] = b4;
1325129044dSC.J. Collier	ip[4] = b5;
1335129044dSC.J. Collier	ip[5] = b6;
1345129044dSC.J. Collier	ip[6] = b7;
1355129044dSC.J. Collier	ip[7] = b8;
1365129044dSC.J. Collier	ip[8] = b9;
1375129044dSC.J. Collier	ip[9] = b10;
1385129044dSC.J. Collier	ip[10] = b11;
1395129044dSC.J. Collier	ip[11] = b12;
1405129044dSC.J. Collier	ip[12] = b13;
1415129044dSC.J. Collier	ip[13] = b14;
1425129044dSC.J. Collier	ip[14] = b15;
1435129044dSC.J. Collier	ip[15] = b16;
1445129044dSC.J. Collier}
1455129044dSC.J. Collier
1465129044dSC.J. Collier/*
1475129044dSC.J. Collier * Check that rte_lpm6_create fails gracefully for incorrect user input
1485129044dSC.J. Collier * arguments
1495129044dSC.J. Collier */
1505129044dSC.J. Collierint32_t
1515129044dSC.J. Colliertest0(void)
1525129044dSC.J. Collier{
1535129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
1545129044dSC.J. Collier	struct rte_lpm6_config config;
1555129044dSC.J. Collier
1565129044dSC.J. Collier	config.max_rules = MAX_RULES;
1575129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
1585129044dSC.J. Collier	config.flags = 0;
1595129044dSC.J. Collier
1605129044dSC.J. Collier	/* rte_lpm6_create: lpm name == NULL */
1615129044dSC.J. Collier	lpm = rte_lpm6_create(NULL, SOCKET_ID_ANY, &config);
1625129044dSC.J. Collier	TEST_LPM_ASSERT(lpm == NULL);
1635129044dSC.J. Collier
1645129044dSC.J. Collier	/* rte_lpm6_create: max_rules = 0 */
1655129044dSC.J. Collier	/* Note: __func__ inserts the function name, in this case "test0". */
1665129044dSC.J. Collier	config.max_rules = 0;
1675129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1685129044dSC.J. Collier	TEST_LPM_ASSERT(lpm == NULL);
1695129044dSC.J. Collier
1705129044dSC.J. Collier	/* socket_id < -1 is invalid */
1715129044dSC.J. Collier	config.max_rules = MAX_RULES;
1725129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, -2, &config);
1735129044dSC.J. Collier	TEST_LPM_ASSERT(lpm == NULL);
1745129044dSC.J. Collier
1755129044dSC.J. Collier	/* rte_lpm6_create: number_tbl8s is bigger than the maximum */
1765129044dSC.J. Collier	config.number_tbl8s = MAX_NUM_TBL8S + 1;
1775129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1785129044dSC.J. Collier	TEST_LPM_ASSERT(lpm == NULL);
1795129044dSC.J. Collier
1805129044dSC.J. Collier	/* rte_lpm6_create: config = NULL */
1815129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, NULL);
1825129044dSC.J. Collier	TEST_LPM_ASSERT(lpm == NULL);
1835129044dSC.J. Collier
1845129044dSC.J. Collier	return PASS;
1855129044dSC.J. Collier}
1865129044dSC.J. Collier
1875129044dSC.J. Collier/*
1885129044dSC.J. Collier * Creates two different LPM tables. Tries to create a third one with the same
1895129044dSC.J. Collier * name as the first one and expects the create function to return the same
1905129044dSC.J. Collier * pointer.
1915129044dSC.J. Collier */
1925129044dSC.J. Collierint32_t
1935129044dSC.J. Colliertest1(void)
1945129044dSC.J. Collier{
1955129044dSC.J. Collier	struct rte_lpm6 *lpm1 = NULL, *lpm2 = NULL, *lpm3 = NULL;
1965129044dSC.J. Collier	struct rte_lpm6_config config;
1975129044dSC.J. Collier
1985129044dSC.J. Collier	config.max_rules = MAX_RULES;
1995129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
2005129044dSC.J. Collier	config.flags = 0;
2015129044dSC.J. Collier
2025129044dSC.J. Collier	/* rte_lpm6_create: lpm name == LPM1 */
2035129044dSC.J. Collier	lpm1 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config);
2045129044dSC.J. Collier	TEST_LPM_ASSERT(lpm1 != NULL);
2055129044dSC.J. Collier
2065129044dSC.J. Collier	/* rte_lpm6_create: lpm name == LPM2 */
2075129044dSC.J. Collier	lpm2 = rte_lpm6_create("LPM2", SOCKET_ID_ANY, &config);
2085129044dSC.J. Collier	TEST_LPM_ASSERT(lpm2 != NULL);
2095129044dSC.J. Collier
2105129044dSC.J. Collier	/* rte_lpm6_create: lpm name == LPM2 */
2115129044dSC.J. Collier	lpm3 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config);
2125129044dSC.J. Collier	TEST_LPM_ASSERT(lpm3 == NULL);
2135129044dSC.J. Collier
2145129044dSC.J. Collier	rte_lpm6_free(lpm1);
2155129044dSC.J. Collier	rte_lpm6_free(lpm2);
2165129044dSC.J. Collier
2175129044dSC.J. Collier	return PASS;
2185129044dSC.J. Collier}
2195129044dSC.J. Collier
2205129044dSC.J. Collier/*
221809f0800SChristian Ehrhardt * Create lpm table then delete lpm table 20 times
2225129044dSC.J. Collier * Use a slightly different rules size each time
2235129044dSC.J. Collier */
2245129044dSC.J. Collierint32_t
2255129044dSC.J. Colliertest2(void)
2265129044dSC.J. Collier{
2275129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
2285129044dSC.J. Collier	struct rte_lpm6_config config;
2295129044dSC.J. Collier	int32_t i;
2305129044dSC.J. Collier
2315129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
2325129044dSC.J. Collier	config.flags = 0;
2335129044dSC.J. Collier
2345129044dSC.J. Collier	/* rte_lpm6_free: Free NULL */
235809f0800SChristian Ehrhardt	for (i = 0; i < 20; i++) {
2365129044dSC.J. Collier		config.max_rules = MAX_RULES - i;
2375129044dSC.J. Collier		lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
2385129044dSC.J. Collier		TEST_LPM_ASSERT(lpm != NULL);
2395129044dSC.J. Collier
2405129044dSC.J. Collier		rte_lpm6_free(lpm);
2415129044dSC.J. Collier	}
2425129044dSC.J. Collier
2435129044dSC.J. Collier	/* Can not test free so return success */
2445129044dSC.J. Collier	return PASS;
2455129044dSC.J. Collier}
2465129044dSC.J. Collier
2475129044dSC.J. Collier/*
2485129044dSC.J. Collier * Call rte_lpm6_free for NULL pointer user input. Note: free has no return and
2495129044dSC.J. Collier * therefore it is impossible to check for failure but this test is added to
2505129044dSC.J. Collier * increase function coverage metrics and to validate that freeing null does
2515129044dSC.J. Collier * not crash.
2525129044dSC.J. Collier */
2535129044dSC.J. Collierint32_t
2545129044dSC.J. Colliertest3(void)
2555129044dSC.J. Collier{
2565129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
2575129044dSC.J. Collier	struct rte_lpm6_config config;
2585129044dSC.J. Collier
2595129044dSC.J. Collier	config.max_rules = MAX_RULES;
2605129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
2615129044dSC.J. Collier	config.flags = 0;
2625129044dSC.J. Collier
2635129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
2645129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
2655129044dSC.J. Collier
2665129044dSC.J. Collier	rte_lpm6_free(lpm);
2675129044dSC.J. Collier	rte_lpm6_free(NULL);
2685129044dSC.J. Collier	return PASS;
2695129044dSC.J. Collier}
2705129044dSC.J. Collier
2715129044dSC.J. Collier/*
2725129044dSC.J. Collier * Check that rte_lpm6_add fails gracefully for incorrect user input arguments
2735129044dSC.J. Collier */
2745129044dSC.J. Collierint32_t
2755129044dSC.J. Colliertest4(void)
2765129044dSC.J. Collier{
2775129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
2785129044dSC.J. Collier	struct rte_lpm6_config config;
2795129044dSC.J. Collier
2805129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2815129044dSC.J. Collier	uint8_t depth = 24, next_hop = 100;
2825129044dSC.J. Collier	int32_t status = 0;
2835129044dSC.J. Collier
2845129044dSC.J. Collier	config.max_rules = MAX_RULES;
2855129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
2865129044dSC.J. Collier	config.flags = 0;
2875129044dSC.J. Collier
2885129044dSC.J. Collier	/* rte_lpm6_add: lpm == NULL */
2895129044dSC.J. Collier	status = rte_lpm6_add(NULL, ip, depth, next_hop);
2905129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
2915129044dSC.J. Collier
2925129044dSC.J. Collier	/*Create vaild lpm to use in rest of test. */
2935129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
2945129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
2955129044dSC.J. Collier
2965129044dSC.J. Collier	/* rte_lpm6_add: depth < 1 */
2975129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, 0, next_hop);
2985129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
2995129044dSC.J. Collier
3005129044dSC.J. Collier	/* rte_lpm6_add: depth > MAX_DEPTH */
3015129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, (MAX_DEPTH + 1), next_hop);
3025129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3035129044dSC.J. Collier
3045129044dSC.J. Collier	rte_lpm6_free(lpm);
3055129044dSC.J. Collier
3065129044dSC.J. Collier	return PASS;
3075129044dSC.J. Collier}
3085129044dSC.J. Collier
3095129044dSC.J. Collier/*
3105129044dSC.J. Collier * Check that rte_lpm6_delete fails gracefully for incorrect user input
3115129044dSC.J. Collier * arguments
3125129044dSC.J. Collier */
3135129044dSC.J. Collierint32_t
3145129044dSC.J. Colliertest5(void)
3155129044dSC.J. Collier{
3165129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
3175129044dSC.J. Collier	struct rte_lpm6_config config;
3185129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3195129044dSC.J. Collier	uint8_t depth = 24;
3205129044dSC.J. Collier	int32_t status = 0;
3215129044dSC.J. Collier
3225129044dSC.J. Collier	config.max_rules = MAX_RULES;
3235129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
3245129044dSC.J. Collier	config.flags = 0;
3255129044dSC.J. Collier
3265129044dSC.J. Collier	/* rte_lpm_delete: lpm == NULL */
3275129044dSC.J. Collier	status = rte_lpm6_delete(NULL, ip, depth);
3285129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3295129044dSC.J. Collier
3305129044dSC.J. Collier	/*Create vaild lpm to use in rest of test. */
3315129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
3325129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
3335129044dSC.J. Collier
3345129044dSC.J. Collier	/* rte_lpm_delete: depth < 1 */
3355129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, 0);
3365129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3375129044dSC.J. Collier
3385129044dSC.J. Collier	/* rte_lpm_delete: depth > MAX_DEPTH */
3395129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, (MAX_DEPTH + 1));
3405129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3415129044dSC.J. Collier
3425129044dSC.J. Collier	rte_lpm6_free(lpm);
3435129044dSC.J. Collier
3445129044dSC.J. Collier	return PASS;
3455129044dSC.J. Collier}
3465129044dSC.J. Collier
3475129044dSC.J. Collier/*
3485129044dSC.J. Collier * Check that rte_lpm6_lookup fails gracefully for incorrect user input
3495129044dSC.J. Collier * arguments
3505129044dSC.J. Collier */
3515129044dSC.J. Collierint32_t
3525129044dSC.J. Colliertest6(void)
3535129044dSC.J. Collier{
3545129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
3555129044dSC.J. Collier	struct rte_lpm6_config config;
3565129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3575129044dSC.J. Collier	uint8_t next_hop_return = 0;
3585129044dSC.J. Collier	int32_t status = 0;
3595129044dSC.J. Collier
3605129044dSC.J. Collier	config.max_rules = MAX_RULES;
3615129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
3625129044dSC.J. Collier	config.flags = 0;
3635129044dSC.J. Collier
3645129044dSC.J. Collier	/* rte_lpm6_lookup: lpm == NULL */
3655129044dSC.J. Collier	status = rte_lpm6_lookup(NULL, ip, &next_hop_return);
3665129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3675129044dSC.J. Collier
3685129044dSC.J. Collier	/*Create vaild lpm to use in rest of test. */
3695129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
3705129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
3715129044dSC.J. Collier
3725129044dSC.J. Collier	/* rte_lpm6_lookup: ip = NULL */
3735129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, NULL, &next_hop_return);
3745129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3755129044dSC.J. Collier
3765129044dSC.J. Collier	/* rte_lpm6_lookup: next_hop = NULL */
3775129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, NULL);
3785129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
3795129044dSC.J. Collier
3805129044dSC.J. Collier	rte_lpm6_free(lpm);
3815129044dSC.J. Collier
3825129044dSC.J. Collier	return PASS;
3835129044dSC.J. Collier}
3845129044dSC.J. Collier
3855129044dSC.J. Collier/*
3865129044dSC.J. Collier * Checks that rte_lpm6_lookup_bulk_func fails gracefully for incorrect user
3875129044dSC.J. Collier * input arguments
3885129044dSC.J. Collier */
3895129044dSC.J. Collierint32_t
3905129044dSC.J. Colliertest7(void)
3915129044dSC.J. Collier{
3925129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
3935129044dSC.J. Collier	struct rte_lpm6_config config;
3945129044dSC.J. Collier	uint8_t ip[10][16];
3955129044dSC.J. Collier	int16_t next_hop_return[10];
3965129044dSC.J. Collier	int32_t status = 0;
3975129044dSC.J. Collier
3985129044dSC.J. Collier	config.max_rules = MAX_RULES;
3995129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
4005129044dSC.J. Collier	config.flags = 0;
4015129044dSC.J. Collier
4025129044dSC.J. Collier	/* rte_lpm6_lookup: lpm == NULL */
4035129044dSC.J. Collier	status = rte_lpm6_lookup_bulk_func(NULL, ip, next_hop_return, 10);
4045129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
4055129044dSC.J. Collier
4065129044dSC.J. Collier	/*Create vaild lpm to use in rest of test. */
4075129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
4085129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
4095129044dSC.J. Collier
4105129044dSC.J. Collier	/* rte_lpm6_lookup: ip = NULL */
4115129044dSC.J. Collier	status = rte_lpm6_lookup_bulk_func(lpm, NULL, next_hop_return, 10);
4125129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
4135129044dSC.J. Collier
4145129044dSC.J. Collier	/* rte_lpm6_lookup: next_hop = NULL */
4155129044dSC.J. Collier	status = rte_lpm6_lookup_bulk_func(lpm, ip, NULL, 10);
4165129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
4175129044dSC.J. Collier
4185129044dSC.J. Collier	rte_lpm6_free(lpm);
4195129044dSC.J. Collier
4205129044dSC.J. Collier	return PASS;
4215129044dSC.J. Collier}
4225129044dSC.J. Collier
4235129044dSC.J. Collier/*
4245129044dSC.J. Collier * Checks that rte_lpm6_delete_bulk_func fails gracefully for incorrect user
4255129044dSC.J. Collier * input arguments
4265129044dSC.J. Collier */
4275129044dSC.J. Collierint32_t
4285129044dSC.J. Colliertest8(void)
4295129044dSC.J. Collier{
4305129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
4315129044dSC.J. Collier	struct rte_lpm6_config config;
4325129044dSC.J. Collier	uint8_t ip[10][16];
4335129044dSC.J. Collier	uint8_t depth[10];
4345129044dSC.J. Collier	int32_t status = 0;
4355129044dSC.J. Collier
4365129044dSC.J. Collier	config.max_rules = MAX_RULES;
4375129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
4385129044dSC.J. Collier	config.flags = 0;
4395129044dSC.J. Collier
4405129044dSC.J. Collier	/* rte_lpm6_delete: lpm == NULL */
4415129044dSC.J. Collier	status = rte_lpm6_delete_bulk_func(NULL, ip, depth, 10);
4425129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
4435129044dSC.J. Collier
4445129044dSC.J. Collier	/*Create vaild lpm to use in rest of test. */
4455129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
4465129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
4475129044dSC.J. Collier
4485129044dSC.J. Collier	/* rte_lpm6_delete: ip = NULL */
4495129044dSC.J. Collier	status = rte_lpm6_delete_bulk_func(lpm, NULL, depth, 10);
4505129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
4515129044dSC.J. Collier
4525129044dSC.J. Collier	/* rte_lpm6_delete: next_hop = NULL */
4535129044dSC.J. Collier	status = rte_lpm6_delete_bulk_func(lpm, ip, NULL, 10);
4545129044dSC.J. Collier	TEST_LPM_ASSERT(status < 0);
4555129044dSC.J. Collier
4565129044dSC.J. Collier	rte_lpm6_free(lpm);
4575129044dSC.J. Collier
4585129044dSC.J. Collier	return PASS;
4595129044dSC.J. Collier}
4605129044dSC.J. Collier
4615129044dSC.J. Collier/*
4625129044dSC.J. Collier * Call add, lookup and delete for a single rule with depth < 24.
4635129044dSC.J. Collier * Check all the combinations for the first three bytes that result in a hit.
4645129044dSC.J. Collier * Delete the rule and check that the same test returs a miss.
4655129044dSC.J. Collier */
4665129044dSC.J. Collierint32_t
4675129044dSC.J. Colliertest9(void)
4685129044dSC.J. Collier{
4695129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
4705129044dSC.J. Collier	struct rte_lpm6_config config;
4715129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4725129044dSC.J. Collier	uint8_t depth = 16, next_hop_add = 100, next_hop_return = 0;
4735129044dSC.J. Collier	int32_t status = 0;
4745129044dSC.J. Collier	uint8_t i;
4755129044dSC.J. Collier
4765129044dSC.J. Collier	config.max_rules = MAX_RULES;
4775129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
4785129044dSC.J. Collier	config.flags = 0;
4795129044dSC.J. Collier
4805129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
4815129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
4825129044dSC.J. Collier
4835129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
4845129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
4855129044dSC.J. Collier
4865129044dSC.J. Collier	for (i = 0; i < UINT8_MAX; i++) {
4875129044dSC.J. Collier		ip[2] = i;
4885129044dSC.J. Collier		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
4895129044dSC.J. Collier		TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
4905129044dSC.J. Collier	}
4915129044dSC.J. Collier
4925129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
4935129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
4945129044dSC.J. Collier
4955129044dSC.J. Collier	for (i = 0; i < UINT8_MAX; i++) {
4965129044dSC.J. Collier		ip[2] = i;
4975129044dSC.J. Collier		status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
4985129044dSC.J. Collier		TEST_LPM_ASSERT(status == -ENOENT);
4995129044dSC.J. Collier	}
5005129044dSC.J. Collier
5015129044dSC.J. Collier	rte_lpm6_free(lpm);
5025129044dSC.J. Collier
5035129044dSC.J. Collier	return PASS;
5045129044dSC.J. Collier}
5055129044dSC.J. Collier
5065129044dSC.J. Collier/*
5075129044dSC.J. Collier * Adds max_rules + 1 and expects a failure. Deletes a rule, then adds
5085129044dSC.J. Collier * another one and expects success.
5095129044dSC.J. Collier */
5105129044dSC.J. Collierint32_t
5115129044dSC.J. Colliertest10(void)
5125129044dSC.J. Collier{
5135129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
5145129044dSC.J. Collier	struct rte_lpm6_config config;
5155129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
5165129044dSC.J. Collier	uint8_t depth, next_hop_add = 100;
5175129044dSC.J. Collier	int32_t status = 0;
5185129044dSC.J. Collier	int i;
5195129044dSC.J. Collier
5205129044dSC.J. Collier	config.max_rules = 127;
5215129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
5225129044dSC.J. Collier	config.flags = 0;
5235129044dSC.J. Collier
5245129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
5255129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
5265129044dSC.J. Collier
5275129044dSC.J. Collier	for (i = 1; i < 128; i++) {
5285129044dSC.J. Collier		depth = (uint8_t)i;
5295129044dSC.J. Collier		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5305129044dSC.J. Collier		TEST_LPM_ASSERT(status == 0);
5315129044dSC.J. Collier	}
5325129044dSC.J. Collier
5335129044dSC.J. Collier	depth = 128;
5345129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5355129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOSPC);
5365129044dSC.J. Collier
5375129044dSC.J. Collier	depth = 127;
5385129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
5395129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5405129044dSC.J. Collier
5415129044dSC.J. Collier	depth = 128;
5425129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5435129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5445129044dSC.J. Collier
5455129044dSC.J. Collier	rte_lpm6_free(lpm);
5465129044dSC.J. Collier
5475129044dSC.J. Collier	return PASS;
5485129044dSC.J. Collier}
5495129044dSC.J. Collier
5505129044dSC.J. Collier/*
5515129044dSC.J. Collier * Creates an LPM table with a small number of tbl8s and exhaust them in the
5525129044dSC.J. Collier * middle of the process of creating a rule.
5535129044dSC.J. Collier */
5545129044dSC.J. Collierint32_t
5555129044dSC.J. Colliertest11(void)
5565129044dSC.J. Collier{
5575129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
5585129044dSC.J. Collier	struct rte_lpm6_config config;
5595129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
5605129044dSC.J. Collier	uint8_t depth, next_hop_add = 100;
5615129044dSC.J. Collier	int32_t status = 0;
5625129044dSC.J. Collier
5635129044dSC.J. Collier	config.max_rules = MAX_RULES;
5645129044dSC.J. Collier	config.number_tbl8s = 16;
5655129044dSC.J. Collier	config.flags = 0;
5665129044dSC.J. Collier
5675129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
5685129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
5695129044dSC.J. Collier
5705129044dSC.J. Collier	depth = 128;
5715129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5725129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5735129044dSC.J. Collier
5745129044dSC.J. Collier	ip[0] = 1;
5755129044dSC.J. Collier	depth = 25;
5765129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5775129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5785129044dSC.J. Collier
5795129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
5805129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5815129044dSC.J. Collier
5825129044dSC.J. Collier	depth = 33;
5835129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5845129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5855129044dSC.J. Collier
5865129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
5875129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5885129044dSC.J. Collier
5895129044dSC.J. Collier	depth = 41;
5905129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5915129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5925129044dSC.J. Collier
5935129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
5945129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
5955129044dSC.J. Collier
5965129044dSC.J. Collier	depth = 49;
5975129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
5985129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOSPC);
5995129044dSC.J. Collier
6005129044dSC.J. Collier	depth = 41;
6015129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6025129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6035129044dSC.J. Collier
6045129044dSC.J. Collier	rte_lpm6_free(lpm);
6055129044dSC.J. Collier
6065129044dSC.J. Collier	return PASS;
6075129044dSC.J. Collier}
6085129044dSC.J. Collier
6095129044dSC.J. Collier/*
6105129044dSC.J. Collier * Creates an LPM table with a small number of tbl8s and exhaust them in the
6115129044dSC.J. Collier * middle of the process of adding a rule when there is already an existing rule
6125129044dSC.J. Collier * in that position and needs to be extended.
6135129044dSC.J. Collier */
6145129044dSC.J. Collierint32_t
6155129044dSC.J. Colliertest12(void)
6165129044dSC.J. Collier{
6175129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
6185129044dSC.J. Collier	struct rte_lpm6_config config;
6195129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
6205129044dSC.J. Collier	uint8_t depth, next_hop_add = 100;
6215129044dSC.J. Collier	int32_t status = 0;
6225129044dSC.J. Collier
6235129044dSC.J. Collier	config.max_rules = MAX_RULES;
6245129044dSC.J. Collier	config.number_tbl8s = 16;
6255129044dSC.J. Collier	config.flags = 0;
6265129044dSC.J. Collier
6275129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
6285129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
6295129044dSC.J. Collier
6305129044dSC.J. Collier	depth = 128;
6315129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6325129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6335129044dSC.J. Collier
6345129044dSC.J. Collier	ip[0] = 1;
6355129044dSC.J. Collier	depth = 41;
6365129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6375129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6385129044dSC.J. Collier
6395129044dSC.J. Collier	depth = 49;
6405129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6415129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOSPC);
6425129044dSC.J. Collier
6435129044dSC.J. Collier	rte_lpm6_free(lpm);
6445129044dSC.J. Collier
6455129044dSC.J. Collier	return PASS;
6465129044dSC.J. Collier}
6475129044dSC.J. Collier
6485129044dSC.J. Collier/*
6495129044dSC.J. Collier * Creates an LPM table with max_rules = 2 and tries to add 3 rules.
6505129044dSC.J. Collier * Delete one of the rules and tries to add the third one again.
6515129044dSC.J. Collier */
6525129044dSC.J. Collierint32_t
6535129044dSC.J. Colliertest13(void)
6545129044dSC.J. Collier{
6555129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
6565129044dSC.J. Collier	struct rte_lpm6_config config;
6575129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
6585129044dSC.J. Collier	uint8_t depth, next_hop_add = 100;
6595129044dSC.J. Collier	int32_t status = 0;
6605129044dSC.J. Collier
6615129044dSC.J. Collier	config.max_rules = 2;
6625129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
6635129044dSC.J. Collier	config.flags = 0;
6645129044dSC.J. Collier
6655129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
6665129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
6675129044dSC.J. Collier
6685129044dSC.J. Collier	depth = 1;
6695129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6705129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6715129044dSC.J. Collier
6725129044dSC.J. Collier	depth = 2;
6735129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6745129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6755129044dSC.J. Collier
6765129044dSC.J. Collier	depth = 3;
6775129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6785129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOSPC);
6795129044dSC.J. Collier
6805129044dSC.J. Collier	depth = 2;
6815129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
6825129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6835129044dSC.J. Collier
6845129044dSC.J. Collier	depth = 3;
6855129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
6865129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
6875129044dSC.J. Collier
6885129044dSC.J. Collier	rte_lpm6_free(lpm);
6895129044dSC.J. Collier
6905129044dSC.J. Collier	return PASS;
6915129044dSC.J. Collier}
6925129044dSC.J. Collier
6935129044dSC.J. Collier/*
694809f0800SChristian Ehrhardt * Add 2^12 routes with different first 12 bits and depth 25.
6955129044dSC.J. Collier * Add one more route with the same depth and check that results in a failure.
6965129044dSC.J. Collier * After that delete the last rule and create the one that was attempted to be
6975129044dSC.J. Collier * created. This checks tbl8 exhaustion.
6985129044dSC.J. Collier */
6995129044dSC.J. Collierint32_t
7005129044dSC.J. Colliertest14(void)
7015129044dSC.J. Collier{
7025129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
7035129044dSC.J. Collier	struct rte_lpm6_config config;
7045129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
7055129044dSC.J. Collier	uint8_t depth = 25, next_hop_add = 100;
7065129044dSC.J. Collier	int32_t status = 0;
707809f0800SChristian Ehrhardt	int i;
7085129044dSC.J. Collier
7095129044dSC.J. Collier	config.max_rules = MAX_RULES;
710809f0800SChristian Ehrhardt	config.number_tbl8s = 256;
7115129044dSC.J. Collier	config.flags = 0;
7125129044dSC.J. Collier
7135129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
7145129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
7155129044dSC.J. Collier
7165129044dSC.J. Collier	for (i = 0; i < 256; i++) {
7175129044dSC.J. Collier		ip[0] = (uint8_t)i;
718809f0800SChristian Ehrhardt		status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
719809f0800SChristian Ehrhardt		TEST_LPM_ASSERT(status == 0);
7205129044dSC.J. Collier	}
7215129044dSC.J. Collier
7225129044dSC.J. Collier	ip[0] = 255;
723809f0800SChristian Ehrhardt	ip[1] = 1;
7245129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
7255129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOSPC);
7265129044dSC.J. Collier
7275129044dSC.J. Collier	ip[0] = 255;
728809f0800SChristian Ehrhardt	ip[1] = 0;
7295129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
7305129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
7315129044dSC.J. Collier
7325129044dSC.J. Collier	ip[0] = 255;
733809f0800SChristian Ehrhardt	ip[1] = 1;
7345129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
7355129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
7365129044dSC.J. Collier
7375129044dSC.J. Collier	rte_lpm6_free(lpm);
7385129044dSC.J. Collier
7395129044dSC.J. Collier	return PASS;
7405129044dSC.J. Collier}
7415129044dSC.J. Collier
7425129044dSC.J. Collier/*
7435129044dSC.J. Collier * Call add, lookup and delete for a single rule with depth = 24
7445129044dSC.J. Collier */
7455129044dSC.J. Collierint32_t
7465129044dSC.J. Colliertest15(void)
7475129044dSC.J. Collier{
7485129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
7495129044dSC.J. Collier	struct rte_lpm6_config config;
7505129044dSC.J. Collier	uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
7515129044dSC.J. Collier	uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0;
7525129044dSC.J. Collier	int32_t status = 0;
7535129044dSC.J. Collier
7545129044dSC.J. Collier	config.max_rules = MAX_RULES;
7555129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
7565129044dSC.J. Collier	config.flags = 0;
7575129044dSC.J. Collier
7585129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
7595129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
7605129044dSC.J. Collier
7615129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
7625129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
7635129044dSC.J. Collier
7645129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
7655129044dSC.J. Collier	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
7665129044dSC.J. Collier
7675129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
7685129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
7695129044dSC.J. Collier
7705129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
7715129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOENT);
7725129044dSC.J. Collier
7735129044dSC.J. Collier	rte_lpm6_free(lpm);
7745129044dSC.J. Collier
7755129044dSC.J. Collier	return PASS;
7765129044dSC.J. Collier}
7775129044dSC.J. Collier
7785129044dSC.J. Collier/*
7795129044dSC.J. Collier * Call add, lookup and delete for a single rule with depth > 24
7805129044dSC.J. Collier */
7815129044dSC.J. Collierint32_t
7825129044dSC.J. Colliertest16(void)
7835129044dSC.J. Collier{
7845129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
7855129044dSC.J. Collier	struct rte_lpm6_config config;
7865129044dSC.J. Collier	uint8_t ip[] = {12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0};
7875129044dSC.J. Collier	uint8_t depth = 128, next_hop_add = 100, next_hop_return = 0;
7885129044dSC.J. Collier	int32_t status = 0;
7895129044dSC.J. Collier
7905129044dSC.J. Collier	config.max_rules = MAX_RULES;
7915129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
7925129044dSC.J. Collier	config.flags = 0;
7935129044dSC.J. Collier
7945129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
7955129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
7965129044dSC.J. Collier
7975129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
7985129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
7995129044dSC.J. Collier
8005129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
8015129044dSC.J. Collier	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
8025129044dSC.J. Collier
8035129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
8045129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
8055129044dSC.J. Collier
8065129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
8075129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOENT);
8085129044dSC.J. Collier
8095129044dSC.J. Collier	rte_lpm6_free(lpm);
8105129044dSC.J. Collier
8115129044dSC.J. Collier	return PASS;
8125129044dSC.J. Collier}
8135129044dSC.J. Collier
8145129044dSC.J. Collier/*
8155129044dSC.J. Collier * Use rte_lpm6_add to add rules which effect only the second half of the lpm
8165129044dSC.J. Collier * table. Use all possible depths ranging from 1..32. Set the next hop = to the
8175129044dSC.J. Collier * depth. Check lookup hit for on every add and check for lookup miss on the
8185129044dSC.J. Collier * first half of the lpm table after each add. Finally delete all rules going
8195129044dSC.J. Collier * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each
8205129044dSC.J. Collier * delete. The lookup should return the next_hop_add value related to the
8215129044dSC.J. Collier * previous depth value (i.e. depth -1).
8225129044dSC.J. Collier */
8235129044dSC.J. Collierint32_t
8245129044dSC.J. Colliertest17(void)
8255129044dSC.J. Collier{
8265129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
8275129044dSC.J. Collier	struct rte_lpm6_config config;
8285129044dSC.J. Collier	uint8_t ip1[] = {127,255,255,255,255,255,255,255,255,
8295129044dSC.J. Collier			255,255,255,255,255,255,255};
8305129044dSC.J. Collier	uint8_t ip2[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
8315129044dSC.J. Collier	uint8_t depth, next_hop_add, next_hop_return;
8325129044dSC.J. Collier	int32_t status = 0;
8335129044dSC.J. Collier
8345129044dSC.J. Collier	config.max_rules = MAX_RULES;
8355129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
8365129044dSC.J. Collier	config.flags = 0;
8375129044dSC.J. Collier
8385129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
8395129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
8405129044dSC.J. Collier
8415129044dSC.J. Collier	/* Loop with rte_lpm6_add. */
842809f0800SChristian Ehrhardt	for (depth = 1; depth <= 16; depth++) {
8435129044dSC.J. Collier		/* Let the next_hop_add value = depth. Just for change. */
8445129044dSC.J. Collier		next_hop_add = depth;
8455129044dSC.J. Collier
8465129044dSC.J. Collier		status = rte_lpm6_add(lpm, ip2, depth, next_hop_add);
8475129044dSC.J. Collier		TEST_LPM_ASSERT(status == 0);
8485129044dSC.J. Collier
8495129044dSC.J. Collier		/* Check IP in first half of tbl24 which should be empty. */
8505129044dSC.J. Collier		status = rte_lpm6_lookup(lpm, ip1, &next_hop_return);
8515129044dSC.J. Collier		TEST_LPM_ASSERT(status == -ENOENT);
8525129044dSC.J. Collier
8535129044dSC.J. Collier		status = rte_lpm6_lookup(lpm, ip2, &next_hop_return);
8545129044dSC.J. Collier		TEST_LPM_ASSERT((status == 0) &&
8555129044dSC.J. Collier			(next_hop_return == next_hop_add));
8565129044dSC.J. Collier	}
8575129044dSC.J. Collier
8585129044dSC.J. Collier	/* Loop with rte_lpm6_delete. */
859809f0800SChristian Ehrhardt	for (depth = 16; depth >= 1; depth--) {
8605129044dSC.J. Collier		next_hop_add = (uint8_t) (depth - 1);
8615129044dSC.J. Collier
8625129044dSC.J. Collier		status = rte_lpm6_delete(lpm, ip2, depth);
8635129044dSC.J. Collier		TEST_LPM_ASSERT(status == 0);
8645129044dSC.J. Collier
8655129044dSC.J. Collier		status = rte_lpm6_lookup(lpm, ip2, &next_hop_return);
8665129044dSC.J. Collier
8675129044dSC.J. Collier		if (depth != 1) {
8685129044dSC.J. Collier			TEST_LPM_ASSERT((status == 0) &&
8695129044dSC.J. Collier				(next_hop_return == next_hop_add));
8705129044dSC.J. Collier		}
8715129044dSC.J. Collier		else {
8725129044dSC.J. Collier			TEST_LPM_ASSERT(status == -ENOENT);
8735129044dSC.J. Collier		}
8745129044dSC.J. Collier
8755129044dSC.J. Collier		status = rte_lpm6_lookup(lpm, ip1, &next_hop_return);
8765129044dSC.J. Collier		TEST_LPM_ASSERT(status == -ENOENT);
8775129044dSC.J. Collier	}
8785129044dSC.J. Collier
8795129044dSC.J. Collier	rte_lpm6_free(lpm);
8805129044dSC.J. Collier
8815129044dSC.J. Collier	return PASS;
8825129044dSC.J. Collier}
8835129044dSC.J. Collier
8845129044dSC.J. Collier/*
8855129044dSC.J. Collier * - Add & lookup to hit invalid TBL24 entry
8865129044dSC.J. Collier * - Add & lookup to hit valid TBL24 entry not extended
8875129044dSC.J. Collier * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry
8885129044dSC.J. Collier * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry
8895129044dSC.J. Collier */
8905129044dSC.J. Collierint32_t
8915129044dSC.J. Colliertest18(void)
8925129044dSC.J. Collier{
8935129044dSC.J. Collier	struct rte_lpm6 *lpm = NULL;
8945129044dSC.J. Collier	struct rte_lpm6_config config;
8955129044dSC.J. Collier	uint8_t ip[16], ip_1[16], ip_2[16];
8965129044dSC.J. Collier	uint8_t depth, depth_1, depth_2, next_hop_add, next_hop_add_1,
8975129044dSC.J. Collier		next_hop_add_2, next_hop_return;
8985129044dSC.J. Collier	int32_t status = 0;
8995129044dSC.J. Collier
9005129044dSC.J. Collier	config.max_rules = MAX_RULES;
9015129044dSC.J. Collier	config.number_tbl8s = NUMBER_TBL8S;
9025129044dSC.J. Collier	config.flags = 0;
9035129044dSC.J. Collier
9045129044dSC.J. Collier	/* Add & lookup to hit invalid TBL24 entry */
9055129044dSC.J. Collier	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
9065129044dSC.J. Collier	depth = 24;
9075129044dSC.J. Collier	next_hop_add = 100;
9085129044dSC.J. Collier
9095129044dSC.J. Collier	lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
9105129044dSC.J. Collier	TEST_LPM_ASSERT(lpm != NULL);
9115129044dSC.J. Collier
9125129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
9135129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
9145129044dSC.J. Collier
9155129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
9165129044dSC.J. Collier	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
9175129044dSC.J. Collier
9185129044dSC.J. Collier	status = rte_lpm6_delete(lpm, ip, depth);
9195129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
9205129044dSC.J. Collier
9215129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
9225129044dSC.J. Collier	TEST_LPM_ASSERT(status == -ENOENT);
9235129044dSC.J. Collier
9245129044dSC.J. Collier	rte_lpm6_delete_all(lpm);
9255129044dSC.J. Collier
9265129044dSC.J. Collier	/* Add & lookup to hit valid TBL24 entry not extended */
9275129044dSC.J. Collier	IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
9285129044dSC.J. Collier	depth = 23;
9295129044dSC.J. Collier	next_hop_add = 100;
9305129044dSC.J. Collier
9315129044dSC.J. Collier	status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
9325129044dSC.J. Collier	TEST_LPM_ASSERT(status == 0);
9335129044dSC.J. Collier
9345129044dSC.J. Collier	status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
9355129044dSC.J. Collier	TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
9365129044dSC.J. Collier
937