DPDK patches and discussions
 help / color / mirror / Atom feed
From: mablexidana  <mablexidana@163.com>
To: "Bruce Richardson" <bruce.richardson@intel.com>, dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH] fix lpm bugs
Date: Fri, 23 Oct 2015 12:40:07 +0800 (CST)	[thread overview]
Message-ID: <51540495.a2d9.15092ff2946.Coremail.mablexidana@163.com> (raw)
In-Reply-To: <313921ca.4b27.1508d543038.Coremail.mablexidana@163.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=GBK, Size: 14941 bytes --]

hi:
Fixes: 396284f345a1 ("add app/test/test_lpm.c test lpm, add 3 new cases 1),add->lookup 2),add->delete->lookup 3),add->delete->add->lookup")
[PATCH] add app/test/test_lpm.c test lpm, add 3 new cases


test procedure:
 1),add->lookup 
 2),add->delete->lookup 
 3),add->delete->add->lookup


This is the test program to test lpm bugs. 




Thanks


Regards


yuexin
---
 app/test/test_lpm.c | 480 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 480 insertions(+)


diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index 8b4ded9..d2f8a52 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -35,8 +35,11 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>


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


 #include "test.h"


@@ -77,8 +81,69 @@ static int32_t test14(void);
 static int32_t test15(void);
 static int32_t test16(void);
 static int32_t test17(void);
+static int32_t test_random(void);
 static int32_t perf_test(void);


+#ifndef RTE_VERSION_NUM
+#define RTE_VERSION_NUM(a,b,c,d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
+#endif
+
+#ifndef RTE_VERSION
+#define RTE_VERSION RTE_VERSION_NUM( \
+            RTE_VER_MAJOR, \
+            RTE_VER_MINOR, \
+            RTE_VER_PATCH_LEVEL,\
+            0)
+#endif
+
+
+#define LPM_ADD_ROUTE_MAX       100
+#define LPM_TEST_LOOKUP_COUNT   1
+#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);
+int route_table_lpm_lookup(struct rte_lpm *lpm_tree, uint32_t dip, uint8_t *next_hop);
+#else
+int route_table_lpm_lookup(struct rte_lpm *lpm_tree, uint32_t dip, uint16_t *next_hop);
+#endif
+
 rte_lpm_test tests[] = {
 /* Test Cases */
 test0,
@@ -99,6 +164,7 @@ rte_lpm_test tests[] = {
 test15,
 test16,
 test17,
+test_random,
 perf_test,
 };


@@ -1137,6 +1203,420 @@ test17(void)
 return PASS;
 }


+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
+}
+
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+int route_table_lpm_lookup(struct rte_lpm *lpm, uint32_t dip, uint8_t *next_hop)
+#else
+int route_table_lpm_lookup(struct rte_lpm *lpm, uint32_t dip, uint16_t *next_hop)
+#endif
+{
+    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 = %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;
+#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
+    uint8_t lookup_next_hop_0 = 0;
+    uint8_t lookup_next_hop_1 = 0;
+#else
+    uint16_t lookup_next_hop_0 = 0;
+    uint16_t lookup_next_hop_1 = 0;
+#endif
+
+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;
+//    int case_process,i;
+    struct rte_lpm *lpm = NULL;
+    lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, LPM_ADD_ROUTE_MAX  * ARG, 0);
+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;
+}
+
+
 /*
  * Lookup performance test
  */
--
1.8.5.2 (Apple Git-48)







\x16º&Áéó†ê%²\x17œ‚+ ÓN,†)ízW(˜Zâ9ËvßNôçvÓ^QzÛ«œö­‡\a§Î^[¨–È^r\b¬ƒM8²\x18§µé\¢d^qè¯y×ë¢i kM¢ž×¥r‰¦­6Š{^•Ê&×~5ߍwëm^[ÉÚ]’Šà>‹-~,pŠØDHÄωß5ì.‚߀Ÿ¢·^½Ú]’Šà\x16¸¶Üç-ÛMyÓ½9ã_´ÛM\x02\x11$ÑyÇ¢½ç_®‰ŸšÉ kM6~h§µé\¢mt۝öãn›ÊŠìš\x06µÓXߊ{^•Ê&Â+a\x11#\x13?mŽrݴם¶Óž4Ó½4\Lm.Š)×UÈ®‰Ï¢»@T

  reply	other threads:[~2015-10-23  4:40 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-21  9:54 mablexidana
2015-10-21 11:07 ` Bruce Richardson
2015-10-22  2:15   ` mablexidana
2015-10-23  4:40     ` mablexidana [this message]
     [not found]     ` <29ae0ca8.e6db.15093aafa12.Coremail.mablexidana@163.com>
2015-10-23  9:08       ` Mcnamara, John

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51540495.a2d9.15092ff2946.Coremail.mablexidana@163.com \
    --to=mablexidana@163.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).