[dpdk-dev] [PATCH 2/2] add 3 lpm test cases

mablexidana mablexidana at 163.com
Fri Oct 23 09:45:04 CEST 2015


hi:


branch:1.2.3
Fixes: feab3e84432b ("add 3 lpm test cases")
test procedure:
 1),add->lookup
 2),add->delete->lookup
 3),add->delete->add->lookup


Regards


yuerxin


---
 app/test/test_lpm.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 455 insertions(+), 1 deletion(-)


diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index 5b8118a..97bbdf7 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -37,9 +37,12 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>
 #include <cmdline_parse.h>


+#include <rte_version.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
 #include <rte_memory.h>
@@ -47,6 +50,7 @@
 #include <rte_branch_prediction.h>
 #include <rte_ip.h>
 #include <time.h>
+#include <sys/time.h>


 #ifdef RTE_LIBRTE_LPM


@@ -88,6 +92,53 @@ static int32_t test15(void);
 static int32_t test16(void);
 static int32_t test17(void);
 static int32_t test18(void);
+static int32_t test_random(void);
+
+#define LPM_ADD_ROUTE_MAX       100
+#define LPM_TEST_LOOKUP_COUNT   5
+#define  ARG                    32
+
+#define RTE_LPM_V3_MAX_DEPTH    32
+#define RAND_SEED               1024
+
+
+#define PRINT_IP_FORMAT         "%u.%u.%u.%u"
+#define  PRINT_HIP(x)\
+        ((x >> 24) & 0xFF),\
+        ((x >> 16) & 0xFF),\
+        ((x >>  8) & 0xFF),\
+        ((x >>  0) & 0xFF)
+
+/*route struct node define*/
+struct route_node {
+    uint32_t dip;
+    uint32_t depth;
+    uint16_t next_hop;
+    uint16_t flags;
+};
+
+/*global varible define*/
+struct route_node route_table_arrary[LPM_ADD_ROUTE_MAX];
+
+
+/*for test_random route table test functions*/
+long getCurrentTime(void);
+int test_random_lpm_case_1(struct rte_lpm *lpm);
+int test_random_lpm_case_2(struct rte_lpm *lpm);
+int test_random_lpm_case_3(struct rte_lpm *lpm);
+int lpm_random_lookup(struct rte_lpm *lpm_tree, uint32_t dip_count);
+int lpm_random_add(struct rte_lpm *lpm_tree, int count);
+int lpm_random_delete(struct rte_lpm *lpm_tree, uint32_t index);
+int lpm_random_add_nexthop(struct rte_lpm *lpm_tree, int count, int next_hop);
+void lpm_route_show(struct rte_lpm *lpm);
+void lpm_route_show_v2(struct rte_lpm *lpm, uint32_t hop1, uint32_t hop2);
+int route_table_arrary_create(void);
+int route_table_arrary_add(uint32_t dip, uint8_t depth, uint32_t next_hop);
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+uint32_t depth_to_mask(uint8_t depth);
+#endif
+int route_table_lpm_lookup(struct rte_lpm *lpm_tree, uint32_t dip, uint8_t *next_hop);
+


 rte_lpm_test tests[] = {
 /* Test Cases */
@@ -109,7 +160,8 @@ rte_lpm_test tests[] = {
 test15,
 test16,
 test17,
-test18
+test18,
+test_random,
 };


 #define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
@@ -1196,6 +1248,408 @@ test15(void)






+long
+getCurrentTime(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv,NULL);
+    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+/*convertt the depth to net mask*/
+uint32_t depth_to_mask(uint8_t depth)
+{
+    return (int)0x80000000 >> (depth - 1);
+}
+#endif
+
+/*for route test table operate*/
+int
+route_table_arrary_create(void)
+{
+    memset(route_table_arrary, 0, sizeof(struct route_node) * LPM_ADD_ROUTE_MAX);
+    return 0;
+}
+
+/*add the route to the route test table*/
+int
+route_table_arrary_add(uint32_t dip, uint8_t depth, uint32_t next_hop)
+{
+    uint32_t i = 0;
+    uint32_t dip_masked = dip & depth_to_mask(depth);
+
+    for(i = 0; i < LPM_ADD_ROUTE_MAX; i++) {
+        if(route_table_arrary[i].flags == 1
+                && route_table_arrary[i].dip == dip
+                && route_table_arrary[i].depth == depth) {
+
+            route_table_arrary[i].dip = dip_masked;
+            route_table_arrary[i].depth = depth;
+            route_table_arrary[i].next_hop = next_hop;
+
+            return 0;   //exsit, update
+        }
+    }
+
+    for(i = 0; i < LPM_ADD_ROUTE_MAX; i++) {
+        if(route_table_arrary[i].flags == 0) {  //add the route
+            route_table_arrary[i].flags = 1;
+            route_table_arrary[i].dip = dip_masked;
+            route_table_arrary[i].depth = depth;
+            route_table_arrary[i].next_hop = next_hop;
+
+            return 0;   //add one by one, success
+        }
+    }
+
+    return -1;  //add failed
+}
+
+int route_table_lpm_lookup(struct rte_lpm *lpm, uint32_t dip, uint8_t *next_hop)
+{
+    int i, j;
+    int start, end;
+    uint32_t mask;
+
+    for(i = RTE_LPM_V3_MAX_DEPTH - 1; i >= 0 ; i--) {
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+        start = lpm->rule_info[i].first_rule;   //find from max depth rule
+        end = start + lpm->rule_info[i].used_rules;
+#else
+        start = i * lpm->max_rules_per_depth;
+        end = start + lpm->used_rules_at_depth[i];
+#endif
+        for(j = start; j < end; j++) {
+            mask = depth_to_mask(i + 1);
+
+            if((dip & mask) == lpm->rules_tbl[j].ip) {
+                *next_hop = lpm->rules_tbl[j].next_hop;
+                return 0;
+            }
+        }
+    }
+
+    return -1;
+}
+
+/*show lpm's route entries*/
+void lpm_route_show(struct rte_lpm *lpm)
+{
+    uint32_t i = 0, j = 0;
+    uint32_t start = 0, end = 0, count = 0;
+
+    printf("[%s:%d]show rule in lpm tree...\n",__func__,__LINE__);
+
+    for(i = 0; i < RTE_LPM_V3_MAX_DEPTH; i++){
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+        start = lpm->rule_info[i].first_rule;
+        end = start + lpm->rule_info[i].used_rules;
+#else
+        start = i * lpm->max_rules_per_depth;
+        end = start + lpm->used_rules_at_depth[i];
+#endif
+        for(j = start; j < end; j++) {
+            printf("\trule id : %u, ip : "PRINT_IP_FORMAT"/%u, next_hop : %u, \t\t lpm arrary(%u - %u - %u)\n",
+                        ++count, PRINT_HIP(lpm->rules_tbl[j].ip), i + 1, lpm->rules_tbl[j].next_hop, i, start, end);
+        }
+    }
+
+    return;
+}
+
+/*show lpm's route entries on hop1 and hop2*/
+void
+lpm_route_show_v2(struct rte_lpm *lpm, uint32_t hop1, uint32_t hop2)
+{
+    uint32_t i = 0, j = 0;
+    uint32_t start = 0, end = 0, count = 0;
+
+    printf("[%s:%d]show rule in lpm tree...\n",__func__,__LINE__);
+
+    for(i = 0; i < RTE_LPM_V3_MAX_DEPTH; i++){
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+        start = lpm->rule_info[i].first_rule;
+        end = start + lpm->rule_info[i].used_rules;
+#else
+        start = i * lpm->max_rules_per_depth;
+        end = start + lpm->used_rules_at_depth[i];
+#endif
+        for(j = start; j < end; j++) {
+            if(lpm->rules_tbl[j].next_hop == hop1 || lpm->rules_tbl[j].next_hop == hop2) {
+                printf("\trule id : %u, ip : "PRINT_IP_FORMAT"/%u, next_hop : %u, \t\t lpm arrary(%u - %u - %u)\n",
+                        ++count, PRINT_HIP(lpm->rules_tbl[j].ip), i + 1, lpm->rules_tbl[j].next_hop, i, start, end);
+            }
+        }
+    }
+
+    return;
+}
+
+int
+lpm_random_add_nexthop(struct rte_lpm *lpm_tree, int count, int next_hop)
+{
+    int32_t i;
+    int32_t status = 0;
+    uint32_t add_dip = 0;
+    uint8_t add_depth = 0;
+    uint8_t next_hop_add = 0;
+uint32_t dip_masked = 0;
+    uint64_t seed = 0;
+    int nh = next_hop-1;
+
+    seed = getCurrentTime();
+rte_srand(seed);
+
+for (i = 0; i < count; i++) {
+next_hop_add = nh++;
+
+add_dip = 0x10200000 + (rte_rand() >> 48);
+        add_depth = rte_rand() % 32 + 1;
+dip_masked = add_dip & depth_to_mask(add_depth);
+
+if(dip_masked == 0) {
+i--;
+continue;
+}
+
+        status = rte_lpm_add(lpm_tree, dip_masked, add_depth, next_hop_add);
+        if(status != 0) {
+            printf("lpm add routes failed, ret : %d...\n", status);
+            continue;
+}
+
+        route_table_arrary_add(dip_masked, add_depth, next_hop_add);
+    }
+
+    return 0;
+}
+
+/*for random route add, for route table & lpm struct*/
+int lpm_random_add(struct rte_lpm *lpm_tree, int count)
+{
+    int32_t i;
+    int32_t status = 0;
+    uint32_t add_dip = 0;
+    uint8_t add_depth = 0;
+    uint8_t next_hop_add = 0;
+uint32_t dip_masked = 0;
+    uint64_t seed = 0;
+
+    seed = getCurrentTime();
+rte_srand(seed);
+    printf("seed is %ld\n", seed);
+
+for (i = 0; i < count; i++) {
+next_hop_add = i % 256;
+
+add_dip = 0x10200000 + (rte_rand() >> 48);
+        add_depth = rte_rand() % 32 + 1;
+dip_masked = add_dip & depth_to_mask(add_depth);
+
+if(dip_masked == 0) {
+i--;
+continue;
+}
+
+        status = rte_lpm_add(lpm_tree, dip_masked, add_depth, next_hop_add);
+        if(status != 0) {
+            printf("lpm add routes failed, ret : %d...\n", status);
+            continue;
+}
+
+        route_table_arrary_add(dip_masked, add_depth, next_hop_add);
+    }
+
+    return 0;
+}
+
+/*for random lookup the route*/
+int lpm_random_lookup(struct rte_lpm *lpm_tree, uint32_t query_count)
+{
+    uint32_t i = 0;
+    uint8_t lookup_next_hop_0 = 0;
+    uint8_t lookup_next_hop_1 = 0;
+
+uint32_t dip;
+    int32_t status_0 = 0, status_1 = 0;
+
+rte_srand(getCurrentTime());
+
+for (i = 0; i < query_count; i++) {
+dip = 0x10200000 + (rte_rand() >> 48);
+
+lookup_next_hop_0 = 0xff;
+lookup_next_hop_1 = 0xff;
+
+status_0 = route_table_lpm_lookup(lpm_tree, dip, &lookup_next_hop_0);
+        status_1 = rte_lpm_lookup(lpm_tree, dip, &lookup_next_hop_1);
+
+        if(status_0 == 0 && status_1 == 0) {
+            if(lookup_next_hop_0 != lookup_next_hop_1) {
+                printf("lookup times : %u, failed, dip : "PRINT_IP_FORMAT", next_hop_0 : %u, next_hop_1 : %u\n",
+i, PRINT_HIP(dip), lookup_next_hop_0, lookup_next_hop_1);
+            status_1 = rte_lpm_lookup(lpm_tree, dip, &lookup_next_hop_1);
+printf("slit 1, for check a time, status_1 %d, next_hop : %u\n", status_1, lookup_next_hop_1);
+lpm_route_show_v2(lpm_tree, lookup_next_hop_0, lookup_next_hop_1);
+            return -1;
+        }
+        } else if(status_0 < 0 && status_1 < 0) {
+            //printf("i : %u, lpm lookup don't exsit, status_0 : %d, status_1 :%d\n", i, status_0, status_1);
+        continue;
+} else {
+            printf("lookup times : %u, failed,  dip : "PRINT_IP_FORMAT" , status_0 : %d, status_1 :%d, next_hop_0 : %u, next_hop_1 : %u\n",
+i, PRINT_HIP(dip), status_0, status_1, lookup_next_hop_0, lookup_next_hop_1);
+            status_1 = rte_lpm_lookup(lpm_tree, dip, &lookup_next_hop_1);
+printf("slit 2, for check a time, status_1 %d, next_hop : %u\n", status_1, lookup_next_hop_1);
+lpm_route_show_v2(lpm_tree, lookup_next_hop_0, lookup_next_hop_1);
+return -1;
+        }
+    }
+
+    return 0;
+}
+
+/*for delte the route by segment, from start to end*/
+int lpm_random_delete(struct rte_lpm *lpm_tree, uint32_t index)
+{
+    int ret = 0;
+    uint32_t dip = 0;
+    uint8_t  depth;
+    uint16_t next_hop;
+uint32_t dip_masked;
+
+if(route_table_arrary[index].flags == 1) {
+dip = route_table_arrary[index].dip;
+depth = route_table_arrary[index].depth;
+next_hop = route_table_arrary[index].next_hop;
+dip_masked = dip & depth_to_mask(depth);
+
+route_table_arrary[index].flags = 0;
+route_table_arrary[index].dip = 0;
+route_table_arrary[index].depth = 0;
+route_table_arrary[index].next_hop = 0;
+
+ret = rte_lpm_delete(lpm_tree, dip_masked, depth);
+if(ret < 0) {
+   printf("delete, failed, index : %u, dip : "PRINT_IP_FORMAT", depth : %u\n", index, PRINT_HIP(dip), depth);
+   return -1;
+}
+}
+
+    return 0;
+}
+
+
+/*add -> lookup*/
+int
+test_random_lpm_case_1(struct rte_lpm *lpm)
+{
+    int ret = 0;
+
+    ret = lpm_random_add(lpm, LPM_ADD_ROUTE_MAX);
+    if(ret < 0) {
+        return ret;
+    }
+
+    ret = lpm_random_lookup(lpm, LPM_TEST_LOOKUP_COUNT);
+    if(ret < 0) {
+        return ret;
+    }
+
+    return 0;
+}
+
+/*add -> del -> lookup*/
+int
+test_random_lpm_case_2(struct rte_lpm *lpm)
+{
+    int i = 0, ret = 0;
+
+    for(i = 0; i <  LPM_ADD_ROUTE_MAX; i++) {
+        lpm_random_delete(lpm, i);
+
+        ret = lpm_random_lookup(lpm, LPM_TEST_LOOKUP_COUNT);
+        if(ret < 0) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+/*for n times: del ->add -> lookup*/
+int
+test_random_lpm_case_3(struct rte_lpm *lpm)
+{
+    int ret = 0;
+    int i = 0;
+    int hops = 0;
+    int add = 1;
+    ret = lpm_random_add(lpm, LPM_ADD_ROUTE_MAX);
+    if(ret < 0) {
+        return ret;
+    }
+    hops = 200;
+    for(i = 0; i <  LPM_ADD_ROUTE_MAX; i++) {
+        usleep(1000);
+        lpm_random_delete(lpm, i);
+        lpm_random_add_nexthop(lpm,add,hops);
+        hops = hops + add;
+        ret = lpm_random_lookup(lpm, LPM_TEST_LOOKUP_COUNT);
+            if(ret < 0) {
+                return -1;
+            }
+    }
+
+    return 0;
+}
+
+/*
+ * Test for random routing add, del and lookup
+ */
+int32_t
+test_random(void) {
+    int ret = PASS;
+    struct rte_lpm *lpm = NULL;
+    lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, LPM_ADD_ROUTE_MAX  * ARG, RTE_LPM_MEMZONE);
+TEST_LPM_ASSERT(lpm != NULL);
+
+    route_table_arrary_create();
+
+    ret = test_random_lpm_case_1(lpm);
+    if(ret != 0) {
+        lpm_route_show(lpm);
+        printf("test_random_lpm_case_1, failed...\n");
+        ret = -1;
+        goto OUT;
+    }
+    printf("test_random_lpm_case_1, ok...\n");
+
+    ret = test_random_lpm_case_2(lpm);
+    if(ret != 0) {
+        lpm_route_show(lpm);
+        printf("test_random_lpm_case_2, failed...\n");
+        ret = -1;
+        goto OUT;
+    }
+    printf("test_random_lpm_case_2, ok...\n");
+
+    ret = test_random_lpm_case_3(lpm);
+    if(ret != 0) {
+        lpm_route_show(lpm);
+        printf("test_random_lpm_case_3, failed...\n");
+        ret = -1;
+        goto OUT;
+    }
+    printf("test_random_lpm_case_3, ok...\n");
+
+OUT:
+    rte_lpm_free(lpm) ;
+    return ret;
+}
+
+
 /*
  * Sequence of operations for find existing fbk hash table
  *
--
1.8.5.2 (Apple Git-48)


More information about the dev mailing list