get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 21410,
    "url": "https://patches.dpdk.org/api/patches/21410/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1488660259-6228-3-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": "<1488660259-6228-3-git-send-email-rkerur@gmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1488660259-6228-3-git-send-email-rkerur@gmail.com",
    "date": "2017-03-04T20:44:18",
    "name": "[dpdk-dev,v3,2/3] LPM config file read option.",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "dc2ac9d83f05c2a22e33b0c8fd8857796985d6ea",
    "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/1488660259-6228-3-git-send-email-rkerur@gmail.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/21410/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/21410/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 13A475592;\n\tSat,  4 Mar 2017 21:45:40 +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 A430C2952\n\tfor <dev@dpdk.org>; Sat,  4 Mar 2017 21:45:16 +0100 (CET)",
            "by mail-pf0-f193.google.com with SMTP id 67so8908885pfg.2\n\tfor <dev@dpdk.org>; Sat, 04 Mar 2017 12:45:16 -0800 (PST)",
            "from user-PC.hsd1.ca.comcast.net\n\t([2601:646:8680:32d0:a4fd:8fa5:6779:2528])\n\tby smtp.gmail.com with ESMTPSA id\n\t197sm30716987pfv.19.2017.03.04.12.45.14\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tSat, 04 Mar 2017 12:45:14 -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=w1/px4yHFBANrw3M/wbbP1qb/r6qS13DAwAgckSvTWc=;\n\tb=WdGuZ55k6MVLG+HdnMqj/XWwPbDPZevMI3i/nqc8U0hE7Q/O5TcP0bC49EP5xMRrUh\n\tPnznYj3khc29NWFHWyRz1pY6z4TC6i5FXKZnxEztNNvOTwuCl9eoo6RTh5p1o7SdC3Oz\n\tfEr508IAsDM1Wwxg2cJAzkd4NQTCVRr0K6MJv0aPkyVAglpczvHBOPgZ5e3OIK3HZYmz\n\tHmRgXfSHfxAal42pkjelGAUj/0ymSo9JOeUw4+zDdO/xrkpm2zq6vicOIUcWbmYlkNbb\n\tFmyT4ed4EveyqxCkwauX7FQnJqJrUpHAQXyHGTgtq7oFk0Y1uzbVZAObhsym+SgY4A6u\n\tBj9g==",
        "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=w1/px4yHFBANrw3M/wbbP1qb/r6qS13DAwAgckSvTWc=;\n\tb=SKVxZV8bUq39OvFUmsskKRjTo0UIOohHsgyOuUq2Hr9FWRX7M2SfJBv/yjSzyk2niN\n\tdjnhUc+bsj/fNI2NiMcO8UW4by40+1lV39LTfkJqrCGMIiK/rhNTTQCJW+dp86bO5EYh\n\t1Xv1tIcFbPcNx6+ClyfxBZijFG8Hnc7momBZx/0WXsaigcAJ1Ns2rjB8XnZQNJmIStfe\n\trm8DiUmgONS7DhqeLu4CPKdHj7cRshSXJn49lpfByWBl1HWrz68HUbW7Q8JCLm0CZ1IV\n\tyRhf0aEPnYwpirkDHugCXcT2Mn0vXQI5+r7mLJ9lWC+8jRHkQK5tqIc8rNUPNh/UH1IB\n\tj70Q==",
        "X-Gm-Message-State": "AMke39mdQVMvtbxLBqJ0lq3vh+64wGcJCy+Y67o9YKCasCHkymOzHJSyNGJdbxLv2muoSw==",
        "X-Received": "by 10.84.214.9 with SMTP id h9mr14001168pli.65.1488660315653;\n\tSat, 04 Mar 2017 12:45:15 -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": "Sat,  4 Mar 2017 12:44:18 -0800",
        "Message-Id": "<1488660259-6228-3-git-send-email-rkerur@gmail.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1488660259-6228-1-git-send-email-rkerur@gmail.com>",
        "References": "<1488660259-6228-1-git-send-email-rkerur@gmail.com>",
        "Subject": "[dpdk-dev] [v3 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 <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": "v3:\n\t> Fix additional checkpatch coding style issues.\n\nv2:\n\t> Fix checkpatch warnings related to code\n\t> MACRO GET_CB_FIELD checkpatch warning not fixed\n\nv1:\n\t> Remove static array configuration of Destination IP, MASK\n\t\tand IF_OUT for LPM and LPM6 config.\n\t> Add reading configuration from a file.\n\t> Format of configuration file is as follows\n\t\t#LPM route entries Dest-IP/Mask IF_OUT\n\t\tL1.1.1.0/24 0\n\t\tL2.1.1.0/24 1\n\t\tL3.1.1.0/24 2\n\t\t...\n\n\t\t#LPM6 route entries Dest-IP/Mask IF_OUT\n\t\tL1111:1111:1111:1111:0000:0000:0000:0000/48 0\n\t\tL2111:1111:1111:1111:0000:0000:0000:0000/48 1\n\t\tL3111:1111:1111:1111:0000:0000:0000:0000/48 2\n\t\t...\n\nSigned-off-by: Ravi Kerur <rkerur@gmail.com>\n---\n examples/l3fwd/l3fwd.h     |  43 +++++++\n examples/l3fwd/l3fwd_acl.c |  39 +-----\n examples/l3fwd/l3fwd_acl.h |  29 -----\n examples/l3fwd/l3fwd_lpm.c | 308 +++++++++++++++++++++++++++++++++++++--------\n examples/l3fwd/main.c      |  29 ++++-\n 5 files changed, 329 insertions(+), 119 deletions(-)",
    "diff": "diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h\nindex 93e08f6..4b1cdc8 100644\n--- a/examples/l3fwd/l3fwd.h\n+++ b/examples/l3fwd/l3fwd.h\n@@ -94,6 +94,47 @@\n #define ACL_LEAD_CHAR\t\t('@')\n #define ROUTE_LEAD_CHAR\t\t('R')\n #define COMMENT_LEAD_CHAR\t('#')\n+#define LPM_LEAD_CHAR\t\t('L')\n+#define EM_LEAD_CHAR\t\t('E')\n+\n+#define\tIPV6_ADDR_LEN\t16\n+#define\tIPV6_ADDR_U16\t(IPV6_ADDR_LEN / sizeof(uint16_t))\n+#define\tIPV6_ADDR_U32\t(IPV6_ADDR_LEN / sizeof(uint32_t))\n+\n+#define GET_CB_FIELD(in, fd, base, lim, dlm)\tdo {            \\\n+\tunsigned long val;                                      \\\n+\tchar *end;                                              \\\n+\terrno = 0;                                              \\\n+\tval = strtoul((in), &end, (base));                      \\\n+\tif (errno != 0 || end[0] != (dlm) || val > (lim))       \\\n+\t\treturn -EINVAL;                               \\\n+\t(fd) = (typeof(fd))val;                                 \\\n+\t(in) = end + 1;                                         \\\n+} while (0)\n+\n+/* Bypass comment and empty lines */\n+static inline int\n+is_bypass_line(char *buff)\n+{\n+\tint i = 0;\n+\n+\t/* comment line */\n+\tif (buff[0] == COMMENT_LEAD_CHAR)\n+\t\treturn 1;\n+\t/* empty line */\n+\twhile (buff[i] != '\\0') {\n+\t\tif (!isspace(buff[i]))\n+\t\t\treturn 0;\n+\t\ti++;\n+\t}\n+\treturn 1;\n+}\n+\n+struct parm_cfg {\n+\tconst char *rule_ipv4_name;\n+\tconst char *rule_ipv6_name;\n+\tint scalar;\n+};\n \n struct mbuf_table {\n \tuint16_t len;\n@@ -134,6 +175,8 @@ extern xmm_t val_eth[RTE_MAX_ETHPORTS];\n \n extern struct lcore_conf lcore_conf[RTE_MAX_LCORE];\n \n+extern struct parm_cfg parm_config;\n+\n extern int numa_on; /**< NUMA is enabled by default. */\n \n /* Send burst of packets on an output interface */\ndiff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c\nindex 103c730..a5b2c12 100644\n--- a/examples/l3fwd/l3fwd_acl.c\n+++ b/examples/l3fwd/l3fwd_acl.c\n@@ -147,10 +147,6 @@ struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {\n \t},\n };\n \n-#define\tIPV6_ADDR_LEN\t16\n-#define\tIPV6_ADDR_U16\t(IPV6_ADDR_LEN / sizeof(uint16_t))\n-#define\tIPV6_ADDR_U32\t(IPV6_ADDR_LEN / sizeof(uint32_t))\n-\n enum {\n \tPROTO_FIELD_IPV6,\n \tSRC1_FIELD_IPV6,\n@@ -297,12 +293,6 @@ static struct {\n \n const char cb_port_delim[] = \":\";\n \n-static struct {\n-\tconst char *rule_ipv4_name;\n-\tconst char *rule_ipv6_name;\n-\tint scalar;\n-} parm_config;\n-\n /*\n  * Print and dump ACL/Route rules functions are defined in\n  * following header file.\n@@ -316,27 +306,6 @@ static struct {\n #include \"l3fwd_acl_scalar.h\"\n \n /*\n- * API's called during initialization to setup ACL rules.\n- */\n-void\n-l3fwd_acl_set_rule_ipv4_name(const char *optarg)\n-{\n-\tparm_config.rule_ipv4_name = optarg;\n-}\n-\n-void\n-l3fwd_acl_set_rule_ipv6_name(const char *optarg)\n-{\n-\tparm_config.rule_ipv6_name = optarg;\n-}\n-\n-void\n-l3fwd_acl_set_scalar(void)\n-{\n-\tparm_config.scalar = 1;\n-}\n-\n-/*\n  * Parses IPV6 address, exepcts the following format:\n  * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X - is a hexedecimal digit).\n  */\n@@ -566,7 +535,7 @@ parse_cb_ipv4vlan_rule(char *str, struct rte_acl_rule *v, int has_userdata)\n }\n \n static int\n-add_rules(const char *rule_path,\n+acl_add_rules(const char *rule_path,\n \t\tstruct rte_acl_rule **proute_base,\n \t\tunsigned int *proute_num,\n \t\tstruct rte_acl_rule **pacl_base,\n@@ -764,8 +733,8 @@ setup_acl(const int socket_id __attribute__((unused)))\n \n \tdump_acl_config();\n \n-\t/* Load  rules from the input file */\n-\tif (add_rules(parm_config.rule_ipv4_name, &route_base_ipv4,\n+\t/* Load rules from the input file */\n+\tif (acl_add_rules(parm_config.rule_ipv4_name, &route_base_ipv4,\n \t\t\t&route_num_ipv4, &acl_base_ipv4, &acl_num_ipv4,\n \t\t\tsizeof(struct acl4_rule), &parse_cb_ipv4vlan_rule) < 0)\n \t\trte_exit(EXIT_FAILURE, \"Failed to add rules\\n\");\n@@ -776,7 +745,7 @@ setup_acl(const int socket_id __attribute__((unused)))\n \tacl_log(\"IPv4 ACL entries %u:\\n\", acl_num_ipv4);\n \tdump_ipv4_rules((struct acl4_rule *)acl_base_ipv4, acl_num_ipv4, 1);\n \n-\tif (add_rules(parm_config.rule_ipv6_name, &route_base_ipv6,\n+\tif (acl_add_rules(parm_config.rule_ipv6_name, &route_base_ipv6,\n \t\t\t&route_num_ipv6,\n \t\t\t&acl_base_ipv6, &acl_num_ipv6,\n \t\t\tsizeof(struct acl6_rule), &parse_cb_ipv6_rule) < 0)\ndiff --git a/examples/l3fwd/l3fwd_acl.h b/examples/l3fwd/l3fwd_acl.h\nindex b79784b..da0b5a8 100644\n--- a/examples/l3fwd/l3fwd_acl.h\n+++ b/examples/l3fwd/l3fwd_acl.h\n@@ -55,17 +55,6 @@\n #define MBUF_IPV6_2PROTO(m)\t\\\n \trte_pktmbuf_mtod_offset((m), uint8_t *, OFF_ETHHEAD + OFF_IPV62PROTO)\n \n-#define GET_CB_FIELD(in, fd, base, lim, dlm)\tdo {            \\\n-\tunsigned long val;                                      \\\n-\tchar *end;                                              \\\n-\terrno = 0;                                              \\\n-\tval = strtoul((in), &end, (base));                      \\\n-\tif (errno != 0 || end[0] != (dlm) || val > (lim))       \\\n-\t\treturn -EINVAL;                               \\\n-\t(fd) = (typeof(fd))val;                                 \\\n-\t(in) = end + 1;                                         \\\n-} while (0)\n-\n /*\n  * ACL rules should have higher priorities than route ones to ensure ACL rule\n  * always be found when input packets have multi-matches in the database.\n@@ -163,24 +152,6 @@ print_one_ipv6_rule(struct acl6_rule *rule, int extra)\n \t\t\trule->data.userdata);\n }\n \n-/* Bypass comment and empty lines */\n-static inline int\n-is_bypass_line(char *buff)\n-{\n-\tint i = 0;\n-\n-\t/* comment line */\n-\tif (buff[0] == COMMENT_LEAD_CHAR)\n-\t\treturn 1;\n-\t/* empty line */\n-\twhile (buff[i] != '\\0') {\n-\t\tif (!isspace(buff[i]))\n-\t\t\treturn 0;\n-\t\ti++;\n-\t}\n-\treturn 1;\n-}\n-\n #ifdef L3FWDACL_DEBUG\n static inline void\n dump_acl4_rule(struct rte_mbuf *m, uint32_t sig)\ndiff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c\nindex ab31210..97f99cf 100644\n--- a/examples/l3fwd/l3fwd_lpm.c\n+++ b/examples/l3fwd/l3fwd_lpm.c\n@@ -57,45 +57,24 @@\n \n #include \"l3fwd.h\"\n \n-struct ipv4_l3fwd_lpm_route {\n-\tuint32_t ip;\n-\tuint8_t  depth;\n-\tuint8_t  if_out;\n+enum {\n+\tCB_FLD_DST_ADDR,\n+\tCB_FLD_IF_OUT,\n+\tCB_FLD_MAX\n };\n \n-struct ipv6_l3fwd_lpm_route {\n-\tuint8_t ip[16];\n+struct lpm_rule {\n+\tunion {\n+\t\tuint32_t ip;\n+\t\tunion {\n+\t\t\tuint32_t ip_32[4];\n+\t\t\tuint8_t ip_8[16];\n+\t\t};\n+\t};\n \tuint8_t  depth;\n \tuint8_t  if_out;\n };\n \n-static struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = {\n-\t{IPv4(1, 1, 1, 0), 24, 0},\n-\t{IPv4(2, 1, 1, 0), 24, 1},\n-\t{IPv4(3, 1, 1, 0), 24, 2},\n-\t{IPv4(4, 1, 1, 0), 24, 3},\n-\t{IPv4(5, 1, 1, 0), 24, 4},\n-\t{IPv4(6, 1, 1, 0), 24, 5},\n-\t{IPv4(7, 1, 1, 0), 24, 6},\n-\t{IPv4(8, 1, 1, 0), 24, 7},\n-};\n-\n-static struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = {\n-\t{{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 0},\n-\t{{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 1},\n-\t{{3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 2},\n-\t{{4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 3},\n-\t{{5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 4},\n-\t{{6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 5},\n-\t{{7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 6},\n-\t{{8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 48, 7},\n-};\n-\n-#define IPV4_L3FWD_LPM_NUM_ROUTES \\\n-\t(sizeof(ipv4_l3fwd_lpm_route_array) / sizeof(ipv4_l3fwd_lpm_route_array[0]))\n-#define IPV6_L3FWD_LPM_NUM_ROUTES \\\n-\t(sizeof(ipv6_l3fwd_lpm_route_array) / sizeof(ipv6_l3fwd_lpm_route_array[0]))\n-\n #define IPV4_L3FWD_LPM_MAX_RULES         1024\n #define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8)\n #define IPV6_L3FWD_LPM_MAX_RULES         1024\n@@ -110,6 +89,211 @@ struct rte_lpm6 *ipv6_l3fwd_lpm_lookup_struct[NB_SOCKETS];\n #include \"l3fwd_lpm.h\"\n #endif\n \n+static int\n+lpm_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+lpm_parse_v6_net(const char *in, uint32_t *v, uint8_t *mask_len)\n+{\n+\tint32_t rc;\n+\tconst char *mp;\n+\tuint8_t m;\n+\tuint32_t tmp[4];\n+\n+\t/* get address. */\n+\trc = lpm_parse_v6_addr(in, &mp, v, '/');\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v6_addr failed %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\n+\t/* get mask. */\n+\tGET_CB_FIELD(mp, m, 0, sizeof(tmp) * CHAR_BIT, 0);\n+\t*mask_len = m;\n+\n+\treturn 0;\n+}\n+\n+static int\n+lpm_parse_v6_rule(char *str, struct lpm_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,\n+\t\t\t\t\"\\nparse_v6_rule strtok_r failed\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\trc = lpm_parse_v6_net(in[CB_FLD_DST_ADDR], v->ip_32, &v->depth);\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v6_net failed\\n\");\n+\t\treturn rc;\n+\t}\n+\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+lpm_parse_v4_net(const char *in, uint32_t *addr, uint8_t *mask_len)\n+{\n+\tuint8_t a, b, c, d, m;\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, '/');\n+\tGET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0);\n+\n+\taddr[0] = IPv4(a, b, c, d);\n+\t*mask_len = m;\n+\n+\treturn 0;\n+}\n+\n+static int\n+lpm_parse_v4_rule(char *str, struct lpm_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\treturn -EINVAL;\n+\t}\n+\n+\trc = lpm_parse_v4_net(in[CB_FLD_DST_ADDR], &v->ip, &v->depth);\n+\tif (rc != 0) {\n+\t\tRTE_LOG(ERR, L3FWD, \"parse_v4_net failed %d\\n\", rc);\n+\t\treturn rc;\n+\t}\n+\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+lpm_add_rules(const char *rule_path,\n+\t\tstruct lpm_rule **proute_base,\n+\t\tunsigned int *proute_num,\n+\t\tint (*parser)(char *, struct lpm_rule *))\n+{\n+\tuint8_t *route_rules;\n+\tstruct lpm_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] == LPM_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 == LPM_LEAD_CHAR)\n+\t\t\tnext = (struct lpm_rule *)\n+\t\t\t\t(route_rules + route_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, LPM_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 lpm_rule *)route_rules;\n+\t*proute_num = route_cnt;\n+\n+\treturn 0;\n+}\n+\n+static int\n+check_lpm_config(void)\n+{\n+\tif (parm_config.rule_ipv4_name == NULL) {\n+\t\tRTE_LOG(ERR, L3FWD, \"LPM 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, \"LPM IPv6 rule file not specified\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n /* main processing loop */\n int\n lpm_main_loop(__attribute__((unused)) void *dummy)\n@@ -196,10 +380,16 @@ setup_lpm(const int socketid)\n {\n \tstruct rte_lpm6_config config;\n \tstruct rte_lpm_config config_ipv4;\n+\tstruct lpm_rule *route_base_v4;\n+\tstruct lpm_rule *route_base_v6;\n+\tunsigned int route_num_v4 = 0, route_num_v6 = 0;\n \tunsigned i;\n \tint ret;\n \tchar s[64];\n \n+\tif (check_lpm_config() != 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to get valid LPM options\\n\");\n+\n \t/* create the LPM table */\n \tconfig_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES;\n \tconfig_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S;\n@@ -212,18 +402,25 @@ setup_lpm(const int socketid)\n \t\t\t\"Unable to create v4 LPM table on socket %d\\n\",\n \t\t\tsocketid);\n \n+\t/* Load rules from the input file */\n+\tif (lpm_add_rules(parm_config.rule_ipv4_name,\n+\t\t&route_base_v4, &route_num_v4,\n+\t\t&lpm_parse_v4_rule) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to add lpm v4 rules\\n\");\n+\n \t/* populate the LPM table */\n-\tfor (i = 0; i < IPV4_L3FWD_LPM_NUM_ROUTES; i++) {\n+\tfor (i = 0; i < route_num_v4; i++) {\n \n \t\t/* skip unused ports */\n-\t\tif ((1 << ipv4_l3fwd_lpm_route_array[i].if_out &\n-\t\t\t\tenabled_port_mask) == 0)\n+\t\tif ((1 << route_base_v4[i].if_out &\n+\t\t\tenabled_port_mask) == 0)\n \t\t\tcontinue;\n \n-\t\tret = rte_lpm_add(ipv4_l3fwd_lpm_lookup_struct[socketid],\n-\t\t\t\tipv4_l3fwd_lpm_route_array[i].ip,\n-\t\t\t\tipv4_l3fwd_lpm_route_array[i].depth,\n-\t\t\t\tipv4_l3fwd_lpm_route_array[i].if_out);\n+\t\tret = rte_lpm_add(\n+\t\t\tipv4_l3fwd_lpm_lookup_struct[socketid],\n+\t\t\troute_base_v4[i].ip,\n+\t\t\troute_base_v4[i].depth,\n+\t\t\troute_base_v4[i].if_out);\n \n \t\tif (ret < 0) {\n \t\t\trte_exit(EXIT_FAILURE,\n@@ -231,9 +428,9 @@ setup_lpm(const int socketid)\n \t\t}\n \n \t\tprintf(\"LPM: Adding route 0x%08x / %d (%d)\\n\",\n-\t\t\t(unsigned)ipv4_l3fwd_lpm_route_array[i].ip,\n-\t\t\tipv4_l3fwd_lpm_route_array[i].depth,\n-\t\t\tipv4_l3fwd_lpm_route_array[i].if_out);\n+\t\t\t(unsigned int)route_base_v4[i].ip,\n+\t\t\troute_base_v4[i].depth,\n+\t\t\troute_base_v4[i].if_out);\n \t}\n \n \t/* create the LPM6 table */\n@@ -249,18 +446,25 @@ setup_lpm(const int socketid)\n \t\t\t\"Unable to create v6 LPM table on socket %d\\n\",\n \t\t\tsocketid);\n \n+\t/* Load rules from the input file */\n+\tif (lpm_add_rules(parm_config.rule_ipv6_name,\n+\t\t&route_base_v6, &route_num_v6,\n+\t\t&lpm_parse_v6_rule) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Failed to add lpm v6 rules\\n\");\n+\n \t/* populate the LPM table */\n-\tfor (i = 0; i < IPV6_L3FWD_LPM_NUM_ROUTES; i++) {\n+\tfor (i = 0; i < route_num_v6; i++) {\n \n \t\t/* skip unused ports */\n-\t\tif ((1 << ipv6_l3fwd_lpm_route_array[i].if_out &\n-\t\t\t\tenabled_port_mask) == 0)\n+\t\tif ((1 << route_base_v6[i].if_out &\n+\t\t\tenabled_port_mask) == 0)\n \t\t\tcontinue;\n \n-\t\tret = rte_lpm6_add(ipv6_l3fwd_lpm_lookup_struct[socketid],\n-\t\t\tipv6_l3fwd_lpm_route_array[i].ip,\n-\t\t\tipv6_l3fwd_lpm_route_array[i].depth,\n-\t\t\tipv6_l3fwd_lpm_route_array[i].if_out);\n+\t\tret = rte_lpm6_add(\n+\t\t\tipv6_l3fwd_lpm_lookup_struct[socketid],\n+\t\t\troute_base_v6[i].ip_8,\n+\t\t\troute_base_v6[i].depth,\n+\t\t\troute_base_v6[i].if_out);\n \n \t\tif (ret < 0) {\n \t\t\trte_exit(EXIT_FAILURE,\n@@ -268,8 +472,8 @@ setup_lpm(const int socketid)\n \t\t}\n \n \t\tprintf(\"LPM: Adding route %s / %d (%d)\\n\",\n-\t\t\t\"IPV6\", ipv6_l3fwd_lpm_route_array[i].depth,\n-\t\t\tipv6_l3fwd_lpm_route_array[i].if_out);\n+\t\t\t\"IPV6\", route_base_v6[i].depth,\n+\t\t\troute_base_v6[i].if_out);\n \t}\n }\n \ndiff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c\nindex edeb31d..9c0e035 100644\n--- a/examples/l3fwd/main.c\n+++ b/examples/l3fwd/main.c\n@@ -126,6 +126,8 @@ uint32_t hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;\n \n struct lcore_conf lcore_conf[RTE_MAX_LCORE];\n \n+struct parm_cfg parm_config;\n+\n struct lcore_params {\n \tuint8_t port_id;\n \tuint8_t queue_id;\n@@ -214,6 +216,27 @@ static struct l3fwd_lkp_mode l3fwd_acl_lkp = {\n };\n \n /*\n+ * API's called during initialization to setup ACL/LPM/EM rules.\n+ */\n+static void\n+l3fwd_set_rule_ipv4_name(const char *optarg)\n+{\n+\tparm_config.rule_ipv4_name = optarg;\n+}\n+\n+static void\n+l3fwd_set_rule_ipv6_name(const char *optarg)\n+{\n+\tparm_config.rule_ipv6_name = optarg;\n+}\n+\n+static void\n+l3fwd_set_scalar(void)\n+{\n+\tparm_config.scalar = 1;\n+}\n+\n+/*\n  * Setup lookup methods for forwarding.\n  * Currently exact-match and longest-prefix-match\n  * are supported ones.\n@@ -691,15 +714,15 @@ parse_args(int argc, char **argv)\n \t\t\tbreak;\n \n \t\tcase CMD_LINE_OPT_RULE_IPV4:\n-\t\t\tl3fwd_acl_set_rule_ipv4_name(optarg);\n+\t\t\tl3fwd_set_rule_ipv4_name(optarg);\n \t\t\tbreak;\n \n \t\tcase CMD_LINE_OPT_RULE_IPV6:\n-\t\t\tl3fwd_acl_set_rule_ipv6_name(optarg);\n+\t\t\tl3fwd_set_rule_ipv6_name(optarg);\n \t\t\tbreak;\n \n \t\tcase CMD_LINE_OPT_SCALAR:\n-\t\t\tl3fwd_acl_set_scalar();\n+\t\t\tl3fwd_set_scalar();\n \t\t\tbreak;\n \n \t\tdefault:\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "2/3"
    ]
}