get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/21418/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 21418,
    "url": "https://patches.dpdk.org/api/patches/21418/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1488743225-25750-4-git-send-email-rkerur@gmail.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1488743225-25750-4-git-send-email-rkerur@gmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1488743225-25750-4-git-send-email-rkerur@gmail.com",
    "date": "2017-03-05T19:47:05",
    "name": "[dpdk-dev,v4,3/3] EM config file read option.",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "77423b96cffeaf86da9620dc06b74bcf50520725",
    "submitter": {
        "id": 134,
        "url": "https://patches.dpdk.org/api/people/134/?format=api",
        "name": "Ravi Kerur",
        "email": "rkerur@gmail.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1488743225-25750-4-git-send-email-rkerur@gmail.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/21418/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/21418/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 88D916CB4;\n\tSun,  5 Mar 2017 20:47:59 +0100 (CET)",
            "from mail-pf0-f193.google.com (mail-pf0-f193.google.com\n\t[209.85.192.193]) by dpdk.org (Postfix) with ESMTP id 6D4EA377E\n\tfor <dev@dpdk.org>; Sun,  5 Mar 2017 20:47:14 +0100 (CET)",
            "by mail-pf0-f193.google.com with SMTP id v190so4442400pfb.0\n\tfor <dev@dpdk.org>; Sun, 05 Mar 2017 11:47:14 -0800 (PST)",
            "from user-PC.hsd1.ca.comcast.net\n\t([2601:646:8680:32d0:9880:23bb:f0e5:b2da])\n\tby smtp.gmail.com with ESMTPSA id\n\tm6sm34876138pfg.126.2017.03.05.11.47.12\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tSun, 05 Mar 2017 11:47:12 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=XbSnacrX0kwSr4x8vrWTpWnmw4JTw9zLfH2B3DOPdE0=;\n\tb=qtMRRFu3sol+TgxTY6MZNphUdmEpqVfQ108HjsvAMOnpXFbi4ZBXGqSKwlyVXP3D3z\n\tx5QuCxlKUp785Cw9mXYuVkFjH5lILzgg1rCtG0vJMH54+n4NJg+dEeGCIt3CtGllLyDO\n\tGSzUtI8VYQMtV21leN7mrMw050l9oSAr1i4q/7XgXP17S/hw5grLqKD9fLVuxdcLzdEX\n\tQlz3On5olaN5cxrdrqSdsTg2b/SEXxVsxUlC7OdyMQ5rqvPo/pCtVqnlHN6twJ/xJ8L0\n\tXQ9swx271fm/5ajSDYsHRNTcgqrgRutNWfd2Wm+IM7jOc8JwLz1d7RFYbTYWoFHjvIzQ\n\twZIg==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=XbSnacrX0kwSr4x8vrWTpWnmw4JTw9zLfH2B3DOPdE0=;\n\tb=flwLVaYiqDjGPCZYIubnHY7O3UmXW+Xr4aAFgVgh+d8Z3iZxVDs5J+0VcilJBI2q3e\n\t3BeYmquyQgrFOLCeXggvf+6Ck6+5LERFAPe6B3BFEiheOPfDsxqjyCCl3mMmt6+aaaxo\n\tH3PY28o7wt7YTdFlARN7XuQP/mvzmqtHsiAIj9tp+88hLG4Rpvspbm4L8IDL1Iaxe/x2\n\tK2W/dKJ0roHTBUrQB/M3Zw4RQFBV7QjNO8VY7sDC/jZ8yJ6cxwduZfOjFadzMZ4ZeGKZ\n\tgwJbzNudkCf/cCvgre6XnYNNwadtkUs0VQ979+Rjfvbd6uxlLhoUnruyw/2CERl25Fq2\n\t4TXA==",
        "X-Gm-Message-State": "AMke39mo3P/EN+MK+Lgg/owGzANYWaNsU1PAY/WV01/ccWMLQ/JMTuwbVcgawth8eWd8AA==",
        "X-Received": "by 10.98.160.84 with SMTP id r81mr16555543pfe.71.1488743233424; \n\tSun, 05 Mar 2017 11:47:13 -0800 (PST)",
        "From": "Ravi Kerur <rkerur@gmail.com>",
        "To": "dev@dpdk.org",
        "Cc": "konstantin.ananyev@intel.com, bruce.richardson@intel.com,\n\tRavi Kerur <rkerur@gmail.com>",
        "Date": "Sun,  5 Mar 2017 11:47:05 -0800",
        "Message-Id": "<1488743225-25750-4-git-send-email-rkerur@gmail.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1488743225-25750-1-git-send-email-rkerur@gmail.com>",
        "References": "<1488743225-25750-1-git-send-email-rkerur@gmail.com>",
        "Subject": "[dpdk-dev] [v4 3/3] EM config file read option.",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "v4:\n\t> No changes.\n\nv3:\n\t> Fix additional checkpatch coding style issues.\n\nv2:\n\t> Fix checkpatch warnings.\n\nv1:\n\t> Remove static array configuration of Dest IP,Src IP, Dest\n\t\tport, Src port, Proto and IF_OUT for EM and EM6 config.\n\t> Add reading configuration from a file.\n\t> Format of configuration file is as follows\n\t\t#EM route entries,\n\t\t#Dest-IP Src-IP Dest-port Src-port Proto IF_OUT\n\t\tE101.0.0.0 100.10.0.0 101 11 0x06 0\n\t\tE201.0.0.0 200.20.0.0 102 12 0x06 1\n\t\tE111.0.0.0 211.30.0.0 101 11 0x06 2\n\t\t...\n\n\t\t#EM6 route entries\n\t\t#Dest-IP Src-IP Dest-port Src-port Proto IF_OUT\n\t\tEfe80:0000:0000:0000:021e:67ff:fe00:0000\n\t\t\tfe80:0000:0000:0000:021b:21ff:fe91:3805 101 11 0x06 0\n\t\tEfe90:0000:0000:0000:021e:67ff:fe00:0000\n\t\t\tfe90:0000:0000:0000:021b:21ff:fe91:3805 102 12 0x06 1\n                ...\n\nSigned-off-by: Ravi Kerur <rkerur@gmail.com>\n---\n examples/l3fwd/l3fwd_em.c | 376 +++++++++++++++++++++++++++++++++++++---------\n 1 file changed, 303 insertions(+), 73 deletions(-)",
    "diff": "diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c\nindex 6fdabf7..cd6b443 100644\n--- a/examples/l3fwd/l3fwd_em.c\n+++ b/examples/l3fwd/l3fwd_em.c\n@@ -95,8 +95,14 @@ union ipv4_5tuple_host {\n #define XMM_NUM_IN_IPV6_5TUPLE 3\n \n struct ipv6_5tuple {\n-\tuint8_t  ip_dst[IPV6_ADDR_LEN];\n-\tuint8_t  ip_src[IPV6_ADDR_LEN];\n+\tunion {\n+\t\tuint8_t  ip_dst[IPV6_ADDR_LEN];\n+\t\tuint32_t ip32_dst[4];\n+\t};\n+\tunion {\n+\t\tuint8_t  ip_src[IPV6_ADDR_LEN];\n+\t\tuint32_t ip32_src[4];\n+\t};\n \tuint16_t port_dst;\n \tuint16_t port_src;\n \tuint8_t  proto;\n@@ -116,47 +122,24 @@ union ipv6_5tuple_host {\n \txmm_t xmm[XMM_NUM_IN_IPV6_5TUPLE];\n };\n \n-\n-\n-struct ipv4_l3fwd_em_route {\n-\tstruct ipv4_5tuple key;\n-\tuint8_t if_out;\n+enum {\n+\tCB_FLD_DST_ADDR,\n+\tCB_FLD_SRC_ADDR,\n+\tCB_FLD_DST_PORT,\n+\tCB_FLD_SRC_PORT,\n+\tCB_FLD_PROTO,\n+\tCB_FLD_IF_OUT,\n+\tCB_FLD_MAX\n };\n \n-struct ipv6_l3fwd_em_route {\n-\tstruct ipv6_5tuple key;\n+struct em_rule {\n+\tunion {\n+\t\tstruct ipv4_5tuple v4_key;\n+\t\tstruct ipv6_5tuple v6_key;\n+\t};\n \tuint8_t if_out;\n };\n \n-static struct ipv4_l3fwd_em_route ipv4_l3fwd_em_route_array[] = {\n-\t{{IPv4(101, 0, 0, 0), IPv4(100, 10, 0, 1),  101, 11, IPPROTO_TCP}, 0},\n-\t{{IPv4(201, 0, 0, 0), IPv4(200, 20, 0, 1),  102, 12, IPPROTO_TCP}, 1},\n-\t{{IPv4(111, 0, 0, 0), IPv4(100, 30, 0, 1),  101, 11, IPPROTO_TCP}, 2},\n-\t{{IPv4(211, 0, 0, 0), IPv4(200, 40, 0, 1),  102, 12, IPPROTO_TCP}, 3},\n-};\n-\n-static struct ipv6_l3fwd_em_route ipv6_l3fwd_em_route_array[] = {\n-\t{{\n-\t{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0},\n-\t{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05},\n-\t101, 11, IPPROTO_TCP}, 0},\n-\n-\t{{\n-\t{0xfe, 0x90, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0},\n-\t{0xfe, 0x90, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05},\n-\t102, 12, IPPROTO_TCP}, 1},\n-\n-\t{{\n-\t{0xfe, 0xa0, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0},\n-\t{0xfe, 0xa0, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05},\n-\t101, 11, IPPROTO_TCP}, 2},\n-\n-\t{{\n-\t{0xfe, 0xb0, 0, 0, 0, 0, 0, 0, 0x02, 0x1e, 0x67, 0xff, 0xfe, 0, 0, 0},\n-\t{0xfe, 0xb0, 0, 0, 0, 0, 0, 0, 0x02, 0x1b, 0x21, 0xff, 0xfe, 0x91, 0x38, 0x05},\n-\t102, 12, IPPROTO_TCP}, 3},\n-};\n-\n struct rte_hash *ipv4_l3fwd_em_lookup_struct[NB_SOCKETS];\n struct rte_hash *ipv6_l3fwd_em_lookup_struct[NB_SOCKETS];\n \n@@ -233,12 +216,6 @@ ipv6_hash_crc(const void *data, __rte_unused uint32_t data_len,\n \treturn init_val;\n }\n \n-#define IPV4_L3FWD_EM_NUM_ROUTES \\\n-\t(sizeof(ipv4_l3fwd_em_route_array) / sizeof(ipv4_l3fwd_em_route_array[0]))\n-\n-#define IPV6_L3FWD_EM_NUM_ROUTES \\\n-\t(sizeof(ipv6_l3fwd_em_route_array) / sizeof(ipv6_l3fwd_em_route_array[0]))\n-\n static uint8_t ipv4_l3fwd_out_if[L3FWD_HASH_ENTRIES] __rte_cache_aligned;\n static uint8_t ipv6_l3fwd_out_if[L3FWD_HASH_ENTRIES] __rte_cache_aligned;\n \n@@ -338,6 +315,224 @@ em_get_ipv6_dst_port(void *ipv6_hdr,  uint8_t portid, void *lookup_struct)\n #include \"l3fwd_em.h\"\n #endif\n \n+static int\n+em_parse_v6_addr(const char *in, const char **end, uint32_t v[IPV6_ADDR_U32],\n+\tchar dlm)\n+{\n+\tuint32_t addr[IPV6_ADDR_U16];\n+\n+\tGET_CB_FIELD(in, addr[0], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[1], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[2], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[3], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[4], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[5], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[6], 16, UINT16_MAX, ':');\n+\tGET_CB_FIELD(in, addr[7], 16, UINT16_MAX, dlm);\n+\n+\t*end = in;\n+\n+\tv[0] = (addr[0] << 16) + addr[1];\n+\tv[1] = (addr[2] << 16) + addr[3];\n+\tv[2] = (addr[4] << 16) + addr[5];\n+\tv[3] = (addr[6] << 16) + addr[7];\n+\n+\treturn 0;\n+}\n+\n+static int\n+em_parse_v6_net(const char *in, uint32_t *v)\n+{\n+\tint32_t rc;\n+\tconst char *mp;\n+\n+\t/* get address. */\n+\trc = em_parse_v6_addr(in, &mp, v, 0);\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v6_addr failed %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+em_parse_v6_rule(char *str, struct em_rule *v)\n+{\n+\tint i, rc;\n+\tchar *s, *sp, *in[CB_FLD_MAX];\n+\tstatic const char *dlm = \" \\t\\n\";\n+\tint dim = CB_FLD_MAX;\n+\ts = str;\n+\n+\tfor (i = 0; i != dim; i++, s = NULL) {\n+\t\tin[i] = strtok_r(s, dlm, &sp);\n+\t\tif (in[i] == NULL) {\n+\t\t\tRTE_LOG(ERR, L3FWD, \"strtok failed\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\trc = em_parse_v6_net(in[CB_FLD_DST_ADDR], v->v6_key.ip32_dst);\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v6_net failed for dst %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\trc = em_parse_v6_net(in[CB_FLD_SRC_ADDR], v->v6_key.ip32_src);\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v6_net failed for src %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\t/* source port. */\n+\tGET_CB_FIELD(in[CB_FLD_SRC_PORT], v->v6_key.port_src, 0, UINT16_MAX, 0);\n+\t/* destination port. */\n+\tGET_CB_FIELD(in[CB_FLD_DST_PORT], v->v6_key.port_dst, 0, UINT16_MAX, 0);\n+\t/* protocol. */\n+\tGET_CB_FIELD(in[CB_FLD_PROTO], v->v6_key.proto, 0, UINT8_MAX, 0);\n+\t/* out interface. */\n+\tGET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);\n+\n+\treturn 0;\n+}\n+\n+static int\n+em_parse_v4_net(const char *in, uint32_t *addr)\n+{\n+\tuint8_t a, b, c, d;\n+\n+\tGET_CB_FIELD(in, a, 0, UINT8_MAX, '.');\n+\tGET_CB_FIELD(in, b, 0, UINT8_MAX, '.');\n+\tGET_CB_FIELD(in, c, 0, UINT8_MAX, '.');\n+\tGET_CB_FIELD(in, d, 0, UINT8_MAX, 0);\n+\n+\taddr[0] = IPv4(a, b, c, d);\n+\treturn 0;\n+}\n+\n+static int\n+em_parse_v4_rule(char *str, struct em_rule *v)\n+{\n+\tint i, rc;\n+\tchar *s, *sp, *in[CB_FLD_MAX];\n+\tstatic const char *dlm = \" \\t\\n\";\n+\tint dim = CB_FLD_MAX;\n+\ts = str;\n+\n+\tfor (i = 0; i != dim; i++, s = NULL) {\n+\t\tin[i] = strtok_r(s, dlm, &sp);\n+\t\tif (in[i] == NULL) {\n+\t\t\tRTE_LOG(ERR, L3FWD, \"parse_v4_rule strtok fail\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\trc = em_parse_v4_net(in[CB_FLD_DST_ADDR], &(v->v4_key.ip_dst));\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v4_net dst failed %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\trc = em_parse_v4_net(in[CB_FLD_SRC_ADDR], &(v->v4_key.ip_src));\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v4_net src failed %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\t/* source port. */\n+\tGET_CB_FIELD(in[CB_FLD_SRC_PORT], v->v4_key.port_src, 0, UINT16_MAX, 0);\n+\t/* destination port. */\n+\tGET_CB_FIELD(in[CB_FLD_DST_PORT], v->v4_key.port_dst, 0, UINT16_MAX, 0);\n+\t/* protocol. */\n+\tGET_CB_FIELD(in[CB_FLD_PROTO], v->v4_key.proto, 0, UINT8_MAX, 0);\n+\t/* out interface. */\n+\tGET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);\n+\n+\treturn 0;\n+}\n+\n+static int\n+em_add_rules(const char *rule_path,\n+\t\tstruct em_rule **proute_base,\n+\t\tunsigned int *proute_num,\n+\t\tint (*parser)(char *, struct em_rule*))\n+{\n+\tuint8_t *route_rules;\n+\tstruct em_rule *next;\n+\tunsigned int route_num = 0;\n+\tunsigned int route_cnt = 0;\n+\tchar buff[LINE_MAX];\n+\tFILE *fh = fopen(rule_path, \"rb\");\n+\tunsigned int i = 0, rule_size = sizeof(*next);\n+\n+\tif (fh == NULL)\n+\t\trte_exit(EXIT_FAILURE, \"%s: Open %s failed\\n\", __func__,\n+\t\t\trule_path);\n+\n+\twhile ((fgets(buff, LINE_MAX, fh) != NULL)) {\n+\t\tif (buff[0] == EM_LEAD_CHAR)\n+\t\t\troute_num++;\n+\t}\n+\n+\tif (route_num == 0)\n+\t\trte_exit(EXIT_FAILURE, \"Not find any route entries in %s!\\n\",\n+\t\t\t\trule_path);\n+\n+\tfseek(fh, 0, SEEK_SET);\n+\n+\troute_rules = calloc(route_num, rule_size);\n+\n+\tif (route_rules == NULL)\n+\t\trte_exit(EXIT_FAILURE, \"%s: failed to malloc memory\\n\",\n+\t\t\t__func__);\n+\n+\ti = 0;\n+\twhile (fgets(buff, LINE_MAX, fh) != NULL) {\n+\t\ti++;\n+\n+\t\tif (is_bypass_line(buff))\n+\t\t\tcontinue;\n+\n+\t\tchar s = buff[0];\n+\n+\t\t/* Route entry */\n+\t\tif (s == EM_LEAD_CHAR)\n+\t\t\tnext = (struct em_rule *)(route_rules +\n+\t\t\t\troute_cnt * rule_size);\n+\n+\t\t/* Illegal line */\n+\t\telse\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"%s Line %u: should start with leading \"\n+\t\t\t\t\"char %c\\n\",\n+\t\t\t\trule_path, i, EM_LEAD_CHAR);\n+\n+\t\tif (parser(buff + 1, next) != 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"%s Line %u: parse rules error\\n\",\n+\t\t\t\trule_path, i);\n+\n+\t\troute_cnt++;\n+\t}\n+\n+\tfclose(fh);\n+\n+\t*proute_base = (struct em_rule *)route_rules;\n+\t*proute_num = route_cnt;\n+\n+\treturn 0;\n+}\n+\n+static int\n+check_em_config(void)\n+{\n+\tif (parm_config.rule_ipv4_name == NULL) {\n+\t\tRTE_LOG(ERR, L3FWD, \"EM IPv4 rule file not specified\\n\");\n+\t\treturn -1;\n+\t} else if (parm_config.rule_ipv6_name == NULL) {\n+\t\tRTE_LOG(ERR, L3FWD, \"EM IPv6 rule file not specified\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static void\n convert_ipv4_5tuple(struct ipv4_5tuple *key1,\n \t\tunion ipv4_5tuple_host *key2)\n@@ -378,16 +573,24 @@ populate_ipv4_few_flow_into_table(const struct rte_hash *h)\n {\n \tuint32_t i;\n \tint32_t ret;\n+\tstruct em_rule *route_base_v4;\n+\tunsigned int route_num_v4 = 0;\n \n \tmask0 = (rte_xmm_t){.u32 = {BIT_8_TO_15, ALL_32_BITS,\n \t\t\t\tALL_32_BITS, ALL_32_BITS} };\n \n-\tfor (i = 0; i < IPV4_L3FWD_EM_NUM_ROUTES; i++) {\n-\t\tstruct ipv4_l3fwd_em_route  entry;\n+\t/* Load rules from the input file */\n+\tif (em_add_rules(parm_config.rule_ipv4_name,\n+\t\t&route_base_v4, &route_num_v4,\n+\t\t&em_parse_v4_rule) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to add em v4 rules\\n\");\n+\n+\tfor (i = 0; i < route_num_v4; i++) {\n+\t\tstruct em_rule  entry;\n \t\tunion ipv4_5tuple_host newkey;\n \n-\t\tentry = ipv4_l3fwd_em_route_array[i];\n-\t\tconvert_ipv4_5tuple(&entry.key, &newkey);\n+\t\tentry = route_base_v4[i];\n+\t\tconvert_ipv4_5tuple(&entry.v4_key, &newkey);\n \t\tret = rte_hash_add_key(h, (void *) &newkey);\n \t\tif (ret < 0) {\n \t\t\trte_exit(EXIT_FAILURE, \"Unable to add entry %\" PRIu32\n@@ -396,7 +599,7 @@ populate_ipv4_few_flow_into_table(const struct rte_hash *h)\n \t\tipv4_l3fwd_out_if[ret] = entry.if_out;\n \t}\n \tprintf(\"Hash: Adding 0x%\" PRIx64 \" keys\\n\",\n-\t\t(uint64_t)IPV4_L3FWD_EM_NUM_ROUTES);\n+\t\t(uint64_t)route_num_v4);\n }\n \n #define BIT_16_TO_23 0x00ff0000\n@@ -405,18 +608,26 @@ populate_ipv6_few_flow_into_table(const struct rte_hash *h)\n {\n \tuint32_t i;\n \tint32_t ret;\n+\tstruct em_rule *route_base_v6;\n+\tunsigned int route_num_v6 = 0;\n \n \tmask1 = (rte_xmm_t){.u32 = {BIT_16_TO_23, ALL_32_BITS,\n \t\t\t\tALL_32_BITS, ALL_32_BITS} };\n \n \tmask2 = (rte_xmm_t){.u32 = {ALL_32_BITS, ALL_32_BITS, 0, 0} };\n \n-\tfor (i = 0; i < IPV6_L3FWD_EM_NUM_ROUTES; i++) {\n-\t\tstruct ipv6_l3fwd_em_route entry;\n+\t/* Load rules from the input file */\n+\tif (em_add_rules(parm_config.rule_ipv6_name,\n+\t\t&route_base_v6, &route_num_v6,\n+\t\t&em_parse_v6_rule) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to add em v6 rules\\n\");\n+\n+\tfor (i = 0; i < route_num_v6; i++) {\n+\t\tstruct em_rule entry;\n \t\tunion ipv6_5tuple_host newkey;\n \n-\t\tentry = ipv6_l3fwd_em_route_array[i];\n-\t\tconvert_ipv6_5tuple(&entry.key, &newkey);\n+\t\tentry = route_base_v6[i];\n+\t\tconvert_ipv6_5tuple(&entry.v6_key, &newkey);\n \t\tret = rte_hash_add_key(h, (void *) &newkey);\n \t\tif (ret < 0) {\n \t\t\trte_exit(EXIT_FAILURE, \"Unable to add entry %\" PRIu32\n@@ -425,7 +636,7 @@ populate_ipv6_few_flow_into_table(const struct rte_hash *h)\n \t\tipv6_l3fwd_out_if[ret] = entry.if_out;\n \t}\n \tprintf(\"Hash: Adding 0x%\" PRIx64 \"keys\\n\",\n-\t\t(uint64_t)IPV6_L3FWD_EM_NUM_ROUTES);\n+\t\t(uint64_t)route_num_v6);\n }\n \n #define NUMBER_PORT_USED 4\n@@ -434,12 +645,20 @@ populate_ipv4_many_flow_into_table(const struct rte_hash *h,\n \t\tunsigned int nr_flow)\n {\n \tunsigned i;\n+\tstruct em_rule *route_base_v4;\n+\tunsigned int route_num_v4 = 0;\n \n \tmask0 = (rte_xmm_t){.u32 = {BIT_8_TO_15, ALL_32_BITS,\n \t\t\t\tALL_32_BITS, ALL_32_BITS} };\n \n+\t/* Load rules from the input file */\n+\tif (em_add_rules(parm_config.rule_ipv4_name,\n+\t\t&route_base_v4, &route_num_v4,\n+\t\t&em_parse_v4_rule) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to add em v4 rules\\n\");\n+\n \tfor (i = 0; i < nr_flow; i++) {\n-\t\tstruct ipv4_l3fwd_em_route entry;\n+\t\tstruct em_rule entry;\n \t\tunion ipv4_5tuple_host newkey;\n \n \t\tuint8_t a = (uint8_t)\n@@ -453,23 +672,23 @@ populate_ipv4_many_flow_into_table(const struct rte_hash *h,\n \t\tmemset(&entry, 0, sizeof(entry));\n \t\tswitch (i & (NUMBER_PORT_USED - 1)) {\n \t\tcase 0:\n-\t\t\tentry = ipv4_l3fwd_em_route_array[0];\n-\t\t\tentry.key.ip_dst = IPv4(101, c, b, a);\n+\t\t\tentry = route_base_v4[0];\n+\t\t\tentry.v4_key.ip_dst = IPv4(101, c, b, a);\n \t\t\tbreak;\n \t\tcase 1:\n-\t\t\tentry = ipv4_l3fwd_em_route_array[1];\n-\t\t\tentry.key.ip_dst = IPv4(201, c, b, a);\n+\t\t\tentry = route_base_v4[1];\n+\t\t\tentry.v4_key.ip_dst = IPv4(201, c, b, a);\n \t\t\tbreak;\n \t\tcase 2:\n-\t\t\tentry = ipv4_l3fwd_em_route_array[2];\n-\t\t\tentry.key.ip_dst = IPv4(111, c, b, a);\n+\t\t\tentry = route_base_v4[2];\n+\t\t\tentry.v4_key.ip_dst = IPv4(111, c, b, a);\n \t\t\tbreak;\n \t\tcase 3:\n-\t\t\tentry = ipv4_l3fwd_em_route_array[3];\n-\t\t\tentry.key.ip_dst = IPv4(211, c, b, a);\n+\t\t\tentry = route_base_v4[3];\n+\t\t\tentry.v4_key.ip_dst = IPv4(211, c, b, a);\n \t\t\tbreak;\n \t\t};\n-\t\tconvert_ipv4_5tuple(&entry.key, &newkey);\n+\t\tconvert_ipv4_5tuple(&entry.v4_key, &newkey);\n \t\tint32_t ret = rte_hash_add_key(h, (void *) &newkey);\n \n \t\tif (ret < 0)\n@@ -486,13 +705,21 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,\n \t\tunsigned int nr_flow)\n {\n \tunsigned i;\n+\tstruct em_rule *route_base_v6;\n+\tunsigned int route_num_v6 = 0;\n \n \tmask1 = (rte_xmm_t){.u32 = {BIT_16_TO_23, ALL_32_BITS,\n \t\t\t\tALL_32_BITS, ALL_32_BITS} };\n \tmask2 = (rte_xmm_t){.u32 = {ALL_32_BITS, ALL_32_BITS, 0, 0} };\n \n+\t/* Load rules from the input file */\n+\tif (em_add_rules(parm_config.rule_ipv6_name,\n+\t\t&route_base_v6, &route_num_v6,\n+\t\t&em_parse_v6_rule) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to add em v6 rules\\n\");\n+\n \tfor (i = 0; i < nr_flow; i++) {\n-\t\tstruct ipv6_l3fwd_em_route entry;\n+\t\tstruct em_rule entry;\n \t\tunion ipv6_5tuple_host newkey;\n \n \t\tuint8_t a = (uint8_t)\n@@ -506,22 +733,22 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,\n \t\tmemset(&entry, 0, sizeof(entry));\n \t\tswitch (i & (NUMBER_PORT_USED - 1)) {\n \t\tcase 0:\n-\t\t\tentry = ipv6_l3fwd_em_route_array[0];\n+\t\t\tentry = route_base_v6[0];\n \t\t\tbreak;\n \t\tcase 1:\n-\t\t\tentry = ipv6_l3fwd_em_route_array[1];\n+\t\t\tentry = route_base_v6[1];\n \t\t\tbreak;\n \t\tcase 2:\n-\t\t\tentry = ipv6_l3fwd_em_route_array[2];\n+\t\t\tentry = route_base_v6[2];\n \t\t\tbreak;\n \t\tcase 3:\n-\t\t\tentry = ipv6_l3fwd_em_route_array[3];\n+\t\t\tentry = route_base_v6[3];\n \t\t\tbreak;\n \t\t};\n-\t\tentry.key.ip_dst[13] = c;\n-\t\tentry.key.ip_dst[14] = b;\n-\t\tentry.key.ip_dst[15] = a;\n-\t\tconvert_ipv6_5tuple(&entry.key, &newkey);\n+\t\tentry.v6_key.ip_dst[13] = c;\n+\t\tentry.v6_key.ip_dst[14] = b;\n+\t\tentry.v6_key.ip_dst[15] = a;\n+\t\tconvert_ipv6_5tuple(&entry.v6_key, &newkey);\n \t\tint32_t ret = rte_hash_add_key(h, (void *) &newkey);\n \n \t\tif (ret < 0)\n@@ -746,6 +973,9 @@ setup_hash(const int socketid)\n \n \tchar s[64];\n \n+\tif (check_em_config() != 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to get valid EM options\\n\");\n+\n \t/* create ipv4 hash */\n \tsnprintf(s, sizeof(s), \"ipv4_l3fwd_hash_%d\", socketid);\n \tipv4_l3fwd_hash_params.name = s;\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "3/3"
    ]
}