14ccd4259SVladimir Medvedkin /* SPDX-License-Identifier: BSD-3-Clause 24ccd4259SVladimir Medvedkin * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com> 34ccd4259SVladimir Medvedkin * Copyright(c) 2019 Intel Corporation 44ccd4259SVladimir Medvedkin */ 54ccd4259SVladimir Medvedkin 64ccd4259SVladimir Medvedkin #include <stdio.h> 74ccd4259SVladimir Medvedkin #include <stdint.h> 84ccd4259SVladimir Medvedkin #include <stdlib.h> 94ccd4259SVladimir Medvedkin 104ccd4259SVladimir Medvedkin #include <rte_ip.h> 114ccd4259SVladimir Medvedkin #include <rte_log.h> 12233b41c2SStephen Hemminger #include <rte_fib.h> 1396c3d06aSVladimir Medvedkin #include <rte_malloc.h> 144ccd4259SVladimir Medvedkin 154ccd4259SVladimir Medvedkin #include "test.h" 164ccd4259SVladimir Medvedkin 174ccd4259SVladimir Medvedkin typedef int32_t (*rte_fib_test)(void); 184ccd4259SVladimir Medvedkin 194ccd4259SVladimir Medvedkin static int32_t test_create_invalid(void); 204ccd4259SVladimir Medvedkin static int32_t test_multiple_create(void); 214ccd4259SVladimir Medvedkin static int32_t test_free_null(void); 224ccd4259SVladimir Medvedkin static int32_t test_add_del_invalid(void); 234ccd4259SVladimir Medvedkin static int32_t test_get_invalid(void); 244ccd4259SVladimir Medvedkin static int32_t test_lookup(void); 2596c3d06aSVladimir Medvedkin static int32_t test_invalid_rcu(void); 2696c3d06aSVladimir Medvedkin static int32_t test_fib_rcu_sync_rw(void); 274ccd4259SVladimir Medvedkin 284ccd4259SVladimir Medvedkin #define MAX_ROUTES (1 << 16) 294ccd4259SVladimir Medvedkin #define MAX_TBL8 (1 << 15) 304ccd4259SVladimir Medvedkin 314ccd4259SVladimir Medvedkin /* 324ccd4259SVladimir Medvedkin * Check that rte_fib_create fails gracefully for incorrect user input 334ccd4259SVladimir Medvedkin * arguments 344ccd4259SVladimir Medvedkin */ 354ccd4259SVladimir Medvedkin int32_t 364ccd4259SVladimir Medvedkin test_create_invalid(void) 374ccd4259SVladimir Medvedkin { 384ccd4259SVladimir Medvedkin struct rte_fib *fib = NULL; 39e194f3cdSVladimir Medvedkin struct rte_fib_conf config = { 0 }; 404ccd4259SVladimir Medvedkin 414ccd4259SVladimir Medvedkin config.max_routes = MAX_ROUTES; 4211c5b9b5SVladimir Medvedkin config.rib_ext_sz = 0; 434ccd4259SVladimir Medvedkin config.default_nh = 0; 444ccd4259SVladimir Medvedkin config.type = RTE_FIB_DUMMY; 454ccd4259SVladimir Medvedkin 464ccd4259SVladimir Medvedkin /* rte_fib_create: fib name == NULL */ 474ccd4259SVladimir Medvedkin fib = rte_fib_create(NULL, SOCKET_ID_ANY, &config); 484ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 494ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 504ccd4259SVladimir Medvedkin 514ccd4259SVladimir Medvedkin /* rte_fib_create: config == NULL */ 524ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, NULL); 534ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 544ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 554ccd4259SVladimir Medvedkin 564ccd4259SVladimir Medvedkin /* socket_id < -1 is invalid */ 574ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, -2, &config); 584ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 594ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 604ccd4259SVladimir Medvedkin 614ccd4259SVladimir Medvedkin /* rte_fib_create: max_routes = 0 */ 624ccd4259SVladimir Medvedkin config.max_routes = 0; 634ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 644ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 654ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 664ccd4259SVladimir Medvedkin config.max_routes = MAX_ROUTES; 674ccd4259SVladimir Medvedkin 684f66d3beSVladimir Medvedkin config.type = RTE_FIB_DIR24_8 + 1; 694ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 704ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 714ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 724ccd4259SVladimir Medvedkin 734ccd4259SVladimir Medvedkin config.type = RTE_FIB_DIR24_8; 744ccd4259SVladimir Medvedkin config.dir24_8.num_tbl8 = MAX_TBL8; 754ccd4259SVladimir Medvedkin 764ccd4259SVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_8B + 1; 774ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 784ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 794ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 804ccd4259SVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_8B; 814ccd4259SVladimir Medvedkin 824ccd4259SVladimir Medvedkin config.dir24_8.num_tbl8 = 0; 834ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 844ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib == NULL, 854ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 864ccd4259SVladimir Medvedkin 874ccd4259SVladimir Medvedkin return TEST_SUCCESS; 884ccd4259SVladimir Medvedkin } 894ccd4259SVladimir Medvedkin 904ccd4259SVladimir Medvedkin /* 914ccd4259SVladimir Medvedkin * Create fib table then delete fib table 10 times 924ccd4259SVladimir Medvedkin * Use a slightly different rules size each time 934ccd4259SVladimir Medvedkin */ 944ccd4259SVladimir Medvedkin int32_t 954ccd4259SVladimir Medvedkin test_multiple_create(void) 964ccd4259SVladimir Medvedkin { 974ccd4259SVladimir Medvedkin struct rte_fib *fib = NULL; 98e194f3cdSVladimir Medvedkin struct rte_fib_conf config = { 0 }; 994ccd4259SVladimir Medvedkin int32_t i; 1004ccd4259SVladimir Medvedkin 10111c5b9b5SVladimir Medvedkin config.rib_ext_sz = 0; 1024ccd4259SVladimir Medvedkin config.default_nh = 0; 1034ccd4259SVladimir Medvedkin config.type = RTE_FIB_DUMMY; 1044ccd4259SVladimir Medvedkin 1054ccd4259SVladimir Medvedkin for (i = 0; i < 100; i++) { 1064ccd4259SVladimir Medvedkin config.max_routes = MAX_ROUTES - i; 1074ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 1084ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 1094ccd4259SVladimir Medvedkin rte_fib_free(fib); 1104ccd4259SVladimir Medvedkin } 1114ccd4259SVladimir Medvedkin /* Can not test free so return success */ 1124ccd4259SVladimir Medvedkin return TEST_SUCCESS; 1134ccd4259SVladimir Medvedkin } 1144ccd4259SVladimir Medvedkin 1154ccd4259SVladimir Medvedkin /* 1164ccd4259SVladimir Medvedkin * Call rte_fib_free for NULL pointer user input. Note: free has no return and 1174ccd4259SVladimir Medvedkin * therefore it is impossible to check for failure but this test is added to 1184ccd4259SVladimir Medvedkin * increase function coverage metrics and to validate that freeing null does 1194ccd4259SVladimir Medvedkin * not crash. 1204ccd4259SVladimir Medvedkin */ 1214ccd4259SVladimir Medvedkin int32_t 1224ccd4259SVladimir Medvedkin test_free_null(void) 1234ccd4259SVladimir Medvedkin { 1244ccd4259SVladimir Medvedkin struct rte_fib *fib = NULL; 125e194f3cdSVladimir Medvedkin struct rte_fib_conf config = { 0 }; 1264ccd4259SVladimir Medvedkin 1274ccd4259SVladimir Medvedkin config.max_routes = MAX_ROUTES; 12811c5b9b5SVladimir Medvedkin config.rib_ext_sz = 0; 1294ccd4259SVladimir Medvedkin config.default_nh = 0; 1304ccd4259SVladimir Medvedkin config.type = RTE_FIB_DUMMY; 1314ccd4259SVladimir Medvedkin 1324ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 1334ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 1344ccd4259SVladimir Medvedkin 1354ccd4259SVladimir Medvedkin rte_fib_free(fib); 1364ccd4259SVladimir Medvedkin rte_fib_free(NULL); 1374ccd4259SVladimir Medvedkin return TEST_SUCCESS; 1384ccd4259SVladimir Medvedkin } 1394ccd4259SVladimir Medvedkin 1404ccd4259SVladimir Medvedkin /* 1414ccd4259SVladimir Medvedkin * Check that rte_fib_add and rte_fib_delete fails gracefully 1424ccd4259SVladimir Medvedkin * for incorrect user input arguments 1434ccd4259SVladimir Medvedkin */ 1444ccd4259SVladimir Medvedkin int32_t 1454ccd4259SVladimir Medvedkin test_add_del_invalid(void) 1464ccd4259SVladimir Medvedkin { 1474ccd4259SVladimir Medvedkin struct rte_fib *fib = NULL; 148e194f3cdSVladimir Medvedkin struct rte_fib_conf config = { 0 }; 1494ccd4259SVladimir Medvedkin uint64_t nh = 100; 1504ccd4259SVladimir Medvedkin uint32_t ip = RTE_IPV4(0, 0, 0, 0); 1514ccd4259SVladimir Medvedkin int ret; 1524ccd4259SVladimir Medvedkin uint8_t depth = 24; 1534ccd4259SVladimir Medvedkin 1544ccd4259SVladimir Medvedkin config.max_routes = MAX_ROUTES; 15511c5b9b5SVladimir Medvedkin config.rib_ext_sz = 0; 1564ccd4259SVladimir Medvedkin config.default_nh = 0; 1574ccd4259SVladimir Medvedkin config.type = RTE_FIB_DUMMY; 1584ccd4259SVladimir Medvedkin 1594ccd4259SVladimir Medvedkin /* rte_fib_add: fib == NULL */ 1604ccd4259SVladimir Medvedkin ret = rte_fib_add(NULL, ip, depth, nh); 1614ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret < 0, 1624ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 1634ccd4259SVladimir Medvedkin 1644ccd4259SVladimir Medvedkin /* rte_fib_delete: fib == NULL */ 1654ccd4259SVladimir Medvedkin ret = rte_fib_delete(NULL, ip, depth); 1664ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret < 0, 1674ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 1684ccd4259SVladimir Medvedkin 1694ccd4259SVladimir Medvedkin /*Create valid fib to use in rest of test. */ 1704ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 1714ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 1724ccd4259SVladimir Medvedkin 1734ccd4259SVladimir Medvedkin /* rte_fib_add: depth > RTE_FIB_MAXDEPTH */ 1744ccd4259SVladimir Medvedkin ret = rte_fib_add(fib, ip, RTE_FIB_MAXDEPTH + 1, nh); 1754ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret < 0, 1764ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 1774ccd4259SVladimir Medvedkin 1784ccd4259SVladimir Medvedkin /* rte_fib_delete: depth > RTE_FIB_MAXDEPTH */ 1794ccd4259SVladimir Medvedkin ret = rte_fib_delete(fib, ip, RTE_FIB_MAXDEPTH + 1); 1804ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret < 0, 1814ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 1824ccd4259SVladimir Medvedkin 1834ccd4259SVladimir Medvedkin rte_fib_free(fib); 1844ccd4259SVladimir Medvedkin 1854ccd4259SVladimir Medvedkin return TEST_SUCCESS; 1864ccd4259SVladimir Medvedkin } 1874ccd4259SVladimir Medvedkin 1884ccd4259SVladimir Medvedkin /* 1894ccd4259SVladimir Medvedkin * Check that rte_fib_get_dp and rte_fib_get_rib fails gracefully 1904ccd4259SVladimir Medvedkin * for incorrect user input arguments 1914ccd4259SVladimir Medvedkin */ 1924ccd4259SVladimir Medvedkin int32_t 1934ccd4259SVladimir Medvedkin test_get_invalid(void) 1944ccd4259SVladimir Medvedkin { 1954ccd4259SVladimir Medvedkin void *p; 1964ccd4259SVladimir Medvedkin 1974ccd4259SVladimir Medvedkin p = rte_fib_get_dp(NULL); 1984ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(p == NULL, 1994ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 2004ccd4259SVladimir Medvedkin 2014ccd4259SVladimir Medvedkin p = rte_fib_get_rib(NULL); 2024ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(p == NULL, 2034ccd4259SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 2044ccd4259SVladimir Medvedkin 2054ccd4259SVladimir Medvedkin return TEST_SUCCESS; 2064ccd4259SVladimir Medvedkin } 2074ccd4259SVladimir Medvedkin 2084ccd4259SVladimir Medvedkin /* 2094ccd4259SVladimir Medvedkin * Add routes for one supernet with all possible depths and do lookup 2104ccd4259SVladimir Medvedkin * on each step 2114ccd4259SVladimir Medvedkin * After delete routes with doing lookup on each step 2124ccd4259SVladimir Medvedkin */ 2134ccd4259SVladimir Medvedkin static int 2144ccd4259SVladimir Medvedkin lookup_and_check_asc(struct rte_fib *fib, uint32_t ip_arr[RTE_FIB_MAXDEPTH], 2154ccd4259SVladimir Medvedkin uint32_t ip_missing, uint64_t def_nh, uint32_t n) 2164ccd4259SVladimir Medvedkin { 2174ccd4259SVladimir Medvedkin uint64_t nh_arr[RTE_FIB_MAXDEPTH]; 2184ccd4259SVladimir Medvedkin int ret; 2194ccd4259SVladimir Medvedkin uint32_t i = 0; 2204ccd4259SVladimir Medvedkin 2214ccd4259SVladimir Medvedkin ret = rte_fib_lookup_bulk(fib, ip_arr, nh_arr, RTE_FIB_MAXDEPTH); 2224ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n"); 2234ccd4259SVladimir Medvedkin 2244ccd4259SVladimir Medvedkin for (; i <= RTE_FIB_MAXDEPTH - n; i++) 2254ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(nh_arr[i] == n, 2264ccd4259SVladimir Medvedkin "Failed to get proper nexthop\n"); 2274ccd4259SVladimir Medvedkin 2284ccd4259SVladimir Medvedkin for (; i < RTE_FIB_MAXDEPTH; i++) 2294ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(nh_arr[i] == --n, 2304ccd4259SVladimir Medvedkin "Failed to get proper nexthop\n"); 2314ccd4259SVladimir Medvedkin 2324ccd4259SVladimir Medvedkin ret = rte_fib_lookup_bulk(fib, &ip_missing, nh_arr, 1); 2334ccd4259SVladimir Medvedkin RTE_TEST_ASSERT((ret == 0) && (nh_arr[0] == def_nh), 2344ccd4259SVladimir Medvedkin "Failed to get proper nexthop\n"); 2354ccd4259SVladimir Medvedkin 2364ccd4259SVladimir Medvedkin return TEST_SUCCESS; 2374ccd4259SVladimir Medvedkin } 2384ccd4259SVladimir Medvedkin 2394ccd4259SVladimir Medvedkin static int 2404ccd4259SVladimir Medvedkin lookup_and_check_desc(struct rte_fib *fib, uint32_t ip_arr[RTE_FIB_MAXDEPTH], 2414ccd4259SVladimir Medvedkin uint32_t ip_missing, uint64_t def_nh, uint32_t n) 2424ccd4259SVladimir Medvedkin { 2434ccd4259SVladimir Medvedkin uint64_t nh_arr[RTE_FIB_MAXDEPTH]; 2444ccd4259SVladimir Medvedkin int ret; 2454ccd4259SVladimir Medvedkin uint32_t i = 0; 2464ccd4259SVladimir Medvedkin 2474ccd4259SVladimir Medvedkin ret = rte_fib_lookup_bulk(fib, ip_arr, nh_arr, RTE_FIB_MAXDEPTH); 2484ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n"); 2494ccd4259SVladimir Medvedkin 2504ccd4259SVladimir Medvedkin for (; i < n; i++) 2514ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(nh_arr[i] == RTE_FIB_MAXDEPTH - i, 2524ccd4259SVladimir Medvedkin "Failed to get proper nexthop\n"); 2534ccd4259SVladimir Medvedkin 2544ccd4259SVladimir Medvedkin for (; i < RTE_FIB_MAXDEPTH; i++) 2554ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(nh_arr[i] == def_nh, 2564ccd4259SVladimir Medvedkin "Failed to get proper nexthop\n"); 2574ccd4259SVladimir Medvedkin 2584ccd4259SVladimir Medvedkin ret = rte_fib_lookup_bulk(fib, &ip_missing, nh_arr, 1); 2594ccd4259SVladimir Medvedkin RTE_TEST_ASSERT((ret == 0) && (nh_arr[0] == def_nh), 2604ccd4259SVladimir Medvedkin "Failed to get proper nexthop\n"); 2614ccd4259SVladimir Medvedkin 2624ccd4259SVladimir Medvedkin return TEST_SUCCESS; 2634ccd4259SVladimir Medvedkin } 2644ccd4259SVladimir Medvedkin 2654ccd4259SVladimir Medvedkin static int 2664ccd4259SVladimir Medvedkin check_fib(struct rte_fib *fib) 2674ccd4259SVladimir Medvedkin { 2684ccd4259SVladimir Medvedkin uint64_t def_nh = 100; 2694ccd4259SVladimir Medvedkin uint32_t ip_arr[RTE_FIB_MAXDEPTH]; 2704ccd4259SVladimir Medvedkin uint32_t ip_add = RTE_IPV4(128, 0, 0, 0); 2714ccd4259SVladimir Medvedkin uint32_t i, ip_missing = RTE_IPV4(127, 255, 255, 255); 2724ccd4259SVladimir Medvedkin int ret; 2734ccd4259SVladimir Medvedkin 2744ccd4259SVladimir Medvedkin for (i = 0; i < RTE_FIB_MAXDEPTH; i++) 2754ccd4259SVladimir Medvedkin ip_arr[i] = ip_add + (1ULL << i) - 1; 2764ccd4259SVladimir Medvedkin 2774ccd4259SVladimir Medvedkin ret = lookup_and_check_desc(fib, ip_arr, ip_missing, def_nh, 0); 2784ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n"); 2794ccd4259SVladimir Medvedkin 2804ccd4259SVladimir Medvedkin for (i = 1; i <= RTE_FIB_MAXDEPTH; i++) { 2814ccd4259SVladimir Medvedkin ret = rte_fib_add(fib, ip_add, i, i); 2824ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to add a route\n"); 2834ccd4259SVladimir Medvedkin ret = lookup_and_check_asc(fib, ip_arr, ip_missing, 2844ccd4259SVladimir Medvedkin def_nh, i); 2854ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n"); 2864ccd4259SVladimir Medvedkin } 2874ccd4259SVladimir Medvedkin 2884ccd4259SVladimir Medvedkin for (i = RTE_FIB_MAXDEPTH; i > 1; i--) { 2894ccd4259SVladimir Medvedkin ret = rte_fib_delete(fib, ip_add, i); 2904ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to delete a route\n"); 2914ccd4259SVladimir Medvedkin ret = lookup_and_check_asc(fib, ip_arr, ip_missing, 2924ccd4259SVladimir Medvedkin def_nh, i - 1); 2934ccd4259SVladimir Medvedkin 2944ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n"); 2954ccd4259SVladimir Medvedkin } 2964ccd4259SVladimir Medvedkin ret = rte_fib_delete(fib, ip_add, i); 2974ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to delete a route\n"); 2984ccd4259SVladimir Medvedkin ret = lookup_and_check_desc(fib, ip_arr, ip_missing, def_nh, 0); 2994ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n"); 3004ccd4259SVladimir Medvedkin 3014ccd4259SVladimir Medvedkin for (i = 0; i < RTE_FIB_MAXDEPTH; i++) { 3024ccd4259SVladimir Medvedkin ret = rte_fib_add(fib, ip_add, RTE_FIB_MAXDEPTH - i, 3034ccd4259SVladimir Medvedkin RTE_FIB_MAXDEPTH - i); 3044ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to add a route\n"); 3054ccd4259SVladimir Medvedkin ret = lookup_and_check_desc(fib, ip_arr, ip_missing, 3064ccd4259SVladimir Medvedkin def_nh, i + 1); 3074ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n"); 3084ccd4259SVladimir Medvedkin } 3094ccd4259SVladimir Medvedkin 3104ccd4259SVladimir Medvedkin for (i = 1; i <= RTE_FIB_MAXDEPTH; i++) { 3114ccd4259SVladimir Medvedkin ret = rte_fib_delete(fib, ip_add, i); 3124ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Failed to delete a route\n"); 3134ccd4259SVladimir Medvedkin ret = lookup_and_check_desc(fib, ip_arr, ip_missing, def_nh, 3144ccd4259SVladimir Medvedkin RTE_FIB_MAXDEPTH - i); 3154ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n"); 3164ccd4259SVladimir Medvedkin } 3174ccd4259SVladimir Medvedkin 3184ccd4259SVladimir Medvedkin return TEST_SUCCESS; 3194ccd4259SVladimir Medvedkin } 3204ccd4259SVladimir Medvedkin 3214ccd4259SVladimir Medvedkin int32_t 3224ccd4259SVladimir Medvedkin test_lookup(void) 3234ccd4259SVladimir Medvedkin { 3244ccd4259SVladimir Medvedkin struct rte_fib *fib = NULL; 325e194f3cdSVladimir Medvedkin struct rte_fib_conf config = { 0 }; 3264ccd4259SVladimir Medvedkin uint64_t def_nh = 100; 3274ccd4259SVladimir Medvedkin int ret; 3284ccd4259SVladimir Medvedkin 3294ccd4259SVladimir Medvedkin config.max_routes = MAX_ROUTES; 33011c5b9b5SVladimir Medvedkin config.rib_ext_sz = 0; 3314ccd4259SVladimir Medvedkin config.default_nh = def_nh; 3324ccd4259SVladimir Medvedkin config.type = RTE_FIB_DUMMY; 3334ccd4259SVladimir Medvedkin 3344ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 3354ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 3364ccd4259SVladimir Medvedkin ret = check_fib(fib); 3374ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, 3384ccd4259SVladimir Medvedkin "Check_fib fails for DUMMY type\n"); 3394ccd4259SVladimir Medvedkin rte_fib_free(fib); 3404ccd4259SVladimir Medvedkin 3414ccd4259SVladimir Medvedkin config.type = RTE_FIB_DIR24_8; 3424ccd4259SVladimir Medvedkin 3434ccd4259SVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_1B; 3444ccd4259SVladimir Medvedkin config.dir24_8.num_tbl8 = 127; 3454ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 3464ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 3474ccd4259SVladimir Medvedkin ret = check_fib(fib); 3484ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, 3494ccd4259SVladimir Medvedkin "Check_fib fails for DIR24_8_1B type\n"); 3504ccd4259SVladimir Medvedkin rte_fib_free(fib); 3514ccd4259SVladimir Medvedkin 3524ccd4259SVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_2B; 3534ccd4259SVladimir Medvedkin config.dir24_8.num_tbl8 = MAX_TBL8 - 1; 3544ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 3554ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 3564ccd4259SVladimir Medvedkin ret = check_fib(fib); 3574ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, 3584ccd4259SVladimir Medvedkin "Check_fib fails for DIR24_8_2B type\n"); 3594ccd4259SVladimir Medvedkin rte_fib_free(fib); 3604ccd4259SVladimir Medvedkin 3614ccd4259SVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; 3624ccd4259SVladimir Medvedkin config.dir24_8.num_tbl8 = MAX_TBL8; 3634ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 3644ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 3654ccd4259SVladimir Medvedkin ret = check_fib(fib); 3664ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, 3674ccd4259SVladimir Medvedkin "Check_fib fails for DIR24_8_4B type\n"); 3684ccd4259SVladimir Medvedkin rte_fib_free(fib); 3694ccd4259SVladimir Medvedkin 3704ccd4259SVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_8B; 3714ccd4259SVladimir Medvedkin config.dir24_8.num_tbl8 = MAX_TBL8; 3724ccd4259SVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 3734ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 3744ccd4259SVladimir Medvedkin ret = check_fib(fib); 3754ccd4259SVladimir Medvedkin RTE_TEST_ASSERT(ret == TEST_SUCCESS, 3764ccd4259SVladimir Medvedkin "Check_fib fails for DIR24_8_8B type\n"); 3774ccd4259SVladimir Medvedkin rte_fib_free(fib); 3784ccd4259SVladimir Medvedkin 3794ccd4259SVladimir Medvedkin return TEST_SUCCESS; 3804ccd4259SVladimir Medvedkin } 3814ccd4259SVladimir Medvedkin 38296c3d06aSVladimir Medvedkin /* 38396c3d06aSVladimir Medvedkin * rte_fib_rcu_qsbr_add positive and negative tests. 38496c3d06aSVladimir Medvedkin * - Add RCU QSBR variable to FIB 38596c3d06aSVladimir Medvedkin * - Add another RCU QSBR variable to FIB 38696c3d06aSVladimir Medvedkin * - Check returns 38796c3d06aSVladimir Medvedkin */ 38896c3d06aSVladimir Medvedkin int32_t 38996c3d06aSVladimir Medvedkin test_invalid_rcu(void) 39096c3d06aSVladimir Medvedkin { 39196c3d06aSVladimir Medvedkin struct rte_fib *fib = NULL; 39219d463aaSDavid Marchand struct rte_fib_conf config = { 0 }; 39396c3d06aSVladimir Medvedkin size_t sz; 39496c3d06aSVladimir Medvedkin struct rte_rcu_qsbr *qsv; 39596c3d06aSVladimir Medvedkin struct rte_rcu_qsbr *qsv2; 39696c3d06aSVladimir Medvedkin int32_t status; 39796c3d06aSVladimir Medvedkin struct rte_fib_rcu_config rcu_cfg = {0}; 39896c3d06aSVladimir Medvedkin uint64_t def_nh = 100; 39996c3d06aSVladimir Medvedkin 40096c3d06aSVladimir Medvedkin config.max_routes = MAX_ROUTES; 40196c3d06aSVladimir Medvedkin config.rib_ext_sz = 0; 40296c3d06aSVladimir Medvedkin config.default_nh = def_nh; 40396c3d06aSVladimir Medvedkin 40496c3d06aSVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 40596c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 40696c3d06aSVladimir Medvedkin 40796c3d06aSVladimir Medvedkin /* Create RCU QSBR variable */ 40896c3d06aSVladimir Medvedkin sz = rte_rcu_qsbr_get_memsize(RTE_MAX_LCORE); 40996c3d06aSVladimir Medvedkin qsv = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz, RTE_CACHE_LINE_SIZE, 41096c3d06aSVladimir Medvedkin SOCKET_ID_ANY); 41196c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(qsv != NULL, "Can not allocate memory for RCU\n"); 41296c3d06aSVladimir Medvedkin 41396c3d06aSVladimir Medvedkin status = rte_rcu_qsbr_init(qsv, RTE_MAX_LCORE); 41496c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(status == 0, "Can not initialize RCU\n"); 41596c3d06aSVladimir Medvedkin 41696c3d06aSVladimir Medvedkin rcu_cfg.v = qsv; 41796c3d06aSVladimir Medvedkin 41896c3d06aSVladimir Medvedkin /* adding rcu to RTE_FIB_DUMMY FIB type */ 419*259deb73SVladimir Medvedkin config.type = RTE_FIB_DUMMY; 42096c3d06aSVladimir Medvedkin rcu_cfg.mode = RTE_FIB_QSBR_MODE_SYNC; 42196c3d06aSVladimir Medvedkin status = rte_fib_rcu_qsbr_add(fib, &rcu_cfg); 422*259deb73SVladimir Medvedkin RTE_TEST_ASSERT(status == -ENOTSUP, 423*259deb73SVladimir Medvedkin "rte_fib_rcu_qsbr_add returned wrong error status when called with DUMMY type FIB\n"); 42496c3d06aSVladimir Medvedkin rte_fib_free(fib); 42596c3d06aSVladimir Medvedkin 42696c3d06aSVladimir Medvedkin config.type = RTE_FIB_DIR24_8; 42796c3d06aSVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; 42896c3d06aSVladimir Medvedkin config.dir24_8.num_tbl8 = MAX_TBL8; 42996c3d06aSVladimir Medvedkin fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 43096c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n"); 431*259deb73SVladimir Medvedkin 432*259deb73SVladimir Medvedkin /* Call rte_fib_rcu_qsbr_add without fib or config */ 433*259deb73SVladimir Medvedkin status = rte_fib_rcu_qsbr_add(NULL, &rcu_cfg); 434*259deb73SVladimir Medvedkin RTE_TEST_ASSERT(status == -EINVAL, "RCU added without fib\n"); 435*259deb73SVladimir Medvedkin status = rte_fib_rcu_qsbr_add(fib, NULL); 436*259deb73SVladimir Medvedkin RTE_TEST_ASSERT(status == -EINVAL, "RCU added without config\n"); 437*259deb73SVladimir Medvedkin 438*259deb73SVladimir Medvedkin /* Invalid QSBR mode */ 43996c3d06aSVladimir Medvedkin rcu_cfg.mode = 2; 44096c3d06aSVladimir Medvedkin status = rte_fib_rcu_qsbr_add(fib, &rcu_cfg); 441*259deb73SVladimir Medvedkin RTE_TEST_ASSERT(status == -EINVAL, "RCU added with incorrect mode\n"); 44296c3d06aSVladimir Medvedkin 44396c3d06aSVladimir Medvedkin rcu_cfg.mode = RTE_FIB_QSBR_MODE_DQ; 444*259deb73SVladimir Medvedkin 445*259deb73SVladimir Medvedkin /* Attach RCU QSBR to FIB to check for double attach */ 44696c3d06aSVladimir Medvedkin status = rte_fib_rcu_qsbr_add(fib, &rcu_cfg); 44796c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(status == 0, "Can not attach RCU to FIB\n"); 44896c3d06aSVladimir Medvedkin 44996c3d06aSVladimir Medvedkin /* Create and attach another RCU QSBR to FIB table */ 45096c3d06aSVladimir Medvedkin qsv2 = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz, RTE_CACHE_LINE_SIZE, 45196c3d06aSVladimir Medvedkin SOCKET_ID_ANY); 45296c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(qsv2 != NULL, "Can not allocate memory for RCU\n"); 45396c3d06aSVladimir Medvedkin 45496c3d06aSVladimir Medvedkin rcu_cfg.v = qsv2; 45596c3d06aSVladimir Medvedkin rcu_cfg.mode = RTE_FIB_QSBR_MODE_SYNC; 45696c3d06aSVladimir Medvedkin status = rte_fib_rcu_qsbr_add(fib, &rcu_cfg); 457*259deb73SVladimir Medvedkin RTE_TEST_ASSERT(status == -EEXIST, "Secondary RCU was mistakenly attached\n"); 45896c3d06aSVladimir Medvedkin 45996c3d06aSVladimir Medvedkin rte_fib_free(fib); 46096c3d06aSVladimir Medvedkin rte_free(qsv); 46196c3d06aSVladimir Medvedkin rte_free(qsv2); 46296c3d06aSVladimir Medvedkin 46396c3d06aSVladimir Medvedkin return TEST_SUCCESS; 46496c3d06aSVladimir Medvedkin } 46596c3d06aSVladimir Medvedkin 46696c3d06aSVladimir Medvedkin static struct rte_fib *g_fib; 46796c3d06aSVladimir Medvedkin static struct rte_rcu_qsbr *g_v; 46896c3d06aSVladimir Medvedkin static uint32_t g_ip = RTE_IPV4(192, 0, 2, 100); 46996c3d06aSVladimir Medvedkin static volatile uint8_t writer_done; 47096c3d06aSVladimir Medvedkin /* Report quiescent state interval every 1024 lookups. Larger critical 47196c3d06aSVladimir Medvedkin * sections in reader will result in writer polling multiple times. 47296c3d06aSVladimir Medvedkin */ 47396c3d06aSVladimir Medvedkin #define QSBR_REPORTING_INTERVAL 1024 47496c3d06aSVladimir Medvedkin #define WRITER_ITERATIONS 512 47596c3d06aSVladimir Medvedkin 47696c3d06aSVladimir Medvedkin /* 47796c3d06aSVladimir Medvedkin * Reader thread using rte_fib data structure with RCU. 47896c3d06aSVladimir Medvedkin */ 47996c3d06aSVladimir Medvedkin static int 48096c3d06aSVladimir Medvedkin test_fib_rcu_qsbr_reader(void *arg) 48196c3d06aSVladimir Medvedkin { 48296c3d06aSVladimir Medvedkin int i; 48396c3d06aSVladimir Medvedkin uint64_t next_hop_return = 0; 48496c3d06aSVladimir Medvedkin 48596c3d06aSVladimir Medvedkin RTE_SET_USED(arg); 48696c3d06aSVladimir Medvedkin /* Register this thread to report quiescent state */ 48796c3d06aSVladimir Medvedkin rte_rcu_qsbr_thread_register(g_v, 0); 48896c3d06aSVladimir Medvedkin rte_rcu_qsbr_thread_online(g_v, 0); 48996c3d06aSVladimir Medvedkin 49096c3d06aSVladimir Medvedkin do { 49196c3d06aSVladimir Medvedkin for (i = 0; i < QSBR_REPORTING_INTERVAL; i++) 49296c3d06aSVladimir Medvedkin rte_fib_lookup_bulk(g_fib, &g_ip, &next_hop_return, 1); 49396c3d06aSVladimir Medvedkin 49496c3d06aSVladimir Medvedkin /* Update quiescent state */ 49596c3d06aSVladimir Medvedkin rte_rcu_qsbr_quiescent(g_v, 0); 49696c3d06aSVladimir Medvedkin } while (!writer_done); 49796c3d06aSVladimir Medvedkin 49896c3d06aSVladimir Medvedkin rte_rcu_qsbr_thread_offline(g_v, 0); 49996c3d06aSVladimir Medvedkin rte_rcu_qsbr_thread_unregister(g_v, 0); 50096c3d06aSVladimir Medvedkin 50196c3d06aSVladimir Medvedkin return 0; 50296c3d06aSVladimir Medvedkin } 50396c3d06aSVladimir Medvedkin 50496c3d06aSVladimir Medvedkin /* 50596c3d06aSVladimir Medvedkin * rte_fib_rcu_qsbr_add sync mode functional test. 50696c3d06aSVladimir Medvedkin * 1 Reader and 1 writer. They cannot be in the same thread in this test. 50796c3d06aSVladimir Medvedkin * - Create FIB which supports 1 tbl8 group at max 50896c3d06aSVladimir Medvedkin * - Add RCU QSBR variable with sync mode to FIB 50996c3d06aSVladimir Medvedkin * - Register a reader thread. Reader keeps looking up a specific rule. 51096c3d06aSVladimir Medvedkin * - Writer keeps adding and deleting a specific rule with depth=28 (> 24) 51196c3d06aSVladimir Medvedkin */ 51296c3d06aSVladimir Medvedkin int32_t 51396c3d06aSVladimir Medvedkin test_fib_rcu_sync_rw(void) 51496c3d06aSVladimir Medvedkin { 51519d463aaSDavid Marchand struct rte_fib_conf config = { 0 }; 51696c3d06aSVladimir Medvedkin size_t sz; 51796c3d06aSVladimir Medvedkin int32_t status; 51896c3d06aSVladimir Medvedkin uint32_t i, next_hop; 51996c3d06aSVladimir Medvedkin uint8_t depth; 52096c3d06aSVladimir Medvedkin struct rte_fib_rcu_config rcu_cfg = {0}; 52196c3d06aSVladimir Medvedkin uint64_t def_nh = 100; 52296c3d06aSVladimir Medvedkin 52396c3d06aSVladimir Medvedkin if (rte_lcore_count() < 2) { 52496c3d06aSVladimir Medvedkin printf("Not enough cores for %s, expecting at least 2\n", __func__); 52596c3d06aSVladimir Medvedkin return TEST_SKIPPED; 52696c3d06aSVladimir Medvedkin } 52796c3d06aSVladimir Medvedkin 52896c3d06aSVladimir Medvedkin config.max_routes = MAX_ROUTES; 52996c3d06aSVladimir Medvedkin config.rib_ext_sz = 0; 53096c3d06aSVladimir Medvedkin config.default_nh = def_nh; 53196c3d06aSVladimir Medvedkin config.type = RTE_FIB_DIR24_8; 53296c3d06aSVladimir Medvedkin config.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; 53396c3d06aSVladimir Medvedkin config.dir24_8.num_tbl8 = 1; 53496c3d06aSVladimir Medvedkin 53596c3d06aSVladimir Medvedkin g_fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config); 53696c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(g_fib != NULL, "Failed to create FIB\n"); 53796c3d06aSVladimir Medvedkin 53896c3d06aSVladimir Medvedkin /* Create RCU QSBR variable */ 53996c3d06aSVladimir Medvedkin sz = rte_rcu_qsbr_get_memsize(1); 54096c3d06aSVladimir Medvedkin g_v = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz, RTE_CACHE_LINE_SIZE, 54196c3d06aSVladimir Medvedkin SOCKET_ID_ANY); 54296c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(g_v != NULL, "Can not allocate memory for RCU\n"); 54396c3d06aSVladimir Medvedkin 54496c3d06aSVladimir Medvedkin status = rte_rcu_qsbr_init(g_v, 1); 54596c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(status == 0, "Can not initialize RCU\n"); 54696c3d06aSVladimir Medvedkin 54796c3d06aSVladimir Medvedkin rcu_cfg.v = g_v; 54896c3d06aSVladimir Medvedkin rcu_cfg.mode = RTE_FIB_QSBR_MODE_SYNC; 54996c3d06aSVladimir Medvedkin /* Attach RCU QSBR to FIB table */ 55096c3d06aSVladimir Medvedkin status = rte_fib_rcu_qsbr_add(g_fib, &rcu_cfg); 55196c3d06aSVladimir Medvedkin RTE_TEST_ASSERT(status == 0, "Can not attach RCU to FIB\n"); 55296c3d06aSVladimir Medvedkin 55396c3d06aSVladimir Medvedkin writer_done = 0; 55496c3d06aSVladimir Medvedkin /* Launch reader thread */ 55596c3d06aSVladimir Medvedkin rte_eal_remote_launch(test_fib_rcu_qsbr_reader, NULL, rte_get_next_lcore(-1, 1, 0)); 55696c3d06aSVladimir Medvedkin 55796c3d06aSVladimir Medvedkin depth = 28; 55896c3d06aSVladimir Medvedkin next_hop = 1; 55996c3d06aSVladimir Medvedkin status = rte_fib_add(g_fib, g_ip, depth, next_hop); 56096c3d06aSVladimir Medvedkin if (status != 0) { 56196c3d06aSVladimir Medvedkin printf("%s: Failed to add rule\n", __func__); 56296c3d06aSVladimir Medvedkin goto error; 56396c3d06aSVladimir Medvedkin } 56496c3d06aSVladimir Medvedkin 56596c3d06aSVladimir Medvedkin /* Writer update */ 56696c3d06aSVladimir Medvedkin for (i = 0; i < WRITER_ITERATIONS; i++) { 56796c3d06aSVladimir Medvedkin status = rte_fib_delete(g_fib, g_ip, depth); 56896c3d06aSVladimir Medvedkin if (status != 0) { 56996c3d06aSVladimir Medvedkin printf("%s: Failed to delete rule at iteration %d\n", __func__, i); 57096c3d06aSVladimir Medvedkin goto error; 57196c3d06aSVladimir Medvedkin } 57296c3d06aSVladimir Medvedkin 57396c3d06aSVladimir Medvedkin status = rte_fib_add(g_fib, g_ip, depth, next_hop); 57496c3d06aSVladimir Medvedkin if (status != 0) { 57596c3d06aSVladimir Medvedkin printf("%s: Failed to add rule at iteration %d\n", __func__, i); 57696c3d06aSVladimir Medvedkin goto error; 57796c3d06aSVladimir Medvedkin } 57896c3d06aSVladimir Medvedkin } 57996c3d06aSVladimir Medvedkin 58096c3d06aSVladimir Medvedkin error: 58196c3d06aSVladimir Medvedkin writer_done = 1; 58296c3d06aSVladimir Medvedkin /* Wait until reader exited. */ 58396c3d06aSVladimir Medvedkin rte_eal_mp_wait_lcore(); 58496c3d06aSVladimir Medvedkin 58596c3d06aSVladimir Medvedkin rte_fib_free(g_fib); 58696c3d06aSVladimir Medvedkin rte_free(g_v); 58796c3d06aSVladimir Medvedkin 58896c3d06aSVladimir Medvedkin return status == 0 ? TEST_SUCCESS : TEST_FAILED; 58996c3d06aSVladimir Medvedkin } 59096c3d06aSVladimir Medvedkin 5914ccd4259SVladimir Medvedkin static struct unit_test_suite fib_fast_tests = { 5924ccd4259SVladimir Medvedkin .suite_name = "fib autotest", 5934ccd4259SVladimir Medvedkin .setup = NULL, 5944ccd4259SVladimir Medvedkin .teardown = NULL, 5954ccd4259SVladimir Medvedkin .unit_test_cases = { 5964ccd4259SVladimir Medvedkin TEST_CASE(test_create_invalid), 5974ccd4259SVladimir Medvedkin TEST_CASE(test_free_null), 5984ccd4259SVladimir Medvedkin TEST_CASE(test_add_del_invalid), 5994ccd4259SVladimir Medvedkin TEST_CASE(test_get_invalid), 6004ccd4259SVladimir Medvedkin TEST_CASE(test_lookup), 60196c3d06aSVladimir Medvedkin TEST_CASE(test_invalid_rcu), 60296c3d06aSVladimir Medvedkin TEST_CASE(test_fib_rcu_sync_rw), 6034ccd4259SVladimir Medvedkin TEST_CASES_END() 6044ccd4259SVladimir Medvedkin } 6054ccd4259SVladimir Medvedkin }; 6064ccd4259SVladimir Medvedkin 6074ccd4259SVladimir Medvedkin static struct unit_test_suite fib_slow_tests = { 6084ccd4259SVladimir Medvedkin .suite_name = "fib slow autotest", 6094ccd4259SVladimir Medvedkin .setup = NULL, 6104ccd4259SVladimir Medvedkin .teardown = NULL, 6114ccd4259SVladimir Medvedkin .unit_test_cases = { 6124ccd4259SVladimir Medvedkin TEST_CASE(test_multiple_create), 6134ccd4259SVladimir Medvedkin TEST_CASES_END() 6144ccd4259SVladimir Medvedkin } 6154ccd4259SVladimir Medvedkin }; 6164ccd4259SVladimir Medvedkin 6174ccd4259SVladimir Medvedkin /* 6184ccd4259SVladimir Medvedkin * Do all unit tests. 6194ccd4259SVladimir Medvedkin */ 6204ccd4259SVladimir Medvedkin static int 6214ccd4259SVladimir Medvedkin test_fib(void) 6224ccd4259SVladimir Medvedkin { 6234ccd4259SVladimir Medvedkin return unit_test_suite_runner(&fib_fast_tests); 6244ccd4259SVladimir Medvedkin } 6254ccd4259SVladimir Medvedkin 6264ccd4259SVladimir Medvedkin static int 6274ccd4259SVladimir Medvedkin test_slow_fib(void) 6284ccd4259SVladimir Medvedkin { 6294ccd4259SVladimir Medvedkin return unit_test_suite_runner(&fib_slow_tests); 6304ccd4259SVladimir Medvedkin } 6314ccd4259SVladimir Medvedkin 632e0a8442cSBruce Richardson REGISTER_FAST_TEST(fib_autotest, true, true, test_fib); 633e0a8442cSBruce Richardson REGISTER_PERF_TEST(fib_slow_autotest, test_slow_fib); 634