From patchwork Fri Mar 10 20:58:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravi Kerur X-Patchwork-Id: 21695 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 0BAE868C5; Fri, 10 Mar 2017 21:58:58 +0100 (CET) Received: from mail-pf0-f195.google.com (mail-pf0-f195.google.com [209.85.192.195]) by dpdk.org (Postfix) with ESMTP id 3C18558FA for ; Fri, 10 Mar 2017 21:58:22 +0100 (CET) Received: by mail-pf0-f195.google.com with SMTP id v190so11965922pfb.0 for ; Fri, 10 Mar 2017 12:58:22 -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=xo4UNLVYgiMVni2+nlaIR6TN08VjaJdlnepmOTYCXf8=; b=TmaAoeO+fPjolVLBqltK+PtBSPPozLm9LIVlXL5nD1UG5nXtww16/yL8tgAu8UBsb9 AW4TFLwxO4c3R32ZQ6hr0Lax/fZemIxfF9uVtFumNsNRiObwclce8ZcgPSNnQH5vmJ08 nOiju9oKYhOy6BQ/rVhU40DQuYQwgBzBDlwDU/nK0D758vYMgQUJB7KSb9qGiCgUfdAr I888KCdPWHUz417ugPHeryeEXNWQhCrXDdJQcK0te/QBxvzm5gceGbo6wFtWFO91Fk8o /B4kgSWW88ZCdtiSJ3iECnwWjxFhsWDeUdjt/NY1ot7zxfpHl2U4C8jMZE+L5CI6tGh2 FHdw== 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=xo4UNLVYgiMVni2+nlaIR6TN08VjaJdlnepmOTYCXf8=; b=oDbZpvLaxVLD0+tIHIEcjVX/m+MCnZfb0564bDersZsdr1cx6fZZzlHvM0X4flMJPY ZDnif+CUj7mKuaNdnHfTaB6y1XhkAD9X9N8gAokxQo0ojVwp5zq0GfP9butO61R7BE53 SakL/HXEZJbrEHB4TohltVG5oxkpK6I+BEPfdLeSlO1Yv5tU3nhvkUDwSlku4fuDdA+J nxcMti7K5yZSDee/iFOVx5UQmCiacyuP22ZIdpOeiH61vxa3NYitoaByHwgH0ywaX8A9 N2oVwQc8r4MzhhFrjXKD0GPhFvyhpSGMqdbQI88onLz+r/JD0l5/+TvPkA6I7cLS4I6S KJjQ== X-Gm-Message-State: AMke39mW8qGROxdfHWrvLCzApz5VL5c0/LnY8xiEuvVzVxpkWmkrm9p1yqPqcRitPH8npQ== X-Received: by 10.84.172.193 with SMTP id n59mr27927977plb.63.1489179501278; Fri, 10 Mar 2017 12:58:21 -0800 (PST) Received: from user-PC.hsd1.ca.comcast.net ([2601:646:8680:32d0:c56b:171f:de7f:f14]) by smtp.gmail.com with ESMTPSA id t6sm20461260pgo.42.2017.03.10.12.58.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 10 Mar 2017 12:58:20 -0800 (PST) From: Ravi Kerur To: dev@dpdk.org Cc: john.mcnamara@intel.com, Ravi Kerur Date: Fri, 10 Mar 2017 12:58:10 -0800 Message-Id: <1489179491-9401-3-git-send-email-rkerur@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1489179491-9401-1-git-send-email-rkerur@gmail.com> References: <1489008729-28784-2-git-send-email-rkerur@gmail.com> <1489179491-9401-1-git-send-email-rkerur@gmail.com> Subject: [dpdk-dev] [PATCH v6 2/3] examples/l3fwd: add config file support for lpm 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" Add support to read from config file to build ipv4 and ipv6 longest prefix match forwarding tables. --- v6: > Change commit message format. v5: > Change is_bypass_line from inline to non-line. v4: > No changes. v3: > Fix additional checkpatch coding style issues. v2: > Fix checkpatch warnings related to code > MACRO GET_CB_FIELD checkpatch warning not fixed 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 | 28 +++++ examples/l3fwd/l3fwd_acl.c | 39 +----- examples/l3fwd/l3fwd_acl.h | 29 ----- examples/l3fwd/l3fwd_lpm.c | 308 +++++++++++++++++++++++++++++++++++++-------- examples/l3fwd/main.c | 47 ++++++- 5 files changed, 332 insertions(+), 119 deletions(-) diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h index 93e08f6..aa4bd25 100644 --- a/examples/l3fwd/l3fwd.h +++ b/examples/l3fwd/l3fwd.h @@ -94,6 +94,29 @@ #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) + +struct parm_cfg { + const char *rule_ipv4_name; + const char *rule_ipv6_name; + int scalar; +}; struct mbuf_table { uint16_t len; @@ -134,6 +157,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 */ @@ -287,4 +312,7 @@ l3fwd_acl_set_rule_ipv6_name(const char *optarg); void l3fwd_acl_set_rule_ipv4_name(const char *optarg); +int +is_bypass_line(const char *buff); + #endif /* __L3_FWD_H__ */ diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c index 388b978..66ed23d 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, @@ -764,8 +733,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"); @@ -776,7 +745,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 b79784b..da0b5a8 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..97f99cf 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,211 @@ 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 (route_num == 0) + 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 (route_rules == NULL) + 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 +380,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 +402,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 +428,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 int)route_base_v4[i].ip, + route_base_v4[i].depth, + route_base_v4[i].if_out); } /* create the LPM6 table */ @@ -249,18 +446,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 +472,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 65d792b..1098f78 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; @@ -212,6 +214,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. @@ -689,15 +712,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: @@ -895,6 +918,24 @@ prepare_ptype_parser(uint8_t portid, uint16_t queueid) return 0; } +/* Bypass comment and empty lines */ +int +is_bypass_line(const 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; +} + int main(int argc, char **argv) {