From patchwork Fri Oct 23 07:45:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mablexidana X-Patchwork-Id: 7934 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 8555DC46A; Fri, 23 Oct 2015 09:45:10 +0200 (CEST) Received: from m13-4.163.com (m13-4.163.com [220.181.13.4]) by dpdk.org (Postfix) with ESMTP id AAE87C456 for ; Fri, 23 Oct 2015 09:45:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=Date:From:Subject:MIME-Version:Message-ID; bh=eWiGS VP6oGH0rGYDoW5yinIE9SrvQS8mhVUfOQYWMLU=; b=H2E0NYcPNUi3DIqrGF1FE iWE8YJU9wk0CE0om2dIHzs/AzPq5R1HCbjsaJmpBG6sNIp5/bgzOAlgJ7Le+/4YJ tVIeOcVX1Z/M7aQWsz+0MuyZmTWnyCPpW03GYIB+r4l9T/4x9MuNiNTBy7nJUDZf r2K9O+910LOUSGd9TztpQg= Received: from mablexidana$163.com ( [182.92.253.20] ) by ajax-webmail-wmsvr4 (Coremail) ; Fri, 23 Oct 2015 15:45:04 +0800 (CST) X-Originating-IP: [182.92.253.20] Date: Fri, 23 Oct 2015 15:45:04 +0800 (CST) From: mablexidana To: dev@dpdk.org X-Priority: 3 X-Mailer: Coremail Webmail Server Version SP_ntes V3.5 build 20150911(74783.7961) Copyright (c) 2002-2015 www.mailtech.cn 163com In-Reply-To: <29f00a47.e2cb.15093a29920.Coremail.mablexidana@163.com> References: <29f00a47.e2cb.15093a29920.Coremail.mablexidana@163.com> X-CM-CTRLDATA: RTaiXmZvb3Rlcl9odG09Mjc1Mjc6NTY= MIME-Version: 1.0 Message-ID: <7b920919.e5aa.15093a87c7e.Coremail.mablexidana@163.com> X-CM-TRANSID: BMGowADX3gKA5SlWGXuPAA--.25820W X-CM-SenderInfo: xpdezvp0lgt0rd6rljoofrz/1tbiMRacsFUL3JsCOwACsp X-Coremail-Antispam: 1U5529EdanIXcx71UUUUU7vcSsGvfC2KfnxnUU== X-Content-Filtered-By: Mailman/MimeDel 2.1.15 Subject: Re: [dpdk-dev] [PATCH 2/2] add 3 lpm test cases X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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(-) #include @@ -47,6 +50,7 @@ #include #include #include +#include #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) 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 #include #include +#include +#include #include #include +#include #include #include