From patchwork Fri Jan 27 20:59:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravi Kerur X-Patchwork-Id: 20067 X-Patchwork-Delegate: thomas@monjalon.net 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 20EFA5598; Fri, 27 Jan 2017 22:00:44 +0100 (CET) Received: from mail-pg0-f65.google.com (mail-pg0-f65.google.com [74.125.83.65]) by dpdk.org (Postfix) with ESMTP id 1E7FE2B83 for ; Fri, 27 Jan 2017 22:00:02 +0100 (CET) Received: by mail-pg0-f65.google.com with SMTP id 204so25809243pge.2 for ; Fri, 27 Jan 2017 13:00:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kjAxpybfHU5f+n6hBnCvuLcw051PpYvhMnBG85TK3iE=; b=eXew06JPD8bFM0EoXlz7Mvqwf9KWVRyxt8inmcFGy7YSjxjgqBcTulE5+JRnRlG24E xOdJkhI+8h0pSapq7p5Af3zXhz4XdV2j1JI4/UoYRZDdCMJXGFlmwkXKihaMsEV77lTP VkieNNPQsJzJG0MWel53QLNH2qGtukDTrrAACJbtQFk1j2BIMXxHcEUxRJG5Ovb+ToJK 3CuOH8Ih8imcVQQNwu6xQTsnnz+Ms+7RfRud6KwfLTXxASQ5w0oEzezq7xe0/3JgJQzU zOkUHfweN0FuhsLyyGnsa8gWm16jhsfj7jZLRJj+eBWA9k5kWw1ZGwbLFkMxiDuO7lLg ka7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kjAxpybfHU5f+n6hBnCvuLcw051PpYvhMnBG85TK3iE=; b=aJAqD8IgZy3YSmwjPhT2YhCJb0+QbbFd/YXgjGrhTMhFqN+iGEbbx8jWxi4+WNGjCG Jdxm9pMpBmHucPsPXwCJIPvi5Rcsv7/FESWjEkvemV3/gfXrR6sSwMLquqAMhq0+K45T NWgfWSB7PPPeAdWrT0Q2qmFJ+4e+vJW/q+9d2FXSgnQ+kAa8FFAtfY7JwK8Ker4hCx7D L079Ptk+y3re9GG0tCE4uuApqYSYkZaskyLPqXFUiOp9dJEOxySWZFdgG9VBSgDVNsbJ UZQPNMAhvUvA97Ykiui3OAVLdlCq1hzakNvu4gaBcq3lYD3snVldFedawgdW/J9SCamC Woog== X-Gm-Message-State: AIkVDXJYgQ+IbNp6mN06KeKhyEyW9OV/Zr8ODY1qQpp5ZWNsw4VzdizhgWMrxssIFARvAQ== X-Received: by 10.99.133.65 with SMTP id u62mr11725632pgd.70.1485550800976; Fri, 27 Jan 2017 13:00:00 -0800 (PST) Received: from user-PC.hsd1.ca.comcast.net ([2601:646:8680:32d0:2583:a413:70b9:144f]) by smtp.gmail.com with ESMTPSA id r21sm13429712pfd.95.2017.01.27.12.59.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 27 Jan 2017 13:00:00 -0800 (PST) From: Ravi Kerur To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, bruce.richardson@intel.com, Ravi Kerur Date: Fri, 27 Jan 2017 12:59:54 -0800 Message-Id: <1485550795-10771-3-git-send-email-rkerur@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1485550795-10771-1-git-send-email-rkerur@gmail.com> References: <1485550795-10771-1-git-send-email-rkerur@gmail.com> Subject: [dpdk-dev] [RFC 17.05 v1 2/3] LPM config file read option X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" v1: > Remove static array configuration of Destination IP, MASK and IF_OUT for LPM and LPM6 config. > Add reading configuration from a file. > Format of configuration file is as follows #LPM route entries Dest-IP/Mask IF_OUT L1.1.1.0/24 0 L2.1.1.0/24 1 L3.1.1.0/24 2 ... #LPM6 route entries Dest-IP/Mask IF_OUT L1111:1111:1111:1111:0000:0000:0000:0000/48 0 L2111:1111:1111:1111:0000:0000:0000:0000/48 1 L3111:1111:1111:1111:0000:0000:0000:0000/48 2 ... Signed-off-by: Ravi Kerur --- examples/l3fwd/l3fwd.h | 43 +++++++ examples/l3fwd/l3fwd_acl.c | 39 +----- examples/l3fwd/l3fwd_acl.h | 29 ----- examples/l3fwd/l3fwd_lpm.c | 307 +++++++++++++++++++++++++++++++++++++-------- examples/l3fwd/main.c | 29 ++++- 5 files changed, 328 insertions(+), 119 deletions(-) diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h index 93e08f6..4b1cdc8 100644 --- a/examples/l3fwd/l3fwd.h +++ b/examples/l3fwd/l3fwd.h @@ -94,6 +94,47 @@ #define ACL_LEAD_CHAR ('@') #define ROUTE_LEAD_CHAR ('R') #define COMMENT_LEAD_CHAR ('#') +#define LPM_LEAD_CHAR ('L') +#define EM_LEAD_CHAR ('E') + +#define IPV6_ADDR_LEN 16 +#define IPV6_ADDR_U16 (IPV6_ADDR_LEN / sizeof(uint16_t)) +#define IPV6_ADDR_U32 (IPV6_ADDR_LEN / sizeof(uint32_t)) + +#define GET_CB_FIELD(in, fd, base, lim, dlm) do { \ + unsigned long val; \ + char *end; \ + errno = 0; \ + val = strtoul((in), &end, (base)); \ + if (errno != 0 || end[0] != (dlm) || val > (lim)) \ + return -EINVAL; \ + (fd) = (typeof(fd))val; \ + (in) = end + 1; \ +} while (0) + +/* Bypass comment and empty lines */ +static inline int +is_bypass_line(char *buff) +{ + int i = 0; + + /* comment line */ + if (buff[0] == COMMENT_LEAD_CHAR) + return 1; + /* empty line */ + while (buff[i] != '\0') { + if (!isspace(buff[i])) + return 0; + i++; + } + return 1; +} + +struct parm_cfg { + const char *rule_ipv4_name; + const char *rule_ipv6_name; + int scalar; +}; struct mbuf_table { uint16_t len; @@ -134,6 +175,8 @@ extern xmm_t val_eth[RTE_MAX_ETHPORTS]; extern struct lcore_conf lcore_conf[RTE_MAX_LCORE]; +extern struct parm_cfg parm_config; + extern int numa_on; /**< NUMA is enabled by default. */ /* Send burst of packets on an output interface */ diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c index 977ca05..d6b15d6 100644 --- a/examples/l3fwd/l3fwd_acl.c +++ b/examples/l3fwd/l3fwd_acl.c @@ -147,10 +147,6 @@ struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { }, }; -#define IPV6_ADDR_LEN 16 -#define IPV6_ADDR_U16 (IPV6_ADDR_LEN / sizeof(uint16_t)) -#define IPV6_ADDR_U32 (IPV6_ADDR_LEN / sizeof(uint32_t)) - enum { PROTO_FIELD_IPV6, SRC1_FIELD_IPV6, @@ -297,12 +293,6 @@ static struct { const char cb_port_delim[] = ":"; -static struct { - const char *rule_ipv4_name; - const char *rule_ipv6_name; - int scalar; -} parm_config; - /* * Print and dump ACL/Route rules functions are defined in * following header file. @@ -316,27 +306,6 @@ static struct { #include "l3fwd_acl_scalar.h" /* - * API's called during initialization to setup ACL rules. - */ -void -l3fwd_acl_set_rule_ipv4_name(const char *optarg) -{ - parm_config.rule_ipv4_name = optarg; -} - -void -l3fwd_acl_set_rule_ipv6_name(const char *optarg) -{ - parm_config.rule_ipv6_name = optarg; -} - -void -l3fwd_acl_set_scalar(void) -{ - parm_config.scalar = 1; -} - -/* * Parses IPV6 address, exepcts the following format: * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X - is a hexedecimal digit). */ @@ -566,7 +535,7 @@ parse_cb_ipv4vlan_rule(char *str, struct rte_acl_rule *v, int has_userdata) } static int -add_rules(const char *rule_path, +acl_add_rules(const char *rule_path, struct rte_acl_rule **proute_base, unsigned int *proute_num, struct rte_acl_rule **pacl_base, @@ -762,8 +731,8 @@ setup_acl(const int socket_id __attribute__((unused))) dump_acl_config(); - /* Load rules from the input file */ - if (add_rules(parm_config.rule_ipv4_name, &route_base_ipv4, + /* Load rules from the input file */ + if (acl_add_rules(parm_config.rule_ipv4_name, &route_base_ipv4, &route_num_ipv4, &acl_base_ipv4, &acl_num_ipv4, sizeof(struct acl4_rule), &parse_cb_ipv4vlan_rule) < 0) rte_exit(EXIT_FAILURE, "Failed to add rules\n"); @@ -774,7 +743,7 @@ setup_acl(const int socket_id __attribute__((unused))) acl_log("IPv4 ACL entries %u:\n", acl_num_ipv4); dump_ipv4_rules((struct acl4_rule *)acl_base_ipv4, acl_num_ipv4, 1); - if (add_rules(parm_config.rule_ipv6_name, &route_base_ipv6, + if (acl_add_rules(parm_config.rule_ipv6_name, &route_base_ipv6, &route_num_ipv6, &acl_base_ipv6, &acl_num_ipv6, sizeof(struct acl6_rule), &parse_cb_ipv6_rule) < 0) diff --git a/examples/l3fwd/l3fwd_acl.h b/examples/l3fwd/l3fwd_acl.h index fc5f66d..dca0f96 100644 --- a/examples/l3fwd/l3fwd_acl.h +++ b/examples/l3fwd/l3fwd_acl.h @@ -55,17 +55,6 @@ #define MBUF_IPV6_2PROTO(m) \ rte_pktmbuf_mtod_offset((m), uint8_t *, OFF_ETHHEAD + OFF_IPV62PROTO) -#define GET_CB_FIELD(in, fd, base, lim, dlm) do { \ - unsigned long val; \ - char *end; \ - errno = 0; \ - val = strtoul((in), &end, (base)); \ - if (errno != 0 || end[0] != (dlm) || val > (lim)) \ - return -EINVAL; \ - (fd) = (typeof(fd))val; \ - (in) = end + 1; \ -} while (0) - /* * ACL rules should have higher priorities than route ones to ensure ACL rule * always be found when input packets have multi-matches in the database. @@ -163,24 +152,6 @@ print_one_ipv6_rule(struct acl6_rule *rule, int extra) rule->data.userdata); } -/* Bypass comment and empty lines */ -static inline int -is_bypass_line(char *buff) -{ - int i = 0; - - /* comment line */ - if (buff[0] == COMMENT_LEAD_CHAR) - return 1; - /* empty line */ - while (buff[i] != '\0') { - if (!isspace(buff[i])) - return 0; - i++; - } - return 1; -} - #ifdef L3FWDACL_DEBUG static inline void dump_acl4_rule(struct rte_mbuf *m, uint32_t sig) diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c index ab31210..6630e91 100644 --- a/examples/l3fwd/l3fwd_lpm.c +++ b/examples/l3fwd/l3fwd_lpm.c @@ -57,45 +57,24 @@ #include "l3fwd.h" -struct ipv4_l3fwd_lpm_route { - uint32_t ip; - uint8_t depth; - uint8_t if_out; +enum { + CB_FLD_DST_ADDR, + CB_FLD_IF_OUT, + CB_FLD_MAX }; -struct ipv6_l3fwd_lpm_route { - uint8_t ip[16]; +struct lpm_rule { + union { + uint32_t ip; + union { + uint32_t ip_32[4]; + uint8_t ip_8[16]; + }; + }; uint8_t depth; uint8_t if_out; }; -static struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = { - {IPv4(1, 1, 1, 0), 24, 0}, - {IPv4(2, 1, 1, 0), 24, 1}, - {IPv4(3, 1, 1, 0), 24, 2}, - {IPv4(4, 1, 1, 0), 24, 3}, - {IPv4(5, 1, 1, 0), 24, 4}, - {IPv4(6, 1, 1, 0), 24, 5}, - {IPv4(7, 1, 1, 0), 24, 6}, - {IPv4(8, 1, 1, 0), 24, 7}, -}; - -static struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = { - {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 0}, - {{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 1}, - {{3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 2}, - {{4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 3}, - {{5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 4}, - {{6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 5}, - {{7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 6}, - {{8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 7}, -}; - -#define IPV4_L3FWD_LPM_NUM_ROUTES \ - (sizeof(ipv4_l3fwd_lpm_route_array) / sizeof(ipv4_l3fwd_lpm_route_array[0])) -#define IPV6_L3FWD_LPM_NUM_ROUTES \ - (sizeof(ipv6_l3fwd_lpm_route_array) / sizeof(ipv6_l3fwd_lpm_route_array[0])) - #define IPV4_L3FWD_LPM_MAX_RULES 1024 #define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8) #define IPV6_L3FWD_LPM_MAX_RULES 1024 @@ -110,6 +89,210 @@ struct rte_lpm6 *ipv6_l3fwd_lpm_lookup_struct[NB_SOCKETS]; #include "l3fwd_lpm.h" #endif +static int +lpm_parse_v6_addr(const char *in, const char **end, uint32_t v[IPV6_ADDR_U32], + char dlm) +{ + uint32_t addr[IPV6_ADDR_U16]; + + GET_CB_FIELD(in, addr[0], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[1], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[2], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[3], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[4], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[5], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[6], 16, UINT16_MAX, ':'); + GET_CB_FIELD(in, addr[7], 16, UINT16_MAX, dlm); + + *end = in; + + v[0] = (addr[0] << 16) + addr[1]; + v[1] = (addr[2] << 16) + addr[3]; + v[2] = (addr[4] << 16) + addr[5]; + v[3] = (addr[6] << 16) + addr[7]; + + return 0; +} + +static int +lpm_parse_v6_net(const char *in, uint32_t *v, uint8_t *mask_len) +{ + int32_t rc; + const char *mp; + uint8_t m; + uint32_t tmp[4]; + + /* get address. */ + rc = lpm_parse_v6_addr(in, &mp, v, '/'); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v6_addr failed %d\n", rc); + return rc; + } + + /* get mask. */ + GET_CB_FIELD(mp, m, 0, sizeof(tmp) * CHAR_BIT, 0); + *mask_len = m; + + return 0; +} + +static int +lpm_parse_v6_rule(char *str, struct lpm_rule *v) +{ + int i, rc; + char *s, *sp, *in[CB_FLD_MAX]; + static const char *dlm = " \t\n"; + int dim = CB_FLD_MAX; + s = str; + + for (i = 0; i != dim; i++, s = NULL) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) { + RTE_LOG(ERR, L3FWD, "\nparse_v6_rule strtok_r failed\n"); + return -EINVAL; + } + } + + rc = lpm_parse_v6_net(in[CB_FLD_DST_ADDR], v->ip_32, &v->depth); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v6_net failed\n"); + return rc; + } + + GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0); + + return 0; +} + +static int +lpm_parse_v4_net(const char *in, uint32_t *addr, uint8_t *mask_len) +{ + uint8_t a, b, c, d, m; + + GET_CB_FIELD(in, a, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, b, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, c, 0, UINT8_MAX, '.'); + GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); + GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); + + addr[0] = IPv4(a, b, c, d); + *mask_len = m; + + return 0; +} + +static int +lpm_parse_v4_rule(char *str, struct lpm_rule *v) +{ + int i, rc; + char *s, *sp, *in[CB_FLD_MAX]; + static const char *dlm = " \t\n"; + int dim = CB_FLD_MAX; + s = str; + + for (i = 0; i != dim; i++, s = NULL) { + in[i] = strtok_r(s, dlm, &sp); + if (in[i] == NULL) + return -EINVAL; + } + + rc = lpm_parse_v4_net(in[CB_FLD_DST_ADDR], &v->ip, &v->depth); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v4_net failed %d\n", rc); + return rc; + } + + GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0); + + return 0; +} + +static int +lpm_add_rules(const char *rule_path, + struct lpm_rule **proute_base, + unsigned int *proute_num, + int (*parser)(char *, struct lpm_rule *)) +{ + uint8_t *route_rules; + struct lpm_rule *next; + unsigned int route_num = 0; + unsigned int route_cnt = 0; + char buff[LINE_MAX]; + FILE *fh = fopen(rule_path, "rb"); + unsigned int i = 0, rule_size = sizeof(*next); + + if (fh == NULL) + rte_exit(EXIT_FAILURE, "%s: Open %s failed\n", __func__, + rule_path); + + while ((fgets(buff, LINE_MAX, fh) != NULL)) { + if (buff[0] == LPM_LEAD_CHAR) + route_num++; + } + + if (0 == route_num) + rte_exit(EXIT_FAILURE, "Not find any route entries in %s!\n", + rule_path); + + fseek(fh, 0, SEEK_SET); + + route_rules = calloc(route_num, rule_size); + + if (NULL == route_rules) + rte_exit(EXIT_FAILURE, "%s: failed to malloc memory\n", + __func__); + + i = 0; + while (fgets(buff, LINE_MAX, fh) != NULL) { + i++; + + if (is_bypass_line(buff)) + continue; + + char s = buff[0]; + + /* Route entry */ + if (s == LPM_LEAD_CHAR) + next = (struct lpm_rule *) + (route_rules + route_cnt * rule_size); + + /* Illegal line */ + else + rte_exit(EXIT_FAILURE, + "%s Line %u: should start with leading " + "char %c\n", + rule_path, i, LPM_LEAD_CHAR); + + if (parser(buff + 1, next) != 0) + rte_exit(EXIT_FAILURE, + "%s Line %u: parse rules error\n", + rule_path, i); + + route_cnt++; + } + + fclose(fh); + + *proute_base = (struct lpm_rule *)route_rules; + *proute_num = route_cnt; + + return 0; +} + +static int +check_lpm_config(void) +{ + if (parm_config.rule_ipv4_name == NULL) { + RTE_LOG(ERR, L3FWD, "LPM IPv4 rule file not specified\n"); + return -1; + } else if (parm_config.rule_ipv6_name == NULL) { + RTE_LOG(ERR, L3FWD, "LPM IPv6 rule file not specified\n"); + return -1; + } + + return 0; +} + /* main processing loop */ int lpm_main_loop(__attribute__((unused)) void *dummy) @@ -196,10 +379,16 @@ setup_lpm(const int socketid) { struct rte_lpm6_config config; struct rte_lpm_config config_ipv4; + struct lpm_rule *route_base_v4; + struct lpm_rule *route_base_v6; + unsigned int route_num_v4 = 0, route_num_v6 = 0; unsigned i; int ret; char s[64]; + if (check_lpm_config() != 0) + rte_exit(EXIT_FAILURE, "Failed to get valid LPM options\n"); + /* create the LPM table */ config_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES; config_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S; @@ -212,18 +401,25 @@ setup_lpm(const int socketid) "Unable to create v4 LPM table on socket %d\n", socketid); + /* Load rules from the input file */ + if (lpm_add_rules(parm_config.rule_ipv4_name, + &route_base_v4, &route_num_v4, + &lpm_parse_v4_rule) < 0) + rte_exit(EXIT_FAILURE, "Failed to add lpm v4 rules\n"); + /* populate the LPM table */ - for (i = 0; i < IPV4_L3FWD_LPM_NUM_ROUTES; i++) { + for (i = 0; i < route_num_v4; i++) { /* skip unused ports */ - if ((1 << ipv4_l3fwd_lpm_route_array[i].if_out & - enabled_port_mask) == 0) + if ((1 << route_base_v4[i].if_out & + enabled_port_mask) == 0) continue; - ret = rte_lpm_add(ipv4_l3fwd_lpm_lookup_struct[socketid], - ipv4_l3fwd_lpm_route_array[i].ip, - ipv4_l3fwd_lpm_route_array[i].depth, - ipv4_l3fwd_lpm_route_array[i].if_out); + ret = rte_lpm_add( + ipv4_l3fwd_lpm_lookup_struct[socketid], + route_base_v4[i].ip, + route_base_v4[i].depth, + route_base_v4[i].if_out); if (ret < 0) { rte_exit(EXIT_FAILURE, @@ -231,9 +427,9 @@ setup_lpm(const int socketid) } printf("LPM: Adding route 0x%08x / %d (%d)\n", - (unsigned)ipv4_l3fwd_lpm_route_array[i].ip, - ipv4_l3fwd_lpm_route_array[i].depth, - ipv4_l3fwd_lpm_route_array[i].if_out); + (unsigned)route_base_v4[i].ip, + route_base_v4[i].depth, + route_base_v4[i].if_out); } /* create the LPM6 table */ @@ -249,18 +445,25 @@ setup_lpm(const int socketid) "Unable to create v6 LPM table on socket %d\n", socketid); + /* Load rules from the input file */ + if (lpm_add_rules(parm_config.rule_ipv6_name, + &route_base_v6, &route_num_v6, + &lpm_parse_v6_rule) < 0) + rte_exit(EXIT_FAILURE, "Failed to add lpm v6 rules\n"); + /* populate the LPM table */ - for (i = 0; i < IPV6_L3FWD_LPM_NUM_ROUTES; i++) { + for (i = 0; i < route_num_v6; i++) { /* skip unused ports */ - if ((1 << ipv6_l3fwd_lpm_route_array[i].if_out & - enabled_port_mask) == 0) + if ((1 << route_base_v6[i].if_out & + enabled_port_mask) == 0) continue; - ret = rte_lpm6_add(ipv6_l3fwd_lpm_lookup_struct[socketid], - ipv6_l3fwd_lpm_route_array[i].ip, - ipv6_l3fwd_lpm_route_array[i].depth, - ipv6_l3fwd_lpm_route_array[i].if_out); + ret = rte_lpm6_add( + ipv6_l3fwd_lpm_lookup_struct[socketid], + route_base_v6[i].ip_8, + route_base_v6[i].depth, + route_base_v6[i].if_out); if (ret < 0) { rte_exit(EXIT_FAILURE, @@ -268,8 +471,8 @@ setup_lpm(const int socketid) } printf("LPM: Adding route %s / %d (%d)\n", - "IPV6", ipv6_l3fwd_lpm_route_array[i].depth, - ipv6_l3fwd_lpm_route_array[i].if_out); + "IPV6", route_base_v6[i].depth, + route_base_v6[i].if_out); } } diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c index d5a6704..062a523 100644 --- a/examples/l3fwd/main.c +++ b/examples/l3fwd/main.c @@ -126,6 +126,8 @@ uint32_t hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT; struct lcore_conf lcore_conf[RTE_MAX_LCORE]; +struct parm_cfg parm_config; + struct lcore_params { uint8_t port_id; uint8_t queue_id; @@ -214,6 +216,27 @@ static struct l3fwd_lkp_mode l3fwd_acl_lkp = { }; /* + * API's called during initialization to setup ACL/LPM/EM rules. + */ +static void +l3fwd_set_rule_ipv4_name(const char *optarg) +{ + parm_config.rule_ipv4_name = optarg; +} + +static void +l3fwd_set_rule_ipv6_name(const char *optarg) +{ + parm_config.rule_ipv6_name = optarg; +} + +static void +l3fwd_set_scalar(void) +{ + parm_config.scalar = 1; +} + +/* * Setup lookup methods for forwarding. * Currently exact-match and longest-prefix-match * are supported ones. @@ -691,15 +714,15 @@ parse_args(int argc, char **argv) break; case CMD_LINE_OPT_RULE_IPV4: - l3fwd_acl_set_rule_ipv4_name(optarg); + l3fwd_set_rule_ipv4_name(optarg); break; case CMD_LINE_OPT_RULE_IPV6: - l3fwd_acl_set_rule_ipv6_name(optarg); + l3fwd_set_rule_ipv6_name(optarg); break; case CMD_LINE_OPT_SCALAR: - l3fwd_acl_set_scalar(); + l3fwd_set_scalar(); break; default: