From patchwork Fri Mar 10 20:58:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravi Kerur X-Patchwork-Id: 21697 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 BA12BC254; Fri, 10 Mar 2017 21:59:11 +0100 (CET) Received: from mail-pg0-f68.google.com (mail-pg0-f68.google.com [74.125.83.68]) by dpdk.org (Postfix) with ESMTP id 1313C5A98 for ; Fri, 10 Mar 2017 21:58:23 +0100 (CET) Received: by mail-pg0-f68.google.com with SMTP id 25so11436319pgy.3 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=4vr1wjjPmUxsHtWIwEKZMxvfEW/4CAPTe+UFHyjhVX4=; b=jkfkcBjVOrqOHwVcNLg7YXDPC+EOiZDOb9cD7pGCbbWjz2up1L8LdXj0AXEG+HkG6u tMYYsEDrDLsnh3sDtT8eeW7vkrXhpnmiNoRh+TP5H8TCyGXSUYfg53F6OUZgaOova7T3 FomkYIxQ2vjV3MG6+cqxG2BYj4SLdzJPTtZ2Jc9kJAOMtTttxCorU4gIbz+mgdpbbp18 Ob3l45pZnr5yS/ibG7W/vs9A+CbuOYnaos221bIq3DQEZZbzy9uBgCLn0iaAR9rgTk/r 9J8l40/X/65E2e9pJ4EG+IQN+N6vY7cnD9yX6LlnLMhmYEslw2BVpedGto075VGc95rw LM/A== 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=4vr1wjjPmUxsHtWIwEKZMxvfEW/4CAPTe+UFHyjhVX4=; b=D1FNUbEHFQZh+Loha5wqDnj1rqxgbssHEN1qn22k9wP/xOZHsGyFlH35CVXjSgw85r 8bD6FEP4pqVno+GbxXR2SNiiAq7VCSX1fRJ4GXpd5y1BP4sDHgoiA0QGinprukLpe19b /psE8TZl+koeYha1/Zemw/ZNBOP76+rxDZrGwOoq6nqbCtRy3jEVgl9tQFcXUdUQdN7Z WD3r9YgopbRnGxGjjtM9EGMxKba0P+m1NJfsjM453HAPgJqgQs3eCHkGdOI2e+fZENx9 buoFPno5YpxdbJBiWjUH2IretgJ//pf6UWJHg2BYLpQCU/t47u7dnHpMLS2rnfekXqKa YDoA== X-Gm-Message-State: AMke39l8oyzX4YYkOE6k3JeKepzpwMANMBphq0RjW+v8TXqkKeijWG7kHogpVZ71FDfvOw== X-Received: by 10.99.36.7 with SMTP id k7mr22419210pgk.199.1489179502111; Fri, 10 Mar 2017 12:58:22 -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.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 10 Mar 2017 12:58:21 -0800 (PST) From: Ravi Kerur To: dev@dpdk.org Cc: john.mcnamara@intel.com, Ravi Kerur Date: Fri, 10 Mar 2017 12:58:11 -0800 Message-Id: <1489179491-9401-4-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 3/3] examples/l3fwd: add config file support for exact 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 exact match forwarding tables. --- v6: > Change commit message format v5: > No changes. v4: > No changes. v3: > Fix additional checkpatch coding style issues. v2: > Fix checkpatch warnings. v1: > Remove static array configuration of Dest IP,Src IP, Dest port, Src port, Proto and IF_OUT for EM and EM6 config. > Add reading configuration from a file. > Format of configuration file is as follows #EM route entries, #Dest-IP Src-IP Dest-port Src-port Proto IF_OUT E101.0.0.0 100.10.0.0 101 11 0x06 0 E201.0.0.0 200.20.0.0 102 12 0x06 1 E111.0.0.0 211.30.0.0 101 11 0x06 2 ... #EM6 route entries #Dest-IP Src-IP Dest-port Src-port Proto IF_OUT Efe80:0000:0000:0000:021e:67ff:fe00:0000 fe80:0000:0000:0000:021b:21ff:fe91:3805 101 11 0x06 0 Efe90:0000:0000:0000:021e:67ff:fe00:0000 fe90:0000:0000:0000:021b:21ff:fe91:3805 102 12 0x06 1 ... Signed-off-by: Ravi Kerur --- examples/l3fwd/l3fwd_em.c | 376 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 303 insertions(+), 73 deletions(-) diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c index 6fdabf7..cd6b443 100644 --- a/examples/l3fwd/l3fwd_em.c +++ b/examples/l3fwd/l3fwd_em.c @@ -95,8 +95,14 @@ union ipv4_5tuple_host { #define XMM_NUM_IN_IPV6_5TUPLE 3 struct ipv6_5tuple { - uint8_t ip_dst[IPV6_ADDR_LEN]; - uint8_t ip_src[IPV6_ADDR_LEN]; + union { + uint8_t ip_dst[IPV6_ADDR_LEN]; + uint32_t ip32_dst[4]; + }; + union { + uint8_t ip_src[IPV6_ADDR_LEN]; + uint32_t ip32_src[4]; + }; uint16_t port_dst; uint16_t port_src; uint8_t proto; @@ -116,47 +122,24 @@ union ipv6_5tuple_host { xmm_t xmm[XMM_NUM_IN_IPV6_5TUPLE]; }; - - -struct ipv4_l3fwd_em_route { - struct ipv4_5tuple key; - uint8_t if_out; +enum { + CB_FLD_DST_ADDR, + CB_FLD_SRC_ADDR, + CB_FLD_DST_PORT, + CB_FLD_SRC_PORT, + CB_FLD_PROTO, + CB_FLD_IF_OUT, + CB_FLD_MAX }; -struct ipv6_l3fwd_em_route { - struct ipv6_5tuple key; +struct em_rule { + union { + struct ipv4_5tuple v4_key; + struct ipv6_5tuple v6_key; + }; uint8_t if_out; }; -static struct ipv4_l3fwd_em_route ipv4_l3fwd_em_route_array[] = { - {{IPv4(101, 0, 0, 0), IPv4(100, 10, 0, 1), 101, 11, IPPROTO_TCP}, 0}, - {{IPv4(201, 0, 0, 0), IPv4(200, 20, 0, 1), 102, 12, IPPROTO_TCP}, 1}, - {{IPv4(111, 0, 0, 0), IPv4(100, 30, 0, 1), 101, 11, IPPROTO_TCP}, 2}, - {{IPv4(211, 0, 0, 0), IPv4(200, 40, 0, 1), 102, 12, IPPROTO_TCP}, 3}, -}; - -static struct ipv6_l3fwd_em_route ipv6_l3fwd_em_route_array[] = { - {{ - {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0}, - {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05}, - 101, 11, IPPROTO_TCP}, 0}, - - {{ - {0xfe, 0x90, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0}, - {0xfe, 0x90, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05}, - 102, 12, IPPROTO_TCP}, 1}, - - {{ - {0xfe, 0xa0, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0}, - {0xfe, 0xa0, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05}, - 101, 11, IPPROTO_TCP}, 2}, - - {{ - {0xfe, 0xb0, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0}, - {0xfe, 0xb0, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05}, - 102, 12, IPPROTO_TCP}, 3}, -}; - struct rte_hash *ipv4_l3fwd_em_lookup_struct[NB_SOCKETS]; struct rte_hash *ipv6_l3fwd_em_lookup_struct[NB_SOCKETS]; @@ -233,12 +216,6 @@ ipv6_hash_crc(const void *data, __rte_unused uint32_t data_len, return init_val; } -#define IPV4_L3FWD_EM_NUM_ROUTES \ - (sizeof(ipv4_l3fwd_em_route_array) / sizeof(ipv4_l3fwd_em_route_array[0])) - -#define IPV6_L3FWD_EM_NUM_ROUTES \ - (sizeof(ipv6_l3fwd_em_route_array) / sizeof(ipv6_l3fwd_em_route_array[0])) - static uint8_t ipv4_l3fwd_out_if[L3FWD_HASH_ENTRIES] __rte_cache_aligned; static uint8_t ipv6_l3fwd_out_if[L3FWD_HASH_ENTRIES] __rte_cache_aligned; @@ -338,6 +315,224 @@ em_get_ipv6_dst_port(void *ipv6_hdr, uint8_t portid, void *lookup_struct) #include "l3fwd_em.h" #endif +static int +em_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 +em_parse_v6_net(const char *in, uint32_t *v) +{ + int32_t rc; + const char *mp; + + /* get address. */ + rc = em_parse_v6_addr(in, &mp, v, 0); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v6_addr failed %d\n", rc); + return rc; + } + return 0; +} + +static int +em_parse_v6_rule(char *str, struct em_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, "strtok failed\n"); + return -EINVAL; + } + } + + rc = em_parse_v6_net(in[CB_FLD_DST_ADDR], v->v6_key.ip32_dst); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v6_net failed for dst %d\n", rc); + return rc; + } + rc = em_parse_v6_net(in[CB_FLD_SRC_ADDR], v->v6_key.ip32_src); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v6_net failed for src %d\n", rc); + return rc; + } + /* source port. */ + GET_CB_FIELD(in[CB_FLD_SRC_PORT], v->v6_key.port_src, 0, UINT16_MAX, 0); + /* destination port. */ + GET_CB_FIELD(in[CB_FLD_DST_PORT], v->v6_key.port_dst, 0, UINT16_MAX, 0); + /* protocol. */ + GET_CB_FIELD(in[CB_FLD_PROTO], v->v6_key.proto, 0, UINT8_MAX, 0); + /* out interface. */ + GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0); + + return 0; +} + +static int +em_parse_v4_net(const char *in, uint32_t *addr) +{ + uint8_t a, b, c, d; + + 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, 0); + + addr[0] = IPv4(a, b, c, d); + return 0; +} + +static int +em_parse_v4_rule(char *str, struct em_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, "parse_v4_rule strtok fail\n"); + return -EINVAL; + } + } + + rc = em_parse_v4_net(in[CB_FLD_DST_ADDR], &(v->v4_key.ip_dst)); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v4_net dst failed %d\n", rc); + return rc; + } + rc = em_parse_v4_net(in[CB_FLD_SRC_ADDR], &(v->v4_key.ip_src)); + if (rc != 0) { + RTE_LOG(ERR, L3FWD, "parse_v4_net src failed %d\n", rc); + return rc; + } + /* source port. */ + GET_CB_FIELD(in[CB_FLD_SRC_PORT], v->v4_key.port_src, 0, UINT16_MAX, 0); + /* destination port. */ + GET_CB_FIELD(in[CB_FLD_DST_PORT], v->v4_key.port_dst, 0, UINT16_MAX, 0); + /* protocol. */ + GET_CB_FIELD(in[CB_FLD_PROTO], v->v4_key.proto, 0, UINT8_MAX, 0); + /* out interface. */ + GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0); + + return 0; +} + +static int +em_add_rules(const char *rule_path, + struct em_rule **proute_base, + unsigned int *proute_num, + int (*parser)(char *, struct em_rule*)) +{ + uint8_t *route_rules; + struct em_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] == EM_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 == EM_LEAD_CHAR) + next = (struct em_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, EM_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 em_rule *)route_rules; + *proute_num = route_cnt; + + return 0; +} + +static int +check_em_config(void) +{ + if (parm_config.rule_ipv4_name == NULL) { + RTE_LOG(ERR, L3FWD, "EM IPv4 rule file not specified\n"); + return -1; + } else if (parm_config.rule_ipv6_name == NULL) { + RTE_LOG(ERR, L3FWD, "EM IPv6 rule file not specified\n"); + return -1; + } + + return 0; +} + static void convert_ipv4_5tuple(struct ipv4_5tuple *key1, union ipv4_5tuple_host *key2) @@ -378,16 +573,24 @@ populate_ipv4_few_flow_into_table(const struct rte_hash *h) { uint32_t i; int32_t ret; + struct em_rule *route_base_v4; + unsigned int route_num_v4 = 0; mask0 = (rte_xmm_t){.u32 = {BIT_8_TO_15, ALL_32_BITS, ALL_32_BITS, ALL_32_BITS} }; - for (i = 0; i < IPV4_L3FWD_EM_NUM_ROUTES; i++) { - struct ipv4_l3fwd_em_route entry; + /* Load rules from the input file */ + if (em_add_rules(parm_config.rule_ipv4_name, + &route_base_v4, &route_num_v4, + &em_parse_v4_rule) < 0) + rte_exit(EXIT_FAILURE, "Failed to add em v4 rules\n"); + + for (i = 0; i < route_num_v4; i++) { + struct em_rule entry; union ipv4_5tuple_host newkey; - entry = ipv4_l3fwd_em_route_array[i]; - convert_ipv4_5tuple(&entry.key, &newkey); + entry = route_base_v4[i]; + convert_ipv4_5tuple(&entry.v4_key, &newkey); ret = rte_hash_add_key(h, (void *) &newkey); if (ret < 0) { rte_exit(EXIT_FAILURE, "Unable to add entry %" PRIu32 @@ -396,7 +599,7 @@ populate_ipv4_few_flow_into_table(const struct rte_hash *h) ipv4_l3fwd_out_if[ret] = entry.if_out; } printf("Hash: Adding 0x%" PRIx64 " keys\n", - (uint64_t)IPV4_L3FWD_EM_NUM_ROUTES); + (uint64_t)route_num_v4); } #define BIT_16_TO_23 0x00ff0000 @@ -405,18 +608,26 @@ populate_ipv6_few_flow_into_table(const struct rte_hash *h) { uint32_t i; int32_t ret; + struct em_rule *route_base_v6; + unsigned int route_num_v6 = 0; mask1 = (rte_xmm_t){.u32 = {BIT_16_TO_23, ALL_32_BITS, ALL_32_BITS, ALL_32_BITS} }; mask2 = (rte_xmm_t){.u32 = {ALL_32_BITS, ALL_32_BITS, 0, 0} }; - for (i = 0; i < IPV6_L3FWD_EM_NUM_ROUTES; i++) { - struct ipv6_l3fwd_em_route entry; + /* Load rules from the input file */ + if (em_add_rules(parm_config.rule_ipv6_name, + &route_base_v6, &route_num_v6, + &em_parse_v6_rule) < 0) + rte_exit(EXIT_FAILURE, "Failed to add em v6 rules\n"); + + for (i = 0; i < route_num_v6; i++) { + struct em_rule entry; union ipv6_5tuple_host newkey; - entry = ipv6_l3fwd_em_route_array[i]; - convert_ipv6_5tuple(&entry.key, &newkey); + entry = route_base_v6[i]; + convert_ipv6_5tuple(&entry.v6_key, &newkey); ret = rte_hash_add_key(h, (void *) &newkey); if (ret < 0) { rte_exit(EXIT_FAILURE, "Unable to add entry %" PRIu32 @@ -425,7 +636,7 @@ populate_ipv6_few_flow_into_table(const struct rte_hash *h) ipv6_l3fwd_out_if[ret] = entry.if_out; } printf("Hash: Adding 0x%" PRIx64 "keys\n", - (uint64_t)IPV6_L3FWD_EM_NUM_ROUTES); + (uint64_t)route_num_v6); } #define NUMBER_PORT_USED 4 @@ -434,12 +645,20 @@ populate_ipv4_many_flow_into_table(const struct rte_hash *h, unsigned int nr_flow) { unsigned i; + struct em_rule *route_base_v4; + unsigned int route_num_v4 = 0; mask0 = (rte_xmm_t){.u32 = {BIT_8_TO_15, ALL_32_BITS, ALL_32_BITS, ALL_32_BITS} }; + /* Load rules from the input file */ + if (em_add_rules(parm_config.rule_ipv4_name, + &route_base_v4, &route_num_v4, + &em_parse_v4_rule) < 0) + rte_exit(EXIT_FAILURE, "Failed to add em v4 rules\n"); + for (i = 0; i < nr_flow; i++) { - struct ipv4_l3fwd_em_route entry; + struct em_rule entry; union ipv4_5tuple_host newkey; uint8_t a = (uint8_t) @@ -453,23 +672,23 @@ populate_ipv4_many_flow_into_table(const struct rte_hash *h, memset(&entry, 0, sizeof(entry)); switch (i & (NUMBER_PORT_USED - 1)) { case 0: - entry = ipv4_l3fwd_em_route_array[0]; - entry.key.ip_dst = IPv4(101, c, b, a); + entry = route_base_v4[0]; + entry.v4_key.ip_dst = IPv4(101, c, b, a); break; case 1: - entry = ipv4_l3fwd_em_route_array[1]; - entry.key.ip_dst = IPv4(201, c, b, a); + entry = route_base_v4[1]; + entry.v4_key.ip_dst = IPv4(201, c, b, a); break; case 2: - entry = ipv4_l3fwd_em_route_array[2]; - entry.key.ip_dst = IPv4(111, c, b, a); + entry = route_base_v4[2]; + entry.v4_key.ip_dst = IPv4(111, c, b, a); break; case 3: - entry = ipv4_l3fwd_em_route_array[3]; - entry.key.ip_dst = IPv4(211, c, b, a); + entry = route_base_v4[3]; + entry.v4_key.ip_dst = IPv4(211, c, b, a); break; }; - convert_ipv4_5tuple(&entry.key, &newkey); + convert_ipv4_5tuple(&entry.v4_key, &newkey); int32_t ret = rte_hash_add_key(h, (void *) &newkey); if (ret < 0) @@ -486,13 +705,21 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h, unsigned int nr_flow) { unsigned i; + struct em_rule *route_base_v6; + unsigned int route_num_v6 = 0; mask1 = (rte_xmm_t){.u32 = {BIT_16_TO_23, ALL_32_BITS, ALL_32_BITS, ALL_32_BITS} }; mask2 = (rte_xmm_t){.u32 = {ALL_32_BITS, ALL_32_BITS, 0, 0} }; + /* Load rules from the input file */ + if (em_add_rules(parm_config.rule_ipv6_name, + &route_base_v6, &route_num_v6, + &em_parse_v6_rule) < 0) + rte_exit(EXIT_FAILURE, "Failed to add em v6 rules\n"); + for (i = 0; i < nr_flow; i++) { - struct ipv6_l3fwd_em_route entry; + struct em_rule entry; union ipv6_5tuple_host newkey; uint8_t a = (uint8_t) @@ -506,22 +733,22 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h, memset(&entry, 0, sizeof(entry)); switch (i & (NUMBER_PORT_USED - 1)) { case 0: - entry = ipv6_l3fwd_em_route_array[0]; + entry = route_base_v6[0]; break; case 1: - entry = ipv6_l3fwd_em_route_array[1]; + entry = route_base_v6[1]; break; case 2: - entry = ipv6_l3fwd_em_route_array[2]; + entry = route_base_v6[2]; break; case 3: - entry = ipv6_l3fwd_em_route_array[3]; + entry = route_base_v6[3]; break; }; - entry.key.ip_dst[13] = c; - entry.key.ip_dst[14] = b; - entry.key.ip_dst[15] = a; - convert_ipv6_5tuple(&entry.key, &newkey); + entry.v6_key.ip_dst[13] = c; + entry.v6_key.ip_dst[14] = b; + entry.v6_key.ip_dst[15] = a; + convert_ipv6_5tuple(&entry.v6_key, &newkey); int32_t ret = rte_hash_add_key(h, (void *) &newkey); if (ret < 0) @@ -746,6 +973,9 @@ setup_hash(const int socketid) char s[64]; + if (check_em_config() != 0) + rte_exit(EXIT_FAILURE, "Failed to get valid EM options\n"); + /* create ipv4 hash */ snprintf(s, sizeof(s), "ipv4_l3fwd_hash_%d", socketid); ipv4_l3fwd_hash_params.name = s;