get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 12189,
    "url": "http://patches.dpdk.org/api/patches/12189/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus/",
    "project": {
        "id": 1,
        "url": "http://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": "<1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus",
    "date": "2016-04-21T15:33:44",
    "name": "[dpdk-dev] Rate as a decimal number",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "3b520e3c871ecad21ebcc1a55c3eb637530fbeb2",
    "submitter": {
        "id": 466,
        "url": "http://patches.dpdk.org/api/people/466/?format=api",
        "name": "inaki.murillo",
        "email": "inaki.murilloa@ehu.eus"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/12189/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/12189/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 0D1652C62;\n\tThu, 21 Apr 2016 17:34:53 +0200 (CEST)",
            "from smtp.ehu.eus (smtp.lg.ehu.es [158.227.0.66])\n\tby dpdk.org (Postfix) with ESMTP id 99BB22C4B\n\tfor <dev@dpdk.org>; Thu, 21 Apr 2016 17:34:51 +0200 (CEST)",
            "from smtp.ehu.eus (localhost.localdomain [127.0.0.1])\n\tby postfix.imss71 (Postfix) with ESMTP id 270E08FD4;\n\tThu, 21 Apr 2016 17:34:51 +0200 (CEST)",
            "from murillo.dhcp.i2t.ehu.eus (unknown [158.227.98.37])\n\tby smtp2 (Postfix) with ESMTPS id 0E4AB58A8;\n\tThu, 21 Apr 2016 17:34:51 +0200 (CEST)"
        ],
        "From": "\"inaki.murillo\" <inaki.murilloa@ehu.eus>",
        "To": "dev@dpdk.org",
        "Cc": "\"inaki.murillo\" <inaki.murilloa@ehu.eus>",
        "Date": "Thu, 21 Apr 2016 17:33:44 +0200",
        "Message-Id": "<1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus>",
        "X-Mailer": "git-send-email 1.9.1",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-Greylist": [
            "Sender IP whitelisted, not delayed by milter-greylist-4.4\n\t(smtp2); Thu, 21 Apr 2016 17:34:51 +0200 (CEST)",
            "Sender IP whitelisted, not delayed by milter-greylist-4.4\n\t(postfix.imss71); Thu, 21 Apr 2016 17:34:51 +0200 (CEST)"
        ],
        "Subject": "[dpdk-dev] [PATCH] Rate as a decimal number",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <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": "Currently Pktgen does not accept a decimal number for the rate. This patch makes possible to set a decimal number as a rate.\n\nSigned-off-by: Iñaki Murillo Arroyo <inaki.murilloa@ehu.eus>\n---\n app/cmd-functions.c    |   71 +-\n app/cmd-functions.h    |   38 +\n app/lpktgenlib.c       |    2 +-\n app/pktgen-cmds.c      |   10 +-\n app/pktgen-cmds.c.orig | 2622 ++++++++++++++++++++++++++++++++++++++++++++++++\n app/pktgen-cmds.h      |    2 +-\n app/pktgen-port-cfg.h  |    2 +-\n app/pktgen.c           |    2 +-\n 8 files changed, 2737 insertions(+), 12 deletions(-)\n create mode 100644 app/pktgen-cmds.c.orig",
    "diff": "diff --git a/app/cmd-functions.c b/app/cmd-functions.c\nindex b2fda7c..a009907 100644\n--- a/app/cmd-functions.c\n+++ b/app/cmd-functions.c\n@@ -1805,7 +1805,7 @@ struct cmd_set_result {\n \tcmdline_fixed_string_t set;\n \tcmdline_portlist_t portlist;\n \tcmdline_fixed_string_t what;\n-\tuint32_t value;\n+\tfloat value;\n };\n \n /**************************************************************************//**\n@@ -1865,8 +1865,8 @@ cmdline_parse_token_string_t cmd_set_what =\n         TOKEN_STRING_INITIALIZER(struct cmd_set_result,\n                                  what,\n                                  \"count#size#rate#burst#tx_cycles#sport#dport#seqCnt#prime#dump#vlanid\");\n-cmdline_parse_token_num_t cmd_set_value =\n-        TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT32);\n+cmdline_parse_token_float_t cmd_set_value =\n+        TOKEN_FLOAT_INITIALIZER(struct cmd_set_result, value, FLOAT);\n \n cmdline_parse_inst_t cmd_set = {\n \t.f = cmd_set_parsed,\n@@ -4691,3 +4691,68 @@ pktgen_load_cmds(char *filename)\n \t}\n \treturn 0;\n }\n+\n+struct cmdline_token_ops cmdline_token_float_ops = {\n+\t.parse = cmdline_parse_float,\n+\t.complete_get_nb = NULL,\n+\t.complete_get_elt = NULL,\n+\t.get_help = cmdline_get_help_float,\n+};\n+\n+/* parse a float */\n+int\n+cmdline_parse_float(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res, unsigned ressize)\n+{\n+\tunsigned int token_len;\n+\tfloat tmp;\n+\n+\tif (res && ressize < STR_TOKEN_SIZE)\n+\t\treturn -1;\n+\n+\tif (!tk || !srcbuf || ! *srcbuf)\n+\t\treturn -1;\n+\n+\ttoken_len = 0;\n+\twhile(!cmdline_isendoftoken(srcbuf[token_len]) && token_len < (STR_TOKEN_SIZE-1))\n+\t{\n+\t\ttoken_len++;\n+\t}\n+\n+\t/* return if token too long */\n+\tif (token_len >= STR_TOKEN_SIZE - 1) {\n+\t\treturn -1;\n+\t}\n+\n+\ttmp =  atof(srcbuf);\n+\tif ((tmp == 0 && strcmp(srcbuf, \"0\") == 0) || (tmp != 0)) {\n+\t\t/* we are sure that token_len is < STR_TOKEN_SIZE-1 */\n+\t\t*(float *)res = tmp;\n+\t\treturn token_len;\n+\t}\n+\n+\treturn -1;\n+\n+}\n+\n+/* parse a float */\n+int\n+cmdline_get_help_float(cmdline_parse_token_hdr_t *tk, char *dstbuf, unsigned int size)\n+{\n+\tstruct cmdline_token_float_data nd;\n+\tint ret;\n+\n+\tif (!tk)\n+\t\treturn -1;\n+\n+\tmemcpy(&nd, &((struct cmdline_token_float *)tk)->float_data, sizeof(nd));\n+\n+\t/* should not happen.... don't so this test */\n+\t/* if (nd.type >= (sizeof(num_help)/sizeof(const char *))) */\n+\t/* return -1; */\n+\n+\tret = snprintf(dstbuf, size, \"FLOAT\");\n+\tif (ret < 0)\n+\t\treturn -1;\n+\tdstbuf[size-1] = '\\0';\n+\treturn 0;\n+}\ndiff --git a/app/cmd-functions.h b/app/cmd-functions.h\nindex 0ccef6d..4b8dc4c 100644\n--- a/app/cmd-functions.h\n+++ b/app/cmd-functions.h\n@@ -77,4 +77,42 @@ extern void pktgen_cmdline_start(void);\n \n extern int pktgen_load_cmds(char *filename);\n \n+/* size of a parsed string */\n+#define STR_TOKEN_SIZE 128\n+\n+enum cmdline_floattype {\n+\tFLOAT\n+};\n+\n+struct cmdline_token_float_data {\n+\tconst float *float_data;\n+};\n+\n+struct cmdline_token_float {\n+\tstruct cmdline_token_hdr hdr;\n+\tstruct cmdline_token_float_data float_data;\n+};\n+typedef struct cmdline_token_float cmdline_parse_token_float_t;\n+\n+extern struct cmdline_token_ops cmdline_token_float_ops;\n+\n+int cmdline_parse_float(cmdline_parse_token_hdr_t *tk,\n+\tconst char *srcbuf, void *res, unsigned ressize);\n+int cmdline_get_help_float(cmdline_parse_token_hdr_t *tk,\n+\tchar *dstbuf, unsigned int size);\n+\n+#define TOKEN_FLOAT_INITIALIZER(structure, field, float_type)    \\\n+{                                                           \\\n+\t/* hdr */                                               \\\n+\t{                                                       \\\n+\t\t&cmdline_token_float_ops,         /* ops */           \\\n+\t\toffsetof(structure, field),     /* offset */        \\\n+\t},                                                      \\\n+\t/* num_data */                                          \\\n+\t{                                                       \\\n+\t\tfloat_type,                        /* type */          \\\n+\t},                                                      \\\n+}\n+\n+\n #endif /* _COMMANDS_H_ */\ndiff --git a/app/lpktgenlib.c b/app/lpktgenlib.c\nindex 693a174..f3a2a84 100644\n--- a/app/lpktgenlib.c\n+++ b/app/lpktgenlib.c\n@@ -240,7 +240,7 @@ parse_portlist(const char *buf, void *pl) {\n \n static int\n pktgen_set(lua_State *L) {\n-\tuint32_t value;\n+\tfloat value;\n \tcmdline_portlist_t portlist;\n \tchar *what;\n \ndiff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c\nindex 83ba230..d150b41 100644\n--- a/app/pktgen-cmds.c\n+++ b/app/pktgen-cmds.c\n@@ -178,7 +178,7 @@ pktgen_save(char *path)\n \t\tfprintf(fd, \"#\\n\");\n \t\tflags = rte_atomic32_read(&info->port_flags);\n \t\tfprintf(fd,\n-\t\t        \"# Port: %2d, Burst:%3d, Rate:%3d%%, Flags:%08x, TX Count:%s\\n\",\n+\t\t        \"# Port: %2d, Burst:%3d, Rate:%3f%%, Flags:%08x, TX Count:%s\\n\",\n \t\t        info->pid,\n \t\t        info->tx_burst,\n \t\t        info->tx_rate,\n@@ -196,7 +196,7 @@ pktgen_save(char *path)\n \t\t        \"set %d size %d\\n\",\n \t\t        info->pid,\n \t\t        pkt->pktSize + FCS_SIZE);\n-\t\tfprintf(fd, \"set %d rate %d\\n\", info->pid, info->tx_rate);\n+\t\tfprintf(fd, \"set %d rate %f\\n\", info->pid, info->tx_rate);\n \t\tfprintf(fd, \"set %d burst %d\\n\", info->pid, info->tx_burst);\n \t\tfprintf(fd, \"set %d sport %d\\n\", info->pid, pkt->sport);\n \t\tfprintf(fd, \"set %d dport %d\\n\", info->pid, pkt->dport);\n@@ -498,9 +498,9 @@ pktgen_transmit_count_rate(int port, char *buff, int len)\n \tport_info_t *info = &pktgen.info[port];\n \n \tif (rte_atomic64_read(&info->transmit_count) == 0)\n-\t\tsnprintf(buff, len, \"Forever /%4d%%\", info->tx_rate);\n+\t\tsnprintf(buff, len, \"Forever /%4f%%\", info->tx_rate);\n \telse\n-\t\tsnprintf(buff, len, \"%ld /%4d%%\",\n+\t\tsnprintf(buff, len, \"%ld /%4f%%\",\n \t\t         rte_atomic64_read(&info->transmit_count),\n \t\t         info->tx_rate);\n \n@@ -1949,7 +1949,7 @@ pktgen_set_port_value(port_info_t *info, char type, uint32_t portValue)\n  */\n \n void\n-pktgen_set_tx_rate(port_info_t *info, uint32_t rate)\n+pktgen_set_tx_rate(port_info_t *info, float rate)\n {\n \tif (rate == 0)\n \t\trate = 1;\ndiff --git a/app/pktgen-cmds.c.orig b/app/pktgen-cmds.c.orig\nnew file mode 100644\nindex 0000000..83ba230\n--- /dev/null\n+++ b/app/pktgen-cmds.c.orig\n@@ -0,0 +1,2622 @@\n+/*-\n+ * Copyright (c) <2010>, Intel Corporation\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above copyright\n+ *   notice, this list of conditions and the following disclaimer in\n+ *   the documentation and/or other materials provided with the\n+ *   distribution.\n+ *\n+ * - Neither the name of Intel Corporation nor the names of its\n+ *   contributors may be used to endorse or promote products derived\n+ *   from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n+ * OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+/**\n+ * Copyright (c) <2010-2014>, Wind River Systems, Inc. All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without modification, are\n+ * permitted provided that the following conditions are met:\n+ *\n+ * 1) Redistributions of source code must retain the above copyright notice,\n+ * this list of conditions and the following disclaimer.\n+ *\n+ * 2) Redistributions in binary form must reproduce the above copyright notice,\n+ * this list of conditions and the following disclaimer in the documentation and/or\n+ * other materials provided with the distribution.\n+ *\n+ * 3) Neither the name of Wind River Systems nor the names of its contributors may be\n+ * used to endorse or promote products derived from this software without specific\n+ * prior written permission.\n+ *\n+ * 4) The screens displayed by the application must contain the copyright notice as defined\n+ * above and can not be removed without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+ *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\n+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+/* Created 2010 by Keith Wiles @ intel.com */\n+\n+#include \"pktgen-cmds.h\"\n+\n+#include \"pktgen-display.h\"\n+#include \"pktgen.h\"\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_save - Save a configuration as a startup script\n+ *\n+ * DESCRIPTION\n+ * Save a configuration as a startup script\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+int\n+pktgen_save(char *path)\n+{\n+\tport_info_t   *info;\n+\tpkt_seq_t     *pkt;\n+\trange_info_t  *range;\n+\tuint32_t flags;\n+\tchar buff[64];\n+\tFILE      *fd;\n+\tint i, j;\n+\tuint64_t lcore;\n+\tstruct ether_addr eaddr;\n+\n+\tfd = fopen(path, \"w\");\n+\tif (fd == NULL)\n+\t\treturn -1;\n+\n+\tfor (i = 0, lcore = 0; i < RTE_MAX_LCORE; i++)\n+\t\tif (rte_lcore_is_enabled(i) )\n+\t\t\tlcore |= (1 << i);\n+\n+\tfprintf(fd, \"#\\n# Pktgen - %s\\n\", pktgen_version());\n+\tfprintf(fd, \"# %s, %s\\n\\n\", wr_copyright_msg(), wr_powered_by());\n+\n+\t/* TODO: Determine DPDK arguments for rank and memory, default for now. */\n+\tfprintf(fd, \"# Command line arguments: (DPDK args are defaults)\\n\");\n+\tfprintf(fd,\n+\t        \"# %s -c %lx -n 3 -m 512 --proc-type %s -- \",\n+\t        pktgen.argv[0],\n+\t        lcore,\n+\t        (rte_eal_process_type() ==\n+\t         RTE_PROC_PRIMARY) ? \"primary\" : \"secondary\");\n+\tfor (i = 1; i < pktgen.argc; i++)\n+\t\tfprintf(fd, \"%s \", pktgen.argv[i]);\n+\tfprintf(fd, \"\\n\\n\");\n+\n+\tfprintf(fd,\n+\t        \"#######################################################################\\n\");\n+\tfprintf(fd, \"# Pktgen Configuration script information:\\n\");\n+\tfprintf(fd,\n+\t        \"#   GUI socket is %s\\n\",\n+\t        (pktgen.flags & ENABLE_GUI_FLAG) ? \"Enabled\" : \"Not Enabled\");\n+\tfprintf(fd, \"#   Flags %08x\\n\", pktgen.flags);\n+\tfprintf(fd, \"#   Number of ports: %d\\n\", pktgen.nb_ports);\n+\tfprintf(fd, \"#   Number ports per page: %d\\n\",\n+\t        pktgen.nb_ports_per_page);\n+\tfprintf(fd,\n+\t        \"#   Number descriptors: RX %d TX: %d\\n\",\n+\t        pktgen.nb_rxd,\n+\t        pktgen.nb_txd);\n+\tfprintf(fd, \"#   Promiscuous mode is %s\\n\\n\",\n+\t        (pktgen.flags & PROMISCUOUS_ON_FLAG) ? \"Enabled\" : \"Disabled\");\n+\n+#if 0\n+\tfprintf(fd, \"# Port Descriptions (-- = blacklisted port):\\n\");\n+\tfor (i = 0; i < RTE_MAX_ETHPORTS; i++)\n+\t\tif (pktgen.portdesc[i] && strlen((char *)pktgen.portdesc[i]) ) {\n+\t\t\tif ( (pktgen.enabled_port_mask & (1 << i)) == 0)\n+\t\t\t\tstrcpy(buff, \"--\");\n+\t\t\telse\n+\t\t\t\tstrcpy(buff, \"++\");\n+\n+\t\t\tfprintf(fd, \"#   %s %s\\n\", buff, pktgen.portdesc[i]);\n+\t\t}\n+\n+#endif\n+\tfprintf(fd,\n+\t        \"\\n#######################################################################\\n\");\n+\n+\tfprintf(fd, \"# Global configuration:\\n\");\n+\tuint16_t rows, cols;\n+\tpktgen_display_get_geometry(&rows, &cols);\n+\tfprintf(fd, \"geometry %dx%d\\n\", cols, rows);\n+\tfprintf(fd,\n+\t        \"mac_from_arp %s\\n\\n\",\n+\t        (pktgen.flags & MAC_FROM_ARP_FLAG) ? \"enable\" : \"disable\");\n+\n+\tfor (i = 0; i < RTE_MAX_ETHPORTS; i++) {\n+\t\tinfo = &pktgen.info[i];\n+\t\tpkt = &info->seq_pkt[SINGLE_PKT];\n+\t\trange = &info->range;\n+\n+\t\tif (info->tx_burst == 0)\n+\t\t\tcontinue;\n+\n+\t\tfprintf(fd,\n+\t\t        \"######################### Port %2d ##################################\\n\",\n+\t\t        i);\n+\t\tif (rte_atomic64_read(&info->transmit_count) == 0)\n+\t\t\tstrcpy(buff, \"Forever\");\n+\t\telse\n+\t\t\tsnprintf(buff, sizeof(buff), \"%ld\",\n+\t\t\t         rte_atomic64_read(&info->transmit_count));\n+\t\tfprintf(fd, \"#\\n\");\n+\t\tflags = rte_atomic32_read(&info->port_flags);\n+\t\tfprintf(fd,\n+\t\t        \"# Port: %2d, Burst:%3d, Rate:%3d%%, Flags:%08x, TX Count:%s\\n\",\n+\t\t        info->pid,\n+\t\t        info->tx_burst,\n+\t\t        info->tx_rate,\n+\t\t        flags,\n+\t\t        buff);\n+\t\tfprintf(fd, \"#           SeqCnt:%d, Prime:%d VLAN ID:%04x, \",\n+\t\t        info->seqCnt, info->prime_cnt, info->vlanid);\n+\t\tpktgen_link_state(info->pid, buff, sizeof(buff));\n+\t\tfprintf(fd, \"Link: %s\\n\", buff);\n+\n+\t\tfprintf(fd, \"#\\n# Set up the primary port information:\\n\");\n+\t\tfprintf(fd, \"set %d count %ld\\n\", info->pid,\n+\t\t        rte_atomic64_read(&info->transmit_count));\n+\t\tfprintf(fd,\n+\t\t        \"set %d size %d\\n\",\n+\t\t        info->pid,\n+\t\t        pkt->pktSize + FCS_SIZE);\n+\t\tfprintf(fd, \"set %d rate %d\\n\", info->pid, info->tx_rate);\n+\t\tfprintf(fd, \"set %d burst %d\\n\", info->pid, info->tx_burst);\n+\t\tfprintf(fd, \"set %d sport %d\\n\", info->pid, pkt->sport);\n+\t\tfprintf(fd, \"set %d dport %d\\n\", info->pid, pkt->dport);\n+\t\tfprintf(fd, \"set %d prime %d\\n\", info->pid, info->prime_cnt);\n+\t\tfprintf(fd, \"type %s %d\\n\",\n+\t\t        (pkt->ethType == ETHER_TYPE_IPv4) ? \"ipv4\" :\n+\t\t        (pkt->ethType == ETHER_TYPE_IPv6) ? \"ipv6\" :\n+\t\t        (pkt->ethType == ETHER_TYPE_VLAN) ? \"vlan\" :\n+\t\t        (pkt->ethType == ETHER_TYPE_ARP) ? \"arp\" : \"unknown\",\n+\t\t        i);\n+\t\tfprintf(fd, \"proto %s %d\\n\",\n+\t\t        (pkt->ipProto == PG_IPPROTO_TCP) ? \"tcp\" :\n+\t\t        (pkt->ipProto == PG_IPPROTO_ICMP) ? \"icmp\" : \"udp\", i);\n+\t\tfprintf(fd, \"set ip dst %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(pkt->ip_dst_addr.addr.ipv4.s_addr),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"set ip src %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(pkt->ip_src_addr.addr.ipv4.s_addr),\n+\t\t                   pkt->ip_mask));\n+\t\tfprintf(fd, \"set mac %d %s\\n\", info->pid,\n+\t\t        inet_mtoa(buff, sizeof(buff), &pkt->eth_dst_addr));\n+\t\tfprintf(fd, \"vlanid %d %d\\n\\n\", i, pkt->vlanid);\n+\n+\t\tfprintf(fd,\n+\t\t        \"pattern %d %s\\n\",\n+\t\t        i,\n+\t\t        (info->fill_pattern_type == ABC_FILL_PATTERN) ? \"abc\" :\n+\t\t        (info->fill_pattern_type == NO_FILL_PATTERN) ? \"none\" :\n+\t\t        (info->fill_pattern_type ==\n+\t\t         ZERO_FILL_PATTERN) ? \"zero\" : \"user\");\n+\t\tif (strlen(info->user_pattern) )\n+\t\t\tfprintf(fd,\n+\t\t\t        \"user.pattern %d %s\\n\",\n+\t\t\t        i,\n+\t\t\t        info->user_pattern);\n+\t\tfprintf(fd, \"\\n\");\n+\n+\t\tfprintf(fd,\n+\t\t        \"latency %d %s\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_LATENCY_PKTS) ? \"enable\" : \"disable\");\n+\n+\t\tfprintf(fd,\n+\t\t        \"mpls %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_MPLS_LABEL) ? \"en\" : \"dis\");\n+\t\tsprintf(buff, \"%x\", pkt->mpls_entry);\n+\t\tfprintf(fd, \"mpls_entry %d %s\\n\", i, buff);\n+\n+\t\tfprintf(fd,\n+\t\t        \"qinq %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_Q_IN_Q_IDS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"qinqids %d %d %d\\n\",\n+\t\t        i,\n+\t\t        pkt->qinq_outerid,\n+\t\t        pkt->qinq_innerid);\n+\n+\t\tfprintf(fd,\n+\t\t        \"gre %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_GRE_IPv4_HEADER) ? \"en\" : \"dis\");\n+\t\tfprintf(fd, \"gre_eth %d %sable\\n\", i,\n+\t\t        (flags & SEND_GRE_ETHER_HEADER) ? \"en\" : \"dis\");\n+\t\tfprintf(fd, \"gre_key %d %d\\n\", i, pkt->gre_key);\n+\n+\t\tfprintf(fd, \"#\\n# Port flag values:\\n\");\n+\t\tfprintf(fd, \"icmp.echo %d %sable\\n\", i,\n+\t\t        (flags & ICMP_ECHO_ENABLE_FLAG) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"pcap %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_PCAP_PKTS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"range %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_RANGE_PKTS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd, \"process %d %sable\\n\", i,\n+\t\t        (flags & PROCESS_INPUT_PKTS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"capture %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & CAPTURE_PKTS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"rxtap %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & PROCESS_RX_TAP_PKTS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"txtap %d %sable\\n\",\n+\t\t        i,\n+\t\t        (flags & PROCESS_TX_TAP_PKTS) ? \"en\" : \"dis\");\n+\t\tfprintf(fd,\n+\t\t        \"vlan %d %sable\\n\\n\",\n+\t\t        i,\n+\t\t        (flags & SEND_VLAN_ID) ? \"en\" : \"dis\");\n+\n+\t\tfprintf(fd, \"#\\n# Range packet information:\\n\");\n+\t\tfprintf(fd, \"src.mac start %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->src_mac, &eaddr)));\n+\t\tfprintf(fd, \"src.mac min %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->src_mac_min, &eaddr)));\n+\t\tfprintf(fd, \"src.mac max %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->src_mac_max, &eaddr)));\n+\t\tfprintf(fd, \"src.mac inc %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->src_mac_inc, &eaddr)));\n+\n+\t\tfprintf(fd, \"dst.mac start %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->dst_mac, &eaddr)));\n+\t\tfprintf(fd, \"dst.mac min %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->dst_mac_min, &eaddr)));\n+\t\tfprintf(fd, \"dst.mac max %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->dst_mac_max, &eaddr)));\n+\t\tfprintf(fd, \"dst.mac inc %d %s\\n\", i,\n+\t\t        inet_mtoa(buff, sizeof(buff),\n+\t\t                  inet_h64tom(range->dst_mac_inc, &eaddr)));\n+\n+\t\tfprintf(fd, \"\\n\");\n+\t\tfprintf(fd, \"src.ip start %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"src.ip min %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip_min),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"src.ip max %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip_max),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"src.ip inc %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip_inc),\n+\t\t                   0xFFFFFFFF));\n+\n+\t\tfprintf(fd, \"\\n\");\n+\t\tfprintf(fd, \"dst.ip start %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"dst.ip min %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip_min),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"dst.ip max %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip_max),\n+\t\t                   0xFFFFFFFF));\n+\t\tfprintf(fd, \"dst.ip inc %d %s\\n\", i,\n+\t\t        inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip_inc),\n+\t\t                   0xFFFFFFFF));\n+\n+\t\tfprintf(fd, \"\\n\");\n+\t\tfprintf(fd, \"src.port start %d %d\\n\", i, range->src_port);\n+\t\tfprintf(fd, \"src.port min %d %d\\n\", i, range->src_port_min);\n+\t\tfprintf(fd, \"src.port max %d %d\\n\", i, range->src_port_max);\n+\t\tfprintf(fd, \"src.port inc %d %d\\n\", i, range->src_port_inc);\n+\n+\t\tfprintf(fd, \"\\n\");\n+\t\tfprintf(fd, \"dst.port start %d %d\\n\", i, range->dst_port);\n+\t\tfprintf(fd, \"dst.port min %d %d\\n\", i, range->dst_port_min);\n+\t\tfprintf(fd, \"dst.port max %d %d\\n\", i, range->dst_port_max);\n+\t\tfprintf(fd, \"dst.port inc %d %d\\n\", i, range->dst_port_inc);\n+\n+\t\tfprintf(fd, \"\\n\");\n+\t\tfprintf(fd, \"vlan.id start %d %d\\n\", i, range->vlan_id);\n+\t\tfprintf(fd, \"vlan.id min %d %d\\n\", i, range->vlan_id_min);\n+\t\tfprintf(fd, \"vlan.id max %d %d\\n\", i, range->vlan_id_max);\n+\t\tfprintf(fd, \"vlan.id inc %d %d\\n\", i, range->vlan_id_inc);\n+\n+\t\tfprintf(fd, \"\\n\");\n+\t\tfprintf(fd,\n+\t\t        \"pkt.size start %d %d\\n\",\n+\t\t        i,\n+\t\t        range->pkt_size + FCS_SIZE);\n+\t\tfprintf(fd,\n+\t\t        \"pkt.size min %d %d\\n\",\n+\t\t        i,\n+\t\t        range->pkt_size_min + FCS_SIZE);\n+\t\tfprintf(fd,\n+\t\t        \"pkt.size max %d %d\\n\",\n+\t\t        i,\n+\t\t        range->pkt_size_max + FCS_SIZE);\n+\t\tfprintf(fd, \"pkt.size inc %d %d\\n\\n\", i, range->pkt_size_inc);\n+\n+\t\tfprintf(fd, \"#\\n# Set up the sequence data for the port.\\n\");\n+\t\tfprintf(fd, \"set %d seqCnt %d\\n\", info->pid, info->seqCnt);\n+\t\tfor (j = 0; j < info->seqCnt; j++) {\n+\t\t\tpkt = &info->seq_pkt[j];\n+\t\t\tfprintf(fd, \"seq %d %d %s \", j, i,\n+\t\t\t        inet_mtoa(buff,\n+\t\t\t                  sizeof(buff),\n+\t\t\t                  &pkt->eth_dst_addr));\n+\t\t\tfprintf(fd, \"%s \",\n+\t\t\t        inet_mtoa(buff,\n+\t\t\t                  sizeof(buff),\n+\t\t\t                  &pkt->eth_src_addr));\n+\t\t\tfprintf(fd, \"%s \",\n+\t\t\t        inet_ntop4(buff, sizeof(buff),\n+\t\t\t                   htonl(pkt->ip_dst_addr.addr.ipv4.s_addr),\n+\t\t\t                   0xFFFFFFFF));\n+\t\t\tfprintf(fd, \"%s \",\n+\t\t\t        inet_ntop4(buff, sizeof(buff),\n+\t\t\t                   htonl(pkt->ip_src_addr.addr.ipv4.s_addr),\n+\t\t\t                   pkt->ip_mask));\n+\t\t\tfprintf(fd,\n+\t\t\t        \"%d %d %s %s %d %d\\n\",\n+\t\t\t        pkt->sport,\n+\t\t\t        pkt->dport,\n+\t\t\t        (pkt->ethType == ETHER_TYPE_IPv4) ? \"ipv4\" :\n+\t\t\t        (pkt->ethType == ETHER_TYPE_IPv6) ? \"ipv6\" :\n+\t\t\t        (pkt->ethType == ETHER_TYPE_VLAN) ? \"vlan\" : \"Other\",\n+\t\t\t        (pkt->ipProto == PG_IPPROTO_TCP) ? \"tcp\" :\n+\t\t\t        (pkt->ipProto == PG_IPPROTO_ICMP) ? \"icmp\" : \"udp\",\n+\t\t\t        pkt->vlanid,\n+\t\t\t        pkt->pktSize + FCS_SIZE);\n+\t\t}\n+\n+\t\tif (pktgen.info[i].pcap) {\n+\t\t\tfprintf(fd, \"#\\n# PCAP port %d\\n\", i);\n+\t\t\tfprintf(fd,\n+\t\t\t        \"#    Packet count: %d\\n\",\n+\t\t\t        pktgen.info[i].pcap->pkt_count);\n+\t\t\tfprintf(fd,\n+\t\t\t        \"#    Filename    : %s\\n\",\n+\t\t\t        pktgen.info[i].pcap->filename);\n+\t\t}\n+\t\tfprintf(fd, \"\\n\");\n+\t}\n+\tfprintf(fd,\n+\t        \"################################ Done #################################\\n\");\n+\n+\tfclose(fd);\n+\treturn 0;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_port_transmitting - Is the port transmitting packets?\n+ *\n+ * DESCRIPTION\n+ * Is the port transmitting packets.\n+ *\n+ * RETURNS: 1 for yes and 0 for no.\n+ *\n+ * SEE ALSO:\n+ */\n+\n+int\n+pktgen_port_transmitting(int port)\n+{\n+\treturn rte_atomic32_read(&pktgen.info[port].port_flags) &\n+\t       SENDING_PACKETS;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_link_state - Get the ASCII string for the port state.\n+ *\n+ * DESCRIPTION\n+ * Return the port state string for a given port.\n+ *\n+ * RETURNS: String pointer to link state\n+ *\n+ * SEE ALSO:\n+ */\n+\n+char *\n+pktgen_link_state(int port, char *buff, int len)\n+{\n+\tport_info_t *info = &pktgen.info[port];\n+\n+\tif (info->link.link_status)\n+\t\tsnprintf(buff, len, \"<UP-%u-%s>\",\n+\t\t         (uint32_t)info->link.link_speed,\n+\t\t         (info->link.link_duplex ==\n+\t\t          ETH_LINK_FULL_DUPLEX) ? (\"FD\") : (\"HD\"));\n+\telse\n+\t\tsnprintf(buff, len, \"<--Down-->\");\n+\n+\treturn buff;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_transmit_count_rate - Get a string for the current transmit count and rate\n+ *\n+ * DESCRIPTION\n+ * Current value of the transmit count/%rate as a string.\n+ *\n+ * RETURNS: String pointer to transmit count/%rate.\n+ *\n+ * SEE ALSO:\n+ */\n+\n+char *\n+pktgen_transmit_count_rate(int port, char *buff, int len)\n+{\n+\tport_info_t *info = &pktgen.info[port];\n+\n+\tif (rte_atomic64_read(&info->transmit_count) == 0)\n+\t\tsnprintf(buff, len, \"Forever /%4d%%\", info->tx_rate);\n+\telse\n+\t\tsnprintf(buff, len, \"%ld /%4d%%\",\n+\t\t         rte_atomic64_read(&info->transmit_count),\n+\t\t         info->tx_rate);\n+\n+\treturn buff;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_port_sizes - Current stats for all port sizes\n+ *\n+ * DESCRIPTION\n+ * Structure returned with all of the counts for each port size.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+int\n+pktgen_port_sizes(int port, port_sizes_t *psizes)\n+{\n+\tport_info_t *info = &pktgen.info[port];\n+\n+\t*psizes = info->sizes;\n+\treturn 0;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_pkt_stats - Get the packet stats structure.\n+ *\n+ * DESCRIPTION\n+ * Return the packet statistics values.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+int\n+pktgen_pkt_stats(int port, pkt_stats_t *pstats)\n+{\n+\tport_info_t *info = &pktgen.info[port];\n+\n+\t*pstats = info->stats;\n+\treturn 0;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_port_stats - Get the port or rate stats for a given port\n+ *\n+ * DESCRIPTION\n+ * Get the ports or rate stats from a given port.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+int\n+pktgen_port_stats(int port, const char *name, eth_stats_t *pstats)\n+{\n+\tport_info_t *info = &pktgen.info[port];\n+\n+\tif (strcmp(name, \"port\") == 0)\n+\t\t*pstats = info->port_stats;\n+\telse if (strcmp(name, \"rate\") == 0)\n+\t\t*pstats = info->rate_stats;\n+\n+\treturn 0;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_flags_string - Return the flags string for display\n+ *\n+ * DESCRIPTION\n+ * Return the current flags string for display for a port.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+char *\n+pktgen_flags_string(port_info_t *info)\n+{\n+\tstatic char buff[32];\n+\tuint32_t flags = rte_atomic32_read(&info->port_flags);\n+\n+\tsnprintf(buff, sizeof(buff), \"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\",\n+\t         (pktgen.flags & PROMISCUOUS_ON_FLAG) ? 'P' : '-',\n+\t         (flags & ICMP_ECHO_ENABLE_FLAG) ? 'E' : '-',\n+\t         (flags & SEND_ARP_REQUEST) ? 'A' : '-',\n+\t         (flags & SEND_GRATUITOUS_ARP) ? 'G' : '-',\n+\t         (flags & SEND_PCAP_PKTS) ? 'p' : '-',\n+\t         (flags & SEND_SEQ_PKTS) ? 'S' : '-',\n+\t         (flags & SEND_RANGE_PKTS) ? 'R' : '-',\n+\t         (flags & PROCESS_INPUT_PKTS) ? 'I' : '-',\n+\t         \"-rt*\"[(flags & (PROCESS_RX_TAP_PKTS | PROCESS_TX_TAP_PKTS)) >>\n+\t                9],\n+\t         (flags & SEND_LATENCY_PKTS) ? 'L' : '-',\n+\t         (flags & SEND_VLAN_ID) ? 'V' :\n+\t         (flags & SEND_MPLS_LABEL) ? 'M' :\n+\t         (flags & SEND_Q_IN_Q_IDS) ? 'Q' : '-',\n+\t         (flags & PROCESS_GARP_PKTS) ? 'g' : '-',\n+\t         (flags & SEND_GRE_IPv4_HEADER) ? 'g' :\n+\t         (flags & SEND_GRE_ETHER_HEADER) ? 'G' : '-',\n+\t         (flags & CAPTURE_PKTS) ? 'C' : '-',\n+\t         (flags & SEND_RANDOM_PKTS) ? 'R' : '-');\n+\n+\treturn buff;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_redisplay - Redisplay the screen or clear the screen.\n+ *\n+ * DESCRIPTION\n+ * Redisplay the screen or clear the screen based on flag.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_redisplay(int cls_flag)\n+{\n+\tif (wr_scrn_is_paused() )\n+\t\treturn;\n+\n+\twr_scrn_pause();\n+\tif (cls_flag) {\n+\t\twr_scrn_cls();\n+\t\twr_scrn_pos(100, 1);\n+\t}\n+\tpktgen.flags |= PRINT_LABELS_FLAG;\n+\twr_scrn_resume();\n+\n+\tpktgen_page_display(NULL, NULL);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_update_display - Update the display, but do not clear screen.\n+ *\n+ * DESCRIPTION\n+ * Update the display, but do not clear the screen.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_update_display(void)\n+{\n+\tpktgen_redisplay(0);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_page_size - Set the number of ports per page.\n+ *\n+ * DESCRIPTION\n+ * Set the max number of ports per page.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_page_size(uint32_t page_size)\n+{\n+\tif ( (page_size > 0) && (page_size <= pktgen.nb_ports) &&\n+\t     (page_size <= 6) ) {\n+\t\tpktgen.nb_ports_per_page = page_size;\n+\t\tpktgen.ending_port = pktgen.starting_port + page_size;\n+\t\tif (pktgen.ending_port >=\n+\t\t    (pktgen.starting_port + pktgen.nb_ports) )\n+\t\t\tpktgen.ending_port =\n+\t\t\t        (pktgen.starting_port + pktgen.nb_ports);\n+\t\tpktgen_redisplay(1);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_screen - Enable or Disable screen updates.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable screen updates.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_screen(const char *onOff)\n+{\n+\tuint16_t rows;\n+\n+\tpktgen_display_get_geometry(&rows, NULL);\n+\n+\tif (parseState(onOff) == DISABLE_STATE) {\n+\t\tif (!wr_scrn_is_paused() ) {\n+\t\t\twr_scrn_pause();\n+\t\t\twr_scrn_cls();\n+\t\t\twr_scrn_setw(1);\n+\t\t\twr_scrn_pos(100, 1);\n+\t\t}\n+\t} else {\n+\t\twr_scrn_cls();\n+\t\twr_scrn_pos(100, 1);\n+\t\twr_scrn_setw(pktgen.last_row + 1);\n+\t\twr_scrn_resume();\n+\t\tpktgen_redisplay(1);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_port_number - Set the current port number for sequence and range pages\n+ *\n+ * DESCRIPTION\n+ * Set the current port number for sequence and range pages.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_port_number(uint32_t port_number)\n+{\n+\tif (port_number <= pktgen.nb_ports) {\n+\t\tpktgen.portNum = port_number;\n+\t\tpktgen_redisplay(1);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_icmp_echo - Set the ICMP echo response flag on a port\n+ *\n+ * DESCRIPTION\n+ * Enable or disable the ICMP echo response flags for the given ports.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_icmp_echo(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE)\n+\t\tpktgen_set_port_flags(info, ICMP_ECHO_ENABLE_FLAG);\n+\telse\n+\t\tpktgen_clr_port_flags(info, ICMP_ECHO_ENABLE_FLAG);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_rx_tap - Enable or disable the Rx TAP interface\n+ *\n+ * DESCRIPTION\n+ * Create and setup the Rx TAP interface.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_rx_tap(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tstruct ifreq ifr;\n+\t\tint sockfd, i;\n+\t\tstatic const char *tapdevs[] =\n+\t\t{ \"/dev/net/tun\", \"/dev/tun\", NULL };\n+\n+\t\tfor (i = 0; tapdevs[i]; i++)\n+\t\t\tif ( (info->rx_tapfd = open(tapdevs[i], O_RDWR)) >= 0)\n+\t\t\t\tbreak;\n+\t\tif (tapdevs[i] == NULL) {\n+\t\t\tpktgen_log_error(\"Unable to create TUN/TAP interface\");\n+\t\t\treturn;\n+\t\t}\n+\t\tmemset(&ifr, 0, sizeof(struct ifreq));\n+\n+\t\tifr.ifr_flags = IFF_TAP | IFF_NO_PI;\n+\n+\t\tsnprintf(ifr.ifr_name, IFNAMSIZ, \"%s%d\", \"pg_rxtap\", info->pid);\n+\t\tif (ioctl(info->rx_tapfd, TUNSETIFF, (void *)&ifr) < 0) {\n+\t\t\tpktgen_log_error(\"Unable to set TUNSETIFF for %s\",\n+\t\t\t                 ifr.ifr_name);\n+\t\t\tclose(info->rx_tapfd);\n+\t\t\tinfo->rx_tapfd = 0;\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tsockfd = socket(AF_INET, SOCK_DGRAM, 0);\n+\n+\t\tifr.ifr_flags = IFF_UP | IFF_RUNNING;\n+\t\tif (ioctl(sockfd, SIOCSIFFLAGS, (void *)&ifr) < 0) {\n+\t\t\tpktgen_log_error(\"Unable to set SIOCSIFFLAGS for %s\",\n+\t\t\t                 ifr.ifr_name);\n+\t\t\tclose(sockfd);\n+\t\t\tclose(info->rx_tapfd);\n+\t\t\tinfo->rx_tapfd = 0;\n+\t\t\treturn;\n+\t\t}\n+\t\tclose(sockfd);\n+\t\tpktgen_set_port_flags(info, PROCESS_RX_TAP_PKTS);\n+\t} else {\n+\t\tif (rte_atomic32_read(&info->port_flags) &\n+\t\t    PROCESS_RX_TAP_PKTS) {\n+\t\t\tclose(info->rx_tapfd);\n+\t\t\tinfo->rx_tapfd = 0;\n+\t\t}\n+\t\tpktgen_clr_port_flags(info, PROCESS_RX_TAP_PKTS);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_tx_tap - Enable or disable the Tx TAP interface\n+ *\n+ * DESCRIPTION\n+ * Create and setup the Tx TAP interface.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_tx_tap(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tstruct ifreq ifr;\n+\t\tint sockfd, i;\n+\t\tstatic const char *tapdevs[] =\n+\t\t{ \"/dev/net/tun\", \"/dev/tun\", NULL };\n+\n+\t\tfor (i = 0; tapdevs[i]; i++)\n+\t\t\tif ( (info->tx_tapfd = open(tapdevs[i], O_RDWR)) >= 0)\n+\t\t\t\tbreak;\n+\t\tif (tapdevs[i] == NULL) {\n+\t\t\tpktgen_log_error(\"Unable to create TUN/TAP interface.\");\n+\t\t\treturn;\n+\t\t}\n+\t\tmemset(&ifr, 0, sizeof(struct ifreq));\n+\n+\t\tifr.ifr_flags = IFF_TAP | IFF_NO_PI;\n+\n+\t\tsnprintf(ifr.ifr_name, IFNAMSIZ, \"%s%d\", \"pg_txtap\", info->pid);\n+\t\tif (ioctl(info->tx_tapfd, TUNSETIFF, (void *)&ifr) < 0) {\n+\t\t\tpktgen_log_error(\"Unable to set TUNSETIFF for %s\",\n+\t\t\t                 ifr.ifr_name);\n+\t\t\tclose(info->tx_tapfd);\n+\t\t\tinfo->tx_tapfd = 0;\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tsockfd = socket(AF_INET, SOCK_DGRAM, 0);\n+\n+\t\tifr.ifr_flags = IFF_UP | IFF_RUNNING;\n+\t\tif (ioctl(sockfd, SIOCSIFFLAGS, (void *)&ifr) < 0) {\n+\t\t\tpktgen_log_error(\"Unable to set SIOCSIFFLAGS for %s\",\n+\t\t\t                 ifr.ifr_name);\n+\t\t\tclose(sockfd);\n+\t\t\tclose(info->tx_tapfd);\n+\t\t\tinfo->tx_tapfd = 0;\n+\t\t\treturn;\n+\t\t}\n+\t\tclose(sockfd);\n+\t\tpktgen_set_port_flags(info, PROCESS_TX_TAP_PKTS);\n+\t} else {\n+\t\tif (rte_atomic32_read(&info->port_flags) &\n+\t\t    PROCESS_TX_TAP_PKTS) {\n+\t\t\tclose(info->tx_tapfd);\n+\t\t\tinfo->tx_tapfd = 0;\n+\t\t}\n+\t\tpktgen_clr_port_flags(info, PROCESS_TX_TAP_PKTS);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_mac_from_arp - Enable or disable getting MAC from ARP requests.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable getting the MAC address from the ARP request packets.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_mac_from_arp(uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE)\n+\t\tpktgen.flags |= MAC_FROM_ARP_FLAG;\n+\telse\n+\t\tpktgen.flags &= ~MAC_FROM_ARP_FLAG;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_random - Enable/disable random bitfield mode\n+ *\n+ * DESCRIPTION\n+ * Enable/disable random bitfield mode\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_random(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE)\n+\t\tpktgen_set_port_flags(info, SEND_RANDOM_PKTS);\n+\telse\n+\t\tpktgen_clr_port_flags(info, SEND_RANDOM_PKTS);\n+}\n+\n+/*\n+ * Local wrapper function to test mp is NULL and return or continue\n+ * to call rte_mempool_dump() routine.\n+ */\n+static void\n+__mempool_dump(FILE *f, struct rte_mempool *mp) {\n+\tif (mp == NULL)\n+\t\treturn;\n+\trte_mempool_dump(f, mp);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_mempool_dump - Display the mempool information\n+ *\n+ * DESCRIPTION\n+ * Dump out the mempool information.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_mempool_dump(port_info_t *info, char *name)\n+{\n+\tint all;\n+\tuint16_t q;\n+\n+\tall = !strcmp(name, \"all\");\n+\n+\tif (info->q[0].tx_mp == NULL)\n+\t\treturn;\n+\n+\tfor (q = 0; q < wr_get_port_rxcnt(pktgen.l2p, info->pid); q++)\n+\t\tif (all || !strcmp(name, \"rx\") )\n+\t\t\trte_mempool_dump(stdout, info->q[q].rx_mp);\n+\tfor (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++) {\n+\t\tif (all ||\n+\t\t    (!strcmp(name,\n+\t\t             \"tx\") &&\n+\t\t     (q < wr_get_port_txcnt(pktgen.l2p, info->pid))) )\n+\t\t\t__mempool_dump(stdout, info->q[q].tx_mp);\n+\t\tif (all || !strcmp(name, \"range\") )\n+\t\t\t__mempool_dump(stdout, info->q[q].range_mp);\n+\t\tif (all || !strcmp(name, \"seq\") )\n+\t\t\t__mempool_dump(stdout, info->q[q].seq_mp);\n+\t\tif (all || !strcmp(name, \"arp\") )\n+\t\t\t__mempool_dump(stdout, info->q[q].special_mp);\n+\t\tif (all || !strcmp(name, \"pcap\") )\n+\t\t\t__mempool_dump(stdout, info->q[q].pcap_mp);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_start_transmitting - Start a port transmitting packets.\n+ *\n+ * DESCRIPTION\n+ * Start the given ports sending packets.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_start_transmitting(port_info_t *info)\n+{\n+\tuint8_t q;\n+\n+\tif (!(rte_atomic32_read(&info->port_flags) & SENDING_PACKETS) ) {\n+\t\tfor (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)\n+\t\t\tpktgen_set_q_flags(info, q, CLEAR_FAST_ALLOC_FLAG);\n+\n+\t\trte_atomic64_set(&info->current_tx_count,\n+\t\t                 rte_atomic64_read(&info->transmit_count));\n+\n+\t\tpktgen_set_port_flags(info, SENDING_PACKETS);\n+\n+\t\tif (rte_atomic64_read(&info->current_tx_count) == 0)\n+\t\t\tpktgen_set_port_flags(info, SEND_FOREVER);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_stop_transmitting - Stop port transmitting packets.\n+ *\n+ * DESCRIPTION\n+ * Stop the given ports from sending traffic.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_stop_transmitting(port_info_t *info)\n+{\n+\tuint8_t q;\n+\n+\tif (rte_atomic32_read(&info->port_flags) & SENDING_PACKETS) {\n+\t\tpktgen_clr_port_flags(info, (SENDING_PACKETS | SEND_FOREVER));\n+\t\tfor (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)\n+\t\t\tpktgen_set_q_flags(info, q, DO_TX_FLUSH);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_prime_ports - Send a small number of packets to setup forwarding tables\n+ *\n+ * DESCRIPTION\n+ * Send a small number of packets from a port to setup the forwarding tables in\n+ * the device under test.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_prime_ports(port_info_t *info)\n+{\n+\tuint8_t q;\n+\n+\tfor (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)\n+\t\tpktgen_set_q_flags(info, q, CLEAR_FAST_ALLOC_FLAG);\n+\trte_atomic64_set(&info->current_tx_count, info->prime_cnt);\n+\tpktgen_set_port_flags(info, SENDING_PACKETS);\n+\trte_delay_ms(300);\n+\tfor (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)\n+\t\tpktgen_set_q_flags(info, q, DO_TX_FLUSH);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_proto - Set up the protocol type for a port/packet.\n+ *\n+ * DESCRIPTION\n+ * Setup all single packets with a protocol types with the port list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_proto(port_info_t *info, char type)\n+{\n+\tinfo->seq_pkt[SINGLE_PKT].ipProto = (type == 'u') ? PG_IPPROTO_UDP :\n+\t        (type == 'i') ? PG_IPPROTO_ICMP :\n+\t        (type == 't') ? PG_IPPROTO_TCP :\n+\t\t/* TODO print error: unknown type */ PG_IPPROTO_TCP;\n+\n+\t/* ICMP only works on IPv4 packets. */\n+\tif (type == 'i')\n+\t\tinfo->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;\n+\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_proto_range - Set up the protocol type for a port/packet.\n+ *\n+ * DESCRIPTION\n+ * Setup all range packets with a protocol types with the port list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_proto_range(port_info_t *info, char type)\n+{\n+\tinfo->seq_pkt[RANGE_PKT].ipProto = (type == 'u') ? PG_IPPROTO_UDP :\n+\t        (type == 'i') ? PG_IPPROTO_ICMP :\n+\t        (type == 't') ? PG_IPPROTO_TCP :\n+\t\t/* TODO print error: unknown type */ PG_IPPROTO_TCP;\n+\tinfo->range.ip_proto = info->seq_pkt[RANGE_PKT].ipProto;\n+\n+\t/* ICMP only works on IPv4 packets. */\n+\tif (type == 'i')\n+\t\tinfo->seq_pkt[RANGE_PKT].ethType = ETHER_TYPE_IPv4;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_pcap_enable_disable - Enable or disable PCAP sending of packets.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable PCAP packet sending.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_pcap_enable_disable(port_info_t *info, char *str)\n+{\n+\tif ( (info->pcap != NULL) && (info->pcap->pkt_count != 0) ) {\n+\t\tif (parseState(str) == ENABLE_STATE) {\n+\t\t\tpktgen_clr_port_flags(info, SEND_RANGE_PKTS);\n+\t\t\tpktgen_clr_port_flags(info, SEND_SEQ_PKTS);\n+\t\t\tpktgen_set_port_flags(info, SEND_PCAP_PKTS);\n+\t\t} else\n+\t\t\tpktgen_clr_port_flags(info, SEND_PCAP_PKTS);\n+\t\tpktgen_packet_rate(info);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_pcap_filter - Compile a PCAP filter for a portlist\n+ *\n+ * DESCRIPTION\n+ * Compile a pcap filter for a portlist\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_pcap_filter(port_info_t *info, char *str)\n+{\n+\tpcap_t *pc = pcap_open_dead(DLT_EN10MB, 65535);\n+\n+\tinfo->pcap_result = pcap_compile(pc,\n+\t                                 &info->pcap_program,\n+\t                                 str,\n+\t                                 1,\n+\t                                 PCAP_NETMASK_UNKNOWN);\n+\n+\tpcap_close(pc);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_blink_enable_disable - Enable or disable a port from blinking.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable the given ports from blinking.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_blink_enable_disable(port_info_t *info, char *str)\n+{\n+\tif (parseState(str) == ENABLE_STATE)\n+\t\tpktgen.blinklist |= (1 << info->pid);\n+\telse {\n+\t\tpktgen.blinklist &= ~(1 << info->pid);\n+\t\trte_eth_led_on(info->pid);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_process_enable_disable - Enable or disable input packet processing.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable input packet processing of ICMP, ARP, ...\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_process_enable_disable(port_info_t *info, char *str)\n+{\n+\tif (parseState(str) == ENABLE_STATE)\n+\t\tpktgen_set_port_flags(info, PROCESS_INPUT_PKTS);\n+\telse\n+\t\tpktgen_clr_port_flags(info, PROCESS_INPUT_PKTS);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_garp_enable_disable - Enable or disable GARP packet processing.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable GARP packet processing of ICMP, ARP, ...\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_garp_enable_disable(port_info_t *info, char *str)\n+{\n+\tif (parseState(str) == ENABLE_STATE)\n+\t\tpktgen_set_port_flags(info,\n+\t\t                      PROCESS_GARP_PKTS | PROCESS_INPUT_PKTS);\n+\telse\n+\t\tpktgen_clr_port_flags(info,\n+\t\t                      PROCESS_GARP_PKTS | PROCESS_INPUT_PKTS);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_pkt_type_range - Set the packet type value for range packets.\n+ *\n+ * DESCRIPTION\n+ * Set the packet type value for the given port list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_pkt_type_range(port_info_t *info, const char *type)\n+{\n+\tinfo->seq_pkt[RANGE_PKT].ethType = (type[0] == 'a') ? ETHER_TYPE_ARP :\n+\t        (type[3] == '4') ? ETHER_TYPE_IPv4 :\n+\t        (type[3] == '6') ? ETHER_TYPE_IPv6 :\n+\t\t/* TODO print error: unknown type */ ETHER_TYPE_IPv4;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_pkt_type - Set the packet type value.\n+ *\n+ * DESCRIPTION\n+ * Set the packet type value for the given port list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_pkt_type(port_info_t *info, const char *type)\n+{\n+\tinfo->seq_pkt[SINGLE_PKT].ethType = (type[0] == 'a') ? ETHER_TYPE_ARP  :\n+\t        (type[3] == '4') ? ETHER_TYPE_IPv4 :\n+\t        (type[3] == '6') ? ETHER_TYPE_IPv6 :\n+\t\t/* TODO print error: unknown type */ ETHER_TYPE_IPv4;\n+\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_vlan - Set the port to send a VLAN ID\n+ *\n+ * DESCRIPTION\n+ * Set the given port list to send VLAN ID packets.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_vlan(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tpktgen_clr_port_flags(info, SEND_MPLS_LABEL);\n+\t\tpktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);\n+\t\tpktgen_set_port_flags(info, SEND_VLAN_ID);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_VLAN_ID);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_vlanid - Set the port VLAN ID value\n+ *\n+ * DESCRIPTION\n+ * Set the given port list with the given VLAN ID.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_vlanid(port_info_t *info, uint16_t vlanid)\n+{\n+\tinfo->vlanid = vlanid;\n+\tinfo->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_mpls - Set the port to send a mpls ID\n+ *\n+ * DESCRIPTION\n+ * Set the given port list to send mpls ID packets.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_mpls(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tpktgen_clr_port_flags(info, SEND_VLAN_ID);\n+\t\tpktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);\n+\t\tpktgen_set_port_flags(info, SEND_MPLS_LABEL);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_MPLS_LABEL);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_mpls_entry - Set the port MPLS entry value\n+ *\n+ * DESCRIPTION\n+ * Set the given port list with the given MPLS entry.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_mpls_entry(port_info_t *info, uint32_t mpls_entry)\n+{\n+\tinfo->mpls_entry = mpls_entry;\n+\tinfo->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_qinq - Set the port to send a Q-in-Q header\n+ *\n+ * DESCRIPTION\n+ * Set the given port list to send Q-in-Q ID packets.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_qinq(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tpktgen_clr_port_flags(info, SEND_VLAN_ID);\n+\t\tpktgen_clr_port_flags(info, SEND_MPLS_LABEL);\n+\t\tpktgen_set_port_flags(info, SEND_Q_IN_Q_IDS);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_qinqids - Set the port Q-in-Q ID values\n+ *\n+ * DESCRIPTION\n+ * Set the given port list with the given Q-in-Q ID's.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_qinqids(port_info_t *info, uint16_t outerid, uint16_t innerid)\n+{\n+\tinfo->qinq_outerid = outerid;\n+\tinfo->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;\n+\tinfo->qinq_innerid = innerid;\n+\tinfo->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_gre - Set the port to send GRE with IPv4 payload\n+ *\n+ * DESCRIPTION\n+ * Set the given port list to send GRE with IPv4 payload\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_gre(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tpktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);\n+\t\tpktgen_set_port_flags(info, SEND_GRE_IPv4_HEADER);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_gre_eth - Set the port to send GRE with Ethernet payload\n+ *\n+ * DESCRIPTION\n+ * Set the given port list to send GRE with Ethernet payload\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_gre_eth(port_info_t *info, uint32_t onOff)\n+{\n+\tif (onOff == ENABLE_STATE) {\n+\t\tpktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);\n+\t\tpktgen_set_port_flags(info, SEND_GRE_ETHER_HEADER);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_gre_key - Set the port GRE key\n+ *\n+ * DESCRIPTION\n+ * Set the given port list with the given GRE key.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_gre_key(port_info_t *info, uint32_t gre_key)\n+{\n+\tinfo->gre_key = gre_key;\n+\tinfo->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_clear_stats - Clear a given port list of stats.\n+ *\n+ * DESCRIPTION\n+ * Clear the given port list of all statistics.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_clear_stats(port_info_t *info)\n+{\n+\tmemset(&info->sizes, 0, sizeof(port_sizes_t));\n+\tmemset(&info->port_stats, 0, sizeof(eth_stats_t));\n+\tmemset(&info->rate_stats, 0, sizeof(eth_stats_t));\n+\n+\trte_eth_stats_get(info->pid, &info->init_stats);\n+    pktgen.max_total_ipackets   = 0;\n+    pktgen.max_total_opackets   = 0;\n+    info->max_ipackets          = 0;\n+    info->max_opackets          = 0;\n+\tinfo->stats.dropped_pkts    = 0;\n+\tinfo->stats.arp_pkts        = 0;\n+\tinfo->stats.echo_pkts       = 0;\n+\tinfo->stats.ip_pkts         = 0;\n+\tinfo->stats.ipv6_pkts       = 0;\n+\tinfo->stats.vlan_pkts       = 0;\n+\tinfo->stats.unknown_pkts    = 0;\n+\tinfo->stats.tx_failed       = 0;\n+\n+\tmemset(&pktgen.cumm_rate_totals, 0, sizeof(eth_stats_t));\n+\n+\tpktgen_update_display();\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_cls - Clear the screen.\n+ *\n+ * DESCRIPTION\n+ * Clear the screen and redisplay the data.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_cls(void)\n+{\n+\tif (wr_scrn_is_paused() ) {\n+\t\twr_scrn_cls();\n+\t\twr_scrn_pos(100, 1);\n+\t} else\t/* Update the display quickly. */\n+\t\tpktgen_redisplay(1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_update - Update the screen information\n+ *\n+ * DESCRIPTION\n+ * Update the screen information\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_update(void)\n+{\n+\tpktgen_page_display(NULL, NULL);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_port_defaults - Set all ports back to the default values.\n+ *\n+ * DESCRIPTION\n+ * Reset the ports back to the defaults.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_port_defaults(uint32_t pid, uint8_t seq)\n+{\n+\tport_info_t *info = &pktgen.info[pid];\n+\tpkt_seq_t *pkt = &info->seq_pkt[seq];\n+\tport_info_t *dst_info;\n+\n+\tpkt->pktSize            = MIN_PKT_SIZE;\n+\tpkt->sport              = DEFAULT_SRC_PORT;\n+\tpkt->dport              = DEFAULT_DST_PORT;\n+\tpkt->ipProto            = PG_IPPROTO_TCP;\n+\tpkt->ethType            = ETHER_TYPE_IPv4;\n+\tpkt->vlanid             = DEFAULT_VLAN_ID;\n+\n+\trte_atomic64_set(&info->transmit_count, DEFAULT_TX_COUNT);\n+\trte_atomic64_init(&info->current_tx_count);\n+\tinfo->tx_rate           = DEFAULT_TX_RATE;\n+\tinfo->tx_burst          = DEFAULT_PKT_BURST;\n+\tinfo->vlanid            = DEFAULT_VLAN_ID;\n+\tinfo->seqCnt            = 0;\n+\tinfo->seqIdx            = 0;\n+\tinfo->prime_cnt         = DEFAULT_PRIME_COUNT;\n+\tinfo->delta             = 0;\n+\n+\tpktgen_packet_rate(info);\n+\n+\tpkt->ip_mask = DEFAULT_NETMASK;\n+\tif ( (pid & 1) == 0) {\n+\t\tpkt->ip_src_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | (pid << 8) | 1;\n+\t\tpkt->ip_dst_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | ((pid + 1) << 8) | 1;\n+\t\tdst_info = info + 1;\n+\t} else {\n+\t\tpkt->ip_src_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | (pid << 8) | 1;\n+\t\tpkt->ip_dst_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | ((pid - 1) << 8) | 1;\n+\t\tdst_info = info - 1;\n+\t}\n+\n+\tif (dst_info->seq_pkt != NULL)\n+\t\tether_addr_copy(&dst_info->seq_pkt[SINGLE_PKT].eth_src_addr,\n+\t\t                &pkt->eth_dst_addr);\n+\telse\n+\t\tmemset(&pkt->eth_dst_addr, 0, sizeof(pkt->eth_dst_addr));\n+\n+\tpktgen_packet_ctor(info, seq, -1);\n+\n+\tpktgen.flags    |= PRINT_LABELS_FLAG;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_ping4 - Send a IPv4 ICMP echo request.\n+ *\n+ * DESCRIPTION\n+ * Send a IPv4 ICMP echo request packet.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_ping4(port_info_t *info)\n+{\n+\tmemcpy(&info->seq_pkt[PING_PKT],\n+\t       &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));\n+\tinfo->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;\n+\tpktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);\n+\tpktgen_set_port_flags(info, SEND_PING4_REQUEST);\n+}\n+\n+#ifdef INCLUDE_PING6\n+/**************************************************************************//**\n+ *\n+ * pktgen_ping6 - Send a IPv6 ICMP echo request packet.\n+ *\n+ * DESCRIPTION\n+ * Send a IPv6 ICMP echo request packet for the given ports.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_ping6(port_info_t *info)\n+{\n+\tmemcpy(&info->pkt[PING_PKT],\n+\t       &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));\n+\tinfo->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;\n+\tpktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);\n+\tpktgen_set_port_flags(info, SEND_PING6_REQUEST);\n+}\n+\n+#endif\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_reset - Reset all ports to the default state\n+ *\n+ * DESCRIPTION\n+ * Reset all ports to the default state.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_reset(port_info_t *info)\n+{\n+\tuint32_t s;\n+\n+\tif (info == NULL)\n+\t\tinfo = &pktgen.info[0];\n+\n+\tpktgen_stop_transmitting(info);\n+\n+\tpktgen.flags &= ~MAC_FROM_ARP_FLAG;\n+\n+\t/* Make sure the port is active and enabled. */\n+\tif (info->seq_pkt) {\n+\t\tinfo->seq_pkt[SINGLE_PKT].pktSize = MIN_PKT_SIZE;\n+\n+\t\tfor (s = 0; s < NUM_TOTAL_PKTS; s++)\n+\t\t\tpktgen_port_defaults(info->pid, s);\n+\n+\t\tpktgen_range_setup(info);\n+\t\tpktgen_clear_stats(info);\n+\t}\n+\n+\tpktgen.flags &= ~PRINT_LABELS_FLAG;\n+\tpktgen_update_display();\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_port_restart - Reset all ports\n+ *\n+ * DESCRIPTION\n+ * Reset all ports\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_port_restart(port_info_t *info)\n+{\n+\tif (info == NULL)\n+\t\tinfo = &pktgen.info[0];\n+\n+\tpktgen_stop_transmitting(info);\n+\n+\trte_delay_ms(10);\n+\n+\t/* Stop and start the device to flush TX and RX buffers from the device rings. */\n+\trte_eth_dev_stop(info->pid);\n+\n+\trte_delay_us(250);\n+\n+\trte_eth_dev_start(info->pid);\n+\n+\tpktgen.flags &= ~PRINT_LABELS_FLAG;\n+\tpktgen_update_display();\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_tx_count - Set the number of packets to transmit on a port.\n+ *\n+ * DESCRIPTION\n+ * Set the transmit count for all ports in the list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_tx_count(port_info_t *info, uint32_t cnt)\n+{\n+\trte_atomic64_set(&info->transmit_count, cnt);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_port_seqCnt - Set the sequence count for a port\n+ *\n+ * DESCRIPTION\n+ * Set a sequence count of packets for all ports in the list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_port_seqCnt(port_info_t *info, uint32_t cnt)\n+{\n+\tif (cnt > NUM_SEQ_PKTS)\n+\t\tcnt = NUM_SEQ_PKTS;\n+\n+\tinfo->seqCnt = cnt;\n+\tif (cnt) {\n+\t\tpktgen_clr_port_flags(info, SEND_RANGE_PKTS);\n+\t\tpktgen_clr_port_flags(info, SEND_PCAP_PKTS);\n+\t\tpktgen_set_port_flags(info, SEND_SEQ_PKTS);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_SEQ_PKTS);\n+\tpktgen_packet_rate(info);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_port_prime - Set the number of packets to send on a prime command\n+ *\n+ * DESCRIPTION\n+ * Set the number packets to send on the prime command for all ports in list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_port_prime(port_info_t *info, uint32_t cnt)\n+{\n+\tif (cnt > MAX_PRIME_COUNT)\n+\t\tcnt = MAX_PRIME_COUNT;\n+\telse if (cnt == 0)\n+\t\tcnt = DEFAULT_PRIME_COUNT;\n+\n+\tinfo->prime_cnt = cnt;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_port_dump - Set the number of received packets to dump to screen.\n+ *\n+ * DESCRIPTION\n+ * Set the number of received packets to dump to screen.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_port_dump(port_info_t *info, uint32_t cnt)\n+{\n+\tint i;\n+\n+\tif (cnt > MAX_DUMP_PACKETS)\n+\t\tcnt = MAX_DUMP_PACKETS;\n+\n+\t/* Prevent concurrency issues by setting the fields in this specific order */\n+\tinfo->dump_count = 0;\n+\tinfo->dump_tail  = 0;\n+\tinfo->dump_head  = 0;\n+\n+\tfor (i = 0; i < MAX_DUMP_PACKETS; ++i)\n+\t\tif (info->dump_list->data != NULL) {\n+\t\t\trte_free(info->dump_list->data);\n+\t\t\tinfo->dump_list->data = NULL;\n+\t\t}\n+\n+\tinfo->dump_count = cnt;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_tx_burst - Set the transmit burst count.\n+ *\n+ * DESCRIPTION\n+ * Set the transmit burst count for all packets.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_tx_burst(port_info_t *info, uint32_t burst)\n+{\n+\tif (burst == 0)\n+\t\tburst = 1;\n+\telse if (burst > DEFAULT_PKT_BURST)\n+\t\tburst = DEFAULT_PKT_BURST;\n+\tinfo->tx_burst = burst;\n+\tpktgen_packet_rate(info);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_tx_cycles - Set the number of Transmit cycles to use.\n+ *\n+ * DESCRIPTION\n+ * Set the number of transmit cycles for the given port list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_tx_cycles(port_info_t *info, uint32_t cycles)\n+{\n+\tinfo->tx_cycles     = cycles;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_pkt_size - Set the size of the packets to send.\n+ *\n+ * DESCRIPTION\n+ * Set the pkt size for the single packet transmit.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_pkt_size(port_info_t *info, uint32_t size)\n+{\n+\tif ( (size - FCS_SIZE) < MIN_PKT_SIZE)\n+\t\tsize = (MIN_PKT_SIZE + FCS_SIZE);\n+\telse if ( (size - FCS_SIZE) > MAX_PKT_SIZE)\n+\t\tsize = MAX_PKT_SIZE + FCS_SIZE;\n+\tinfo->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+\tpktgen_packet_rate(info);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_port_value - Set the port value for single or sequence packets.\n+ *\n+ * DESCRIPTION\n+ * Set the port value for single or sequence packets for the ports listed.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_port_value(port_info_t *info, char type, uint32_t portValue)\n+{\n+\tif (type == 'd')\n+\t\tinfo->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;\n+\telse\n+\t\tinfo->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_tx_rate - Set the transmit rate as a percent value.\n+ *\n+ * DESCRIPTION\n+ * Set the transmit rate as a percent value for all ports listed.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_tx_rate(port_info_t *info, uint32_t rate)\n+{\n+\tif (rate == 0)\n+\t\trate = 1;\n+\telse if (rate > 100)\n+\t\trate = 100;\n+\tinfo->tx_rate = rate;\n+\tpktgen_packet_rate(info);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_ipaddr - Set the IP address for all ports listed\n+ *\n+ * DESCRIPTION\n+ * Set an IP address for all ports listed in the call.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_ipaddr(port_info_t *info, char type, cmdline_ipaddr_t *ip)\n+{\n+\tif (type == 's') {\n+\t\tinfo->seq_pkt[SINGLE_PKT].ip_mask = size_to_mask(ip->prefixlen);\n+\t\tinfo->seq_pkt[SINGLE_PKT].ip_src_addr.addr.ipv4.s_addr = ntohl(\n+\t\t                ip->addr.ipv4.s_addr);\n+\t} else\n+\t\tinfo->seq_pkt[SINGLE_PKT].ip_dst_addr.addr.ipv4.s_addr = ntohl(\n+\t\t                ip->addr.ipv4.s_addr);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_dst_mac - Setup the destination MAC address\n+ *\n+ * DESCRIPTION\n+ * Set the destination MAC address for all ports given.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_dst_mac(port_info_t *info, cmdline_etheraddr_t *mac)\n+{\n+\tmemcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);\n+\tpktgen_packet_ctor(info, SINGLE_PKT, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_range_enable_disable - Enable or disable range packet sending.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable range packet sending.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_range_enable_disable(port_info_t *info, char *str)\n+{\n+\tif (parseState(str) == ENABLE_STATE) {\n+\t\tpktgen_clr_port_flags(info, SEND_SEQ_PKTS);\n+\t\tpktgen_clr_port_flags(info, SEND_PCAP_PKTS);\n+\t\tpktgen_set_port_flags(info, SEND_RANGE_PKTS);\n+\t} else\n+\t\tpktgen_clr_port_flags(info, SEND_RANGE_PKTS);\n+\tpktgen_packet_rate(info);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_latency_enable_disable - Enable or disable latency testing.\n+ *\n+ * DESCRIPTION\n+ * Enable or disable latency testing.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_latency_enable_disable(port_info_t *info, char *str)\n+{\n+\tif (parseState(str) == ENABLE_STATE)\n+\t\tpktgen_set_port_flags(info, SEND_LATENCY_PKTS);\n+\telse\n+\t\tpktgen_clr_port_flags(info, SEND_LATENCY_PKTS);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_pattern_type - Set the pattern type per port.\n+ *\n+ * DESCRIPTION\n+ * Set the given pattern type.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_pattern_type(port_info_t *info, char *str)\n+{\n+\tif (strncmp(str, \"abc\", 3) == 0)\n+\t\tinfo->fill_pattern_type = ABC_FILL_PATTERN;\n+\telse if (strncmp(str, \"none\", 4) == 0)\n+\t\tinfo->fill_pattern_type = NO_FILL_PATTERN;\n+\telse if (strncmp(str, \"user\", 4) == 0)\n+\t\tinfo->fill_pattern_type = USER_FILL_PATTERN;\n+\telse if (strncmp(str, \"zero\", 4) == 0)\n+\t\tinfo->fill_pattern_type = ZERO_FILL_PATTERN;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_user_pattern_set - Set the user pattern string.\n+ *\n+ * DESCRIPTION\n+ * Set the given user pattern string.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_user_pattern_set(port_info_t *info, char *str)\n+{\n+\tchar copy[USER_PATTERN_SIZE + 1], *cp;\n+\n+\tmemset(copy, 0, sizeof(copy));\n+\tstrcpy(copy, str);\n+\tcp = &copy[0];\n+\tif ( (cp[0] == '\"') || (cp[0] == '\\'') ) {\n+\t\tcp[strlen(cp) - 1] = 0;\n+\t\tcp++;\n+\t}\n+\tmemset(info->user_pattern, 0, USER_PATTERN_SIZE);\n+\tstrncpy(info->user_pattern, cp, USER_PATTERN_SIZE);\n+\tinfo->fill_pattern_type = USER_FILL_PATTERN;\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_dest_mac - Set the destination MAC address\n+ *\n+ * DESCRIPTION\n+ * Set the destination MAC address for all ports given.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_dest_mac(port_info_t *info,\n+                    const char *what,\n+                    cmdline_etheraddr_t *mac)\n+{\n+\tif (!strcmp(what, \"min\") )\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac_min);\n+\telse if (!strcmp(what, \"max\") )\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac_max);\n+\telse if (!strcmp(what, \"inc\") )\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac_inc);\n+\telse if (!strcmp(what, \"start\") ) {\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac);\n+\t\t/* Changes add below to reflect MAC value in range */\n+\t\tmemcpy(&info->seq_pkt[RANGE_PKT].eth_dst_addr, mac->mac, 6);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_src_mac - Set the source MAC address for the ports.\n+ *\n+ * DESCRIPTION\n+ * Set the source MAC address for the ports given in the list.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_src_mac(port_info_t *info, const char *what,\n+                   cmdline_etheraddr_t *mac)\n+{\n+\tif (!strcmp(what, \"min\") )\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.src_mac_min);\n+\telse if (!strcmp(what, \"max\") )\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.src_mac_max);\n+\telse if (!strcmp(what, \"inc\") )\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.src_mac_inc);\n+\telse if (!strcmp(what, \"start\") ) {\n+\t\tinet_mtoh64((struct ether_addr *)mac, &info->range.src_mac);\n+\t\t/* Changes add below to reflect MAC value in range */\n+\t\tmemcpy(&info->seq_pkt[RANGE_PKT].eth_src_addr, mac->mac, 6);\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_src_ip - Set the source IP address value.\n+ *\n+ * DESCRIPTION\n+ * Set the source IP address for all of the ports listed.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_src_ip(port_info_t *info, char *what, cmdline_ipaddr_t *ip)\n+{\n+\tif (!strcmp(what, \"min\") )\n+\t\tinfo->range.src_ip_min = ntohl(ip->addr.ipv4.s_addr);\n+\telse if (!strcmp(what, \"max\") )\n+\t\tinfo->range.src_ip_max = ntohl(ip->addr.ipv4.s_addr);\n+\telse if (!strcmp(what, \"inc\") )\n+\t\tinfo->range.src_ip_inc = ntohl(ip->addr.ipv4.s_addr);\n+\telse if (!strcmp(what, \"start\") )\n+\t\tinfo->range.src_ip = ntohl(ip->addr.ipv4.s_addr);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_dst_ip - Set the destination IP address values\n+ *\n+ * DESCRIPTION\n+ * Set the destination IP address values.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_dst_ip(port_info_t *info, char *what, cmdline_ipaddr_t *ip)\n+{\n+\tif (!strcmp(what, \"min\") )\n+\t\tinfo->range.dst_ip_min = ntohl(ip->addr.ipv4.s_addr);\n+\telse if (!strcmp(what, \"max\") )\n+\t\tinfo->range.dst_ip_max = ntohl(ip->addr.ipv4.s_addr);\n+\telse if (!strcmp(what, \"inc\") )\n+\t\tinfo->range.dst_ip_inc = ntohl(ip->addr.ipv4.s_addr);\n+\telse if (!strcmp(what, \"start\") )\n+\t\tinfo->range.dst_ip = ntohl(ip->addr.ipv4.s_addr);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_src_port - Set the source IP port number for the ports\n+ *\n+ * DESCRIPTION\n+ * Set the source IP port number for the ports listed.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_src_port(port_info_t *info, char *what, uint16_t port)\n+{\n+\tif (!strcmp(what, \"inc\") ) {\n+\t\tif (port > 64)\n+\t\t\tport = 64;\n+\t\tinfo->range.src_port_inc = port;\n+\t} else {\n+\t\tif (!strcmp(what, \"min\") )\n+\t\t\tinfo->range.src_port_min = port;\n+\t\telse if (!strcmp(what, \"max\") )\n+\t\t\tinfo->range.src_port_max = port;\n+\t\telse if (!strcmp(what, \"start\") )\n+\t\t\tinfo->range.src_port = port;\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_gtpu_teid - Set the TEID for GTPU header\n+ *\n+ * DESCRIPTION\n+ * Set the GTP-U TEID for the ports listed.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_gtpu_teid(port_info_t *info, char *what, uint32_t teid)\n+{\n+\tif (!strcmp(what, \"inc\") ) {\n+\t\tif (teid != 0)\n+\t\t\tinfo->range.gtpu_teid_inc = teid;\n+\t} else {\n+\t\tif (!strcmp(what, \"min\") )\n+\t\t\tinfo->range.gtpu_teid_min = teid;\n+\t\telse if (!strcmp(what, \"max\") )\n+\t\t\tinfo->range.gtpu_teid_max = teid;\n+\t\telse if (!strcmp(what, \"start\") ) {\n+\t\t\tinfo->range.gtpu_teid = teid;\n+\t\t\tinfo->seq_pkt[RANGE_PKT].gtpu_teid = teid;\n+\t\t}\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_dst_port - Set the destination port value\n+ *\n+ * DESCRIPTION\n+ * Set the destination port values.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_dst_port(port_info_t *info, char *what, uint16_t port)\n+{\n+\tif (!strcmp(what, \"inc\") ) {\n+\t\tif (port > 64)\n+\t\t\tport = 64;\n+\t\tinfo->range.dst_port_inc = port;\n+\t} else {\n+\t\tif (!strcmp(what, \"min\") )\n+\t\t\tinfo->range.dst_port_min = port;\n+\t\telse if (!strcmp(what, \"max\") )\n+\t\t\tinfo->range.dst_port_max = port;\n+\t\telse if (!strcmp(what, \"start\") )\n+\t\t\tinfo->range.dst_port = port;\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_vlan_id - Set the VLAN id value\n+ *\n+ * DESCRIPTION\n+ * Set the VLAN id values.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_vlan_id(port_info_t *info, char *what, uint16_t id)\n+{\n+\tif (!strcmp(what, \"inc\") ) {\n+\t\tif (id > 64)\n+\t\t\tid = 64;\n+\t\tinfo->range.vlan_id_inc = id;\n+\t} else {\n+\t\tif ( (id < MIN_VLAN_ID) || (id > MAX_VLAN_ID) )\n+\t\t\tid = MIN_VLAN_ID;\n+\n+\t\tif (!strcmp(what, \"min\") )\n+\t\t\tinfo->range.vlan_id_min = id;\n+\t\telse if (!strcmp(what, \"max\") )\n+\t\t\tinfo->range.vlan_id_max = id;\n+\t\telse if (!strcmp(what, \"start\") )\n+\t\t\tinfo->range.vlan_id = id;\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_range_pkt_size - Set the Packet size value\n+ *\n+ * DESCRIPTION\n+ * Set the packet size values.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_range_pkt_size(port_info_t *info, char *what, uint16_t size)\n+{\n+\tif (!strcmp(what, \"inc\") ) {\n+\t\tif (size > ETHER_MIN_LEN)\n+\t\t\tsize = ETHER_MIN_LEN;\n+\n+\t\tinfo->range.pkt_size_inc = size;\n+\t} else {\n+\t\tif (size < ETHER_MIN_LEN)\n+\t\t\tsize = MIN_PKT_SIZE;\n+\t\telse if (size > ETHER_MAX_LEN)\n+\t\t\tsize = MAX_PKT_SIZE;\n+\t\telse\n+\t\t\tsize -= FCS_SIZE;\n+\n+\t\tif (!strcmp(what, \"start\") )\n+\t\t\tinfo->range.pkt_size = size;\n+\t\telse if (!strcmp(what, \"min\") )\n+\t\t\tinfo->range.pkt_size_min = size;\n+\t\telse if (!strcmp(what, \"max\") )\n+\t\t\tinfo->range.pkt_size_max = size;\n+\t}\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_send_arp_requests - Send an ARP request for a given port.\n+ *\n+ * DESCRIPTION\n+ * Using the port list do an ARp send for all ports.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_send_arp_requests(port_info_t *info, uint32_t type)\n+{\n+\tif (type == GRATUITOUS_ARP)\n+\t\tpktgen_set_port_flags(info, SEND_GRATUITOUS_ARP);\n+\telse\n+\t\tpktgen_set_port_flags(info, SEND_ARP_REQUEST);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_page - Set the page type to display\n+ *\n+ * DESCRIPTION\n+ * Set the page type ot display\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_page(char *str)\n+{\n+\tuint16_t page;\n+\n+\tif (str == NULL)\n+\t\treturn;\n+\n+\tpage = atoi(str);\n+\tif (page > pktgen.nb_ports)\n+\t\treturn;\n+\n+\t/* Switch to the correct page */\n+\tif (str[0] == 'n') {\n+\t\tpcap_info_t *pcap = pktgen.info[pktgen.portNum].pcap;\n+\n+\t\tif (pcap) {\n+\t\t\tif ( (pcap->pkt_idx + PCAP_PAGE_SIZE) < pcap->pkt_count)\n+\t\t\t\tpcap->pkt_idx += PCAP_PAGE_SIZE;\n+\t\t\telse\n+\t\t\t\tpcap->pkt_idx = 0;\n+\t\t}\n+\t\tpktgen.flags |= PRINT_LABELS_FLAG;\n+\t} else if ( (str[0] == 'c') && (str[1] == 'p') ) {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= CPU_PAGE_FLAG;\n+\t} else if (str[0] == 'p') {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= PCAP_PAGE_FLAG;\n+\t\tif (pktgen.info[pktgen.portNum].pcap)\n+\t\t\tpktgen.info[pktgen.portNum].pcap->pkt_idx = 0;\n+\t} else if ( ( str[0] == 'r' ) && (str[1] == 'a') ) {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= RANGE_PAGE_FLAG;\n+\t} else if (str[0] == 'c') {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= CONFIG_PAGE_FLAG;\n+\t} else if (str[0] == 's') {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= SEQUENCE_PAGE_FLAG;\n+\t} else if (str[0] == 'r') {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= RND_BITFIELD_PAGE_FLAG;\n+\t} else if (str[0] == 'l') {\n+\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\tpktgen.flags |= LOG_PAGE_FLAG;\n+\t} else {\n+\t\tuint16_t start_port;\n+\t\tif (str[0] == 'm')\n+\t\t\tpage = 0;\n+\t\tstart_port = (page * pktgen.nb_ports_per_page);\n+\t\tif ( (pktgen.starting_port != start_port) &&\n+\t\t     (start_port < pktgen.nb_ports) ) {\n+\t\t\tpktgen.starting_port    = start_port;\n+\t\t\tpktgen.ending_port      = start_port +\n+\t\t\t        pktgen.nb_ports_per_page;\n+\t\t\tif (pktgen.ending_port >\n+\t\t\t    (pktgen.starting_port + pktgen.nb_ports) )\n+\t\t\t\tpktgen.ending_port =\n+\t\t\t\t        (pktgen.starting_port +\n+\t\t\t\t         pktgen.nb_ports);\n+\t\t}\n+\t\tif (pktgen.flags & PAGE_MASK_BITS) {\n+\t\t\tpktgen.flags &= ~PAGE_MASK_BITS;\n+\t\t\tpktgen.flags |= PRINT_LABELS_FLAG;\n+\t\t}\n+\t}\n+\tpktgen_redisplay(1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_set_seq - Set a sequence packet for given port\n+ *\n+ * DESCRIPTION\n+ * Set the sequence packet information for all ports listed.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_set_seq(port_info_t *info, uint32_t seqnum,\n+               cmdline_etheraddr_t *daddr, cmdline_etheraddr_t *saddr,\n+               cmdline_ipaddr_t *ip_daddr, cmdline_ipaddr_t *ip_saddr,\n+               uint32_t sport, uint32_t dport, char type, char proto,\n+               uint16_t vlanid, uint32_t pktsize, uint32_t gtpu_teid)\n+{\n+\tpkt_seq_t     *pkt;\n+\n+\tpkt = &info->seq_pkt[seqnum];\n+\tmemcpy(&pkt->eth_dst_addr, daddr->mac, 6);\n+\tmemcpy(&pkt->eth_src_addr, saddr->mac, 6);\n+\tpkt->ip_mask = size_to_mask(ip_saddr->prefixlen);\n+\tif (type == '4') {\n+\t\tpkt->ip_src_addr.addr.ipv4.s_addr = htonl(ip_saddr->addr.ipv4.s_addr);\n+\t\tpkt->ip_dst_addr.addr.ipv4.s_addr = htonl(ip_daddr->addr.ipv4.s_addr);\n+\t} else {\n+\t\tmemcpy(&pkt->ip_src_addr.addr.ipv6.__in6_u.__u6_addr8,\n+\t\t\tip_saddr->addr.ipv6.__in6_u.__u6_addr8, sizeof(struct in6_addr));\n+\t\tmemcpy(&pkt->ip_dst_addr.addr.ipv6.__in6_u.__u6_addr8,\n+\t\t\tip_daddr->addr.ipv6.__in6_u.__u6_addr8, sizeof(struct in6_addr));\n+\t}\n+\tpkt->dport          = dport;\n+\tpkt->sport          = sport;\n+\tpkt->pktSize        = pktsize - FCS_SIZE;\n+\tpkt->ipProto        = (proto == 'u') ? PG_IPPROTO_UDP :\n+\t        (proto == 'i') ? PG_IPPROTO_ICMP : PG_IPPROTO_TCP;\n+\t/* Force the IP protocol to IPv4 if this is a ICMP packet. */\n+\tif (proto == 'i')\n+\t\ttype = '4';\n+\tpkt->ethType        = (type == '6') ? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;\n+\tpkt->vlanid         = vlanid;\n+\tpkt->gtpu_teid      = gtpu_teid;\n+\tpktgen_packet_ctor(info, seqnum, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_compile_pkt - Compile a packet for a given port.\n+ *\n+ * DESCRIPTION\n+ * Compile a packet for a given port.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_compile_pkt(port_info_t *info, uint32_t seqnum,\n+                   cmdline_etheraddr_t *daddr, cmdline_etheraddr_t *saddr,\n+                   cmdline_ipaddr_t *ip_daddr, cmdline_ipaddr_t *ip_saddr,\n+                   uint32_t sport, uint32_t dport, char type, char proto,\n+                   uint16_t vlanid, uint32_t pktsize, uint32_t gtpu_teid)\n+{\n+\tpkt_seq_t     *pkt;\n+\n+\tif (seqnum >= NUM_EXTRA_TX_PKTS)\n+\t\treturn;\n+\n+\tpkt = &info->seq_pkt[seqnum + EXTRA_TX_PKT];\n+\n+\tmemcpy(&pkt->eth_dst_addr, daddr->mac, 6);\n+\tmemcpy(&pkt->eth_src_addr, saddr->mac, 6);\n+\tpkt->ip_mask        = size_to_mask(ip_saddr->prefixlen);\n+\tpkt->ip_src_addr.addr.ipv4.s_addr    = htonl(ip_saddr->addr.ipv4.s_addr);\n+\tpkt->ip_dst_addr.addr.ipv4.s_addr    = htonl(ip_daddr->addr.ipv4.s_addr);\n+\tpkt->dport          = dport;\n+\tpkt->sport          = sport;\n+\tpkt->pktSize        = pktsize - FCS_SIZE;\n+\tpkt->ipProto        = (proto == 'u') ? PG_IPPROTO_UDP :\n+\t        (proto == 'i') ? PG_IPPROTO_ICMP : PG_IPPROTO_TCP;\n+\t/* Force the IP protocol to IPv4 if this is a ICMP packet. */\n+\tif (proto == 'i')\n+\t\ttype = '4';\n+\tpkt->ethType        = (type == '4') ? ETHER_TYPE_IPv4 :\n+\t        (type == '6') ? ETHER_TYPE_IPv6 :\n+\t        (type == 'n') ? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;\n+\tpkt->vlanid         = vlanid;\n+\tpkt->gtpu_teid          = gtpu_teid;\n+\tpktgen_packet_ctor(info, seqnum, -1);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_send_pkt - Send a packet from the sequence array.\n+ *\n+ * DESCRIPTION\n+ * Send a packet from the special pkt_seq_t structures. Seqnum is the 0-N\n+ * index value into the info.seq_pkt[] array for EXTRA_TX_PKTS.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_send_pkt(port_info_t *info, uint32_t seqnum)\n+{\n+\tpktgen_send_seq_pkt(info, seqnum + EXTRA_TX_PKT);\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_recv_pkt - Receive a packet from the sequence array.\n+ *\n+ * DESCRIPTION\n+ * Receive a packet from the special pkt_seq_t structures.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_recv_pkt(port_info_t *info __rte_unused)\n+{\n+\tpktgen_log_warning(\"Not working yet!\");\n+}\n+\n+/**************************************************************************//**\n+ *\n+ * pktgen_quit - Exit pktgen.\n+ *\n+ * DESCRIPTION\n+ * Close and exit Pktgen.\n+ *\n+ * RETURNS: N/A\n+ *\n+ * SEE ALSO:\n+ */\n+\n+void\n+pktgen_quit(void)\n+{\n+\tcmdline_quit(pktgen.cl);\n+}\ndiff --git a/app/pktgen-cmds.h b/app/pktgen-cmds.h\nindex 683abc3..1c50e59 100644\n--- a/app/pktgen-cmds.h\n+++ b/app/pktgen-cmds.h\n@@ -135,7 +135,7 @@ extern void pktgen_set_pkt_size(port_info_t *info, uint32_t size);\n extern void pktgen_set_port_value(port_info_t *info,\n                                   char type,\n                                   uint32_t portValue);\n-extern void pktgen_set_tx_rate(port_info_t *info, uint32_t rate);\n+extern void pktgen_set_tx_rate(port_info_t *info, float rate);\n extern void pktgen_set_ipaddr(port_info_t *info, char type,\n                               cmdline_ipaddr_t *ip);\n extern void pktgen_set_dst_mac(port_info_t *info, cmdline_etheraddr_t *mac);\ndiff --git a/app/pktgen-port-cfg.h b/app/pktgen-port-cfg.h\nindex bd5876c..a20286d 100644\n--- a/app/pktgen-port-cfg.h\n+++ b/app/pktgen-port-cfg.h\n@@ -193,7 +193,7 @@ typedef struct port_info_s {\n \tuint16_t pid;\t\t/**< Port ID value */\n \tuint16_t tx_burst;\t/**< Number of TX burst packets */\n \tuint8_t pad0;\n-\tuint8_t tx_rate;\t\t/**< Percentage rate for tx packets */\n+\tfloat tx_rate;\t\t/**< Percentage rate for tx packets */\n \trte_atomic32_t port_flags;\t/**< Special send flags for ARP and other */\n \n \trte_atomic64_t transmit_count;\t/**< Packets to transmit loaded into current_tx_count */\ndiff --git a/app/pktgen.c b/app/pktgen.c\nindex a0705ab..a64e0ca 100644\n--- a/app/pktgen.c\n+++ b/app/pktgen.c\n@@ -143,7 +143,7 @@ pktgen_packet_rate(port_info_t *info)\n \tinfo->tx_pps    = pps;\n \tinfo->tx_cycles = ((cpp * info->tx_burst) /\n \t                       wr_get_port_txcnt(pktgen.l2p, info->pid));\n-\tinfo->tx_cycles -= ff[info->tx_rate / 10];\n+\tinfo->tx_cycles -= ff[(int)info->tx_rate / 10];\n }\n \n /**************************************************************************//**\n",
    "prefixes": [
        "dpdk-dev"
    ]
}