From: "inaki.murillo" <inaki.murilloa@ehu.eus>
To: dev@dpdk.org
Cc: "inaki.murillo" <inaki.murilloa@ehu.eus>
Subject: [dpdk-dev] [PATCH] Rate as a decimal number
Date: Thu, 21 Apr 2016 17:33:44 +0200 [thread overview]
Message-ID: <1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus> (raw)
Currently Pktgen does not accept a decimal number for the rate. This patch makes possible to set a decimal number as a rate.
Signed-off-by: Iñaki Murillo Arroyo <inaki.murilloa@ehu.eus>
---
app/cmd-functions.c | 71 +-
app/cmd-functions.h | 38 +
app/lpktgenlib.c | 2 +-
app/pktgen-cmds.c | 10 +-
app/pktgen-cmds.c.orig | 2622 ++++++++++++++++++++++++++++++++++++++++++++++++
app/pktgen-cmds.h | 2 +-
app/pktgen-port-cfg.h | 2 +-
app/pktgen.c | 2 +-
8 files changed, 2737 insertions(+), 12 deletions(-)
create mode 100644 app/pktgen-cmds.c.orig
diff --git a/app/cmd-functions.c b/app/cmd-functions.c
index b2fda7c..a009907 100644
--- a/app/cmd-functions.c
+++ b/app/cmd-functions.c
@@ -1805,7 +1805,7 @@ struct cmd_set_result {
cmdline_fixed_string_t set;
cmdline_portlist_t portlist;
cmdline_fixed_string_t what;
- uint32_t value;
+ float value;
};
/**************************************************************************//**
@@ -1865,8 +1865,8 @@ cmdline_parse_token_string_t cmd_set_what =
TOKEN_STRING_INITIALIZER(struct cmd_set_result,
what,
"count#size#rate#burst#tx_cycles#sport#dport#seqCnt#prime#dump#vlanid");
-cmdline_parse_token_num_t cmd_set_value =
- TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT32);
+cmdline_parse_token_float_t cmd_set_value =
+ TOKEN_FLOAT_INITIALIZER(struct cmd_set_result, value, FLOAT);
cmdline_parse_inst_t cmd_set = {
.f = cmd_set_parsed,
@@ -4691,3 +4691,68 @@ pktgen_load_cmds(char *filename)
}
return 0;
}
+
+struct cmdline_token_ops cmdline_token_float_ops = {
+ .parse = cmdline_parse_float,
+ .complete_get_nb = NULL,
+ .complete_get_elt = NULL,
+ .get_help = cmdline_get_help_float,
+};
+
+/* parse a float */
+int
+cmdline_parse_float(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res, unsigned ressize)
+{
+ unsigned int token_len;
+ float tmp;
+
+ if (res && ressize < STR_TOKEN_SIZE)
+ return -1;
+
+ if (!tk || !srcbuf || ! *srcbuf)
+ return -1;
+
+ token_len = 0;
+ while(!cmdline_isendoftoken(srcbuf[token_len]) && token_len < (STR_TOKEN_SIZE-1))
+ {
+ token_len++;
+ }
+
+ /* return if token too long */
+ if (token_len >= STR_TOKEN_SIZE - 1) {
+ return -1;
+ }
+
+ tmp = atof(srcbuf);
+ if ((tmp == 0 && strcmp(srcbuf, "0") == 0) || (tmp != 0)) {
+ /* we are sure that token_len is < STR_TOKEN_SIZE-1 */
+ *(float *)res = tmp;
+ return token_len;
+ }
+
+ return -1;
+
+}
+
+/* parse a float */
+int
+cmdline_get_help_float(cmdline_parse_token_hdr_t *tk, char *dstbuf, unsigned int size)
+{
+ struct cmdline_token_float_data nd;
+ int ret;
+
+ if (!tk)
+ return -1;
+
+ memcpy(&nd, &((struct cmdline_token_float *)tk)->float_data, sizeof(nd));
+
+ /* should not happen.... don't so this test */
+ /* if (nd.type >= (sizeof(num_help)/sizeof(const char *))) */
+ /* return -1; */
+
+ ret = snprintf(dstbuf, size, "FLOAT");
+ if (ret < 0)
+ return -1;
+ dstbuf[size-1] = '\0';
+ return 0;
+}
diff --git a/app/cmd-functions.h b/app/cmd-functions.h
index 0ccef6d..4b8dc4c 100644
--- a/app/cmd-functions.h
+++ b/app/cmd-functions.h
@@ -77,4 +77,42 @@ extern void pktgen_cmdline_start(void);
extern int pktgen_load_cmds(char *filename);
+/* size of a parsed string */
+#define STR_TOKEN_SIZE 128
+
+enum cmdline_floattype {
+ FLOAT
+};
+
+struct cmdline_token_float_data {
+ const float *float_data;
+};
+
+struct cmdline_token_float {
+ struct cmdline_token_hdr hdr;
+ struct cmdline_token_float_data float_data;
+};
+typedef struct cmdline_token_float cmdline_parse_token_float_t;
+
+extern struct cmdline_token_ops cmdline_token_float_ops;
+
+int cmdline_parse_float(cmdline_parse_token_hdr_t *tk,
+ const char *srcbuf, void *res, unsigned ressize);
+int cmdline_get_help_float(cmdline_parse_token_hdr_t *tk,
+ char *dstbuf, unsigned int size);
+
+#define TOKEN_FLOAT_INITIALIZER(structure, field, float_type) \
+{ \
+ /* hdr */ \
+ { \
+ &cmdline_token_float_ops, /* ops */ \
+ offsetof(structure, field), /* offset */ \
+ }, \
+ /* num_data */ \
+ { \
+ float_type, /* type */ \
+ }, \
+}
+
+
#endif /* _COMMANDS_H_ */
diff --git a/app/lpktgenlib.c b/app/lpktgenlib.c
index 693a174..f3a2a84 100644
--- a/app/lpktgenlib.c
+++ b/app/lpktgenlib.c
@@ -240,7 +240,7 @@ parse_portlist(const char *buf, void *pl) {
static int
pktgen_set(lua_State *L) {
- uint32_t value;
+ float value;
cmdline_portlist_t portlist;
char *what;
diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
index 83ba230..d150b41 100644
--- a/app/pktgen-cmds.c
+++ b/app/pktgen-cmds.c
@@ -178,7 +178,7 @@ pktgen_save(char *path)
fprintf(fd, "#\n");
flags = rte_atomic32_read(&info->port_flags);
fprintf(fd,
- "# Port: %2d, Burst:%3d, Rate:%3d%%, Flags:%08x, TX Count:%s\n",
+ "# Port: %2d, Burst:%3d, Rate:%3f%%, Flags:%08x, TX Count:%s\n",
info->pid,
info->tx_burst,
info->tx_rate,
@@ -196,7 +196,7 @@ pktgen_save(char *path)
"set %d size %d\n",
info->pid,
pkt->pktSize + FCS_SIZE);
- fprintf(fd, "set %d rate %d\n", info->pid, info->tx_rate);
+ fprintf(fd, "set %d rate %f\n", info->pid, info->tx_rate);
fprintf(fd, "set %d burst %d\n", info->pid, info->tx_burst);
fprintf(fd, "set %d sport %d\n", info->pid, pkt->sport);
fprintf(fd, "set %d dport %d\n", info->pid, pkt->dport);
@@ -498,9 +498,9 @@ pktgen_transmit_count_rate(int port, char *buff, int len)
port_info_t *info = &pktgen.info[port];
if (rte_atomic64_read(&info->transmit_count) == 0)
- snprintf(buff, len, "Forever /%4d%%", info->tx_rate);
+ snprintf(buff, len, "Forever /%4f%%", info->tx_rate);
else
- snprintf(buff, len, "%ld /%4d%%",
+ snprintf(buff, len, "%ld /%4f%%",
rte_atomic64_read(&info->transmit_count),
info->tx_rate);
@@ -1949,7 +1949,7 @@ pktgen_set_port_value(port_info_t *info, char type, uint32_t portValue)
*/
void
-pktgen_set_tx_rate(port_info_t *info, uint32_t rate)
+pktgen_set_tx_rate(port_info_t *info, float rate)
{
if (rate == 0)
rate = 1;
diff --git a/app/pktgen-cmds.c.orig b/app/pktgen-cmds.c.orig
new file mode 100644
index 0000000..83ba230
--- /dev/null
+++ b/app/pktgen-cmds.c.orig
@@ -0,0 +1,2622 @@
+/*-
+ * Copyright (c) <2010>, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * - Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Copyright (c) <2010-2014>, Wind River Systems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * 4) The screens displayed by the application must contain the copyright notice as defined
+ * above and can not be removed without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/* Created 2010 by Keith Wiles @ intel.com */
+
+#include "pktgen-cmds.h"
+
+#include "pktgen-display.h"
+#include "pktgen.h"
+
+/**************************************************************************//**
+ *
+ * pktgen_save - Save a configuration as a startup script
+ *
+ * DESCRIPTION
+ * Save a configuration as a startup script
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+int
+pktgen_save(char *path)
+{
+ port_info_t *info;
+ pkt_seq_t *pkt;
+ range_info_t *range;
+ uint32_t flags;
+ char buff[64];
+ FILE *fd;
+ int i, j;
+ uint64_t lcore;
+ struct ether_addr eaddr;
+
+ fd = fopen(path, "w");
+ if (fd == NULL)
+ return -1;
+
+ for (i = 0, lcore = 0; i < RTE_MAX_LCORE; i++)
+ if (rte_lcore_is_enabled(i) )
+ lcore |= (1 << i);
+
+ fprintf(fd, "#\n# Pktgen - %s\n", pktgen_version());
+ fprintf(fd, "# %s, %s\n\n", wr_copyright_msg(), wr_powered_by());
+
+ /* TODO: Determine DPDK arguments for rank and memory, default for now. */
+ fprintf(fd, "# Command line arguments: (DPDK args are defaults)\n");
+ fprintf(fd,
+ "# %s -c %lx -n 3 -m 512 --proc-type %s -- ",
+ pktgen.argv[0],
+ lcore,
+ (rte_eal_process_type() ==
+ RTE_PROC_PRIMARY) ? "primary" : "secondary");
+ for (i = 1; i < pktgen.argc; i++)
+ fprintf(fd, "%s ", pktgen.argv[i]);
+ fprintf(fd, "\n\n");
+
+ fprintf(fd,
+ "#######################################################################\n");
+ fprintf(fd, "# Pktgen Configuration script information:\n");
+ fprintf(fd,
+ "# GUI socket is %s\n",
+ (pktgen.flags & ENABLE_GUI_FLAG) ? "Enabled" : "Not Enabled");
+ fprintf(fd, "# Flags %08x\n", pktgen.flags);
+ fprintf(fd, "# Number of ports: %d\n", pktgen.nb_ports);
+ fprintf(fd, "# Number ports per page: %d\n",
+ pktgen.nb_ports_per_page);
+ fprintf(fd,
+ "# Number descriptors: RX %d TX: %d\n",
+ pktgen.nb_rxd,
+ pktgen.nb_txd);
+ fprintf(fd, "# Promiscuous mode is %s\n\n",
+ (pktgen.flags & PROMISCUOUS_ON_FLAG) ? "Enabled" : "Disabled");
+
+#if 0
+ fprintf(fd, "# Port Descriptions (-- = blacklisted port):\n");
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+ if (pktgen.portdesc[i] && strlen((char *)pktgen.portdesc[i]) ) {
+ if ( (pktgen.enabled_port_mask & (1 << i)) == 0)
+ strcpy(buff, "--");
+ else
+ strcpy(buff, "++");
+
+ fprintf(fd, "# %s %s\n", buff, pktgen.portdesc[i]);
+ }
+
+#endif
+ fprintf(fd,
+ "\n#######################################################################\n");
+
+ fprintf(fd, "# Global configuration:\n");
+ uint16_t rows, cols;
+ pktgen_display_get_geometry(&rows, &cols);
+ fprintf(fd, "geometry %dx%d\n", cols, rows);
+ fprintf(fd,
+ "mac_from_arp %s\n\n",
+ (pktgen.flags & MAC_FROM_ARP_FLAG) ? "enable" : "disable");
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+ info = &pktgen.info[i];
+ pkt = &info->seq_pkt[SINGLE_PKT];
+ range = &info->range;
+
+ if (info->tx_burst == 0)
+ continue;
+
+ fprintf(fd,
+ "######################### Port %2d ##################################\n",
+ i);
+ if (rte_atomic64_read(&info->transmit_count) == 0)
+ strcpy(buff, "Forever");
+ else
+ snprintf(buff, sizeof(buff), "%ld",
+ rte_atomic64_read(&info->transmit_count));
+ fprintf(fd, "#\n");
+ flags = rte_atomic32_read(&info->port_flags);
+ fprintf(fd,
+ "# Port: %2d, Burst:%3d, Rate:%3d%%, Flags:%08x, TX Count:%s\n",
+ info->pid,
+ info->tx_burst,
+ info->tx_rate,
+ flags,
+ buff);
+ fprintf(fd, "# SeqCnt:%d, Prime:%d VLAN ID:%04x, ",
+ info->seqCnt, info->prime_cnt, info->vlanid);
+ pktgen_link_state(info->pid, buff, sizeof(buff));
+ fprintf(fd, "Link: %s\n", buff);
+
+ fprintf(fd, "#\n# Set up the primary port information:\n");
+ fprintf(fd, "set %d count %ld\n", info->pid,
+ rte_atomic64_read(&info->transmit_count));
+ fprintf(fd,
+ "set %d size %d\n",
+ info->pid,
+ pkt->pktSize + FCS_SIZE);
+ fprintf(fd, "set %d rate %d\n", info->pid, info->tx_rate);
+ fprintf(fd, "set %d burst %d\n", info->pid, info->tx_burst);
+ fprintf(fd, "set %d sport %d\n", info->pid, pkt->sport);
+ fprintf(fd, "set %d dport %d\n", info->pid, pkt->dport);
+ fprintf(fd, "set %d prime %d\n", info->pid, info->prime_cnt);
+ fprintf(fd, "type %s %d\n",
+ (pkt->ethType == ETHER_TYPE_IPv4) ? "ipv4" :
+ (pkt->ethType == ETHER_TYPE_IPv6) ? "ipv6" :
+ (pkt->ethType == ETHER_TYPE_VLAN) ? "vlan" :
+ (pkt->ethType == ETHER_TYPE_ARP) ? "arp" : "unknown",
+ i);
+ fprintf(fd, "proto %s %d\n",
+ (pkt->ipProto == PG_IPPROTO_TCP) ? "tcp" :
+ (pkt->ipProto == PG_IPPROTO_ICMP) ? "icmp" : "udp", i);
+ fprintf(fd, "set ip dst %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(pkt->ip_dst_addr.addr.ipv4.s_addr),
+ 0xFFFFFFFF));
+ fprintf(fd, "set ip src %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(pkt->ip_src_addr.addr.ipv4.s_addr),
+ pkt->ip_mask));
+ fprintf(fd, "set mac %d %s\n", info->pid,
+ inet_mtoa(buff, sizeof(buff), &pkt->eth_dst_addr));
+ fprintf(fd, "vlanid %d %d\n\n", i, pkt->vlanid);
+
+ fprintf(fd,
+ "pattern %d %s\n",
+ i,
+ (info->fill_pattern_type == ABC_FILL_PATTERN) ? "abc" :
+ (info->fill_pattern_type == NO_FILL_PATTERN) ? "none" :
+ (info->fill_pattern_type ==
+ ZERO_FILL_PATTERN) ? "zero" : "user");
+ if (strlen(info->user_pattern) )
+ fprintf(fd,
+ "user.pattern %d %s\n",
+ i,
+ info->user_pattern);
+ fprintf(fd, "\n");
+
+ fprintf(fd,
+ "latency %d %s\n",
+ i,
+ (flags & SEND_LATENCY_PKTS) ? "enable" : "disable");
+
+ fprintf(fd,
+ "mpls %d %sable\n",
+ i,
+ (flags & SEND_MPLS_LABEL) ? "en" : "dis");
+ sprintf(buff, "%x", pkt->mpls_entry);
+ fprintf(fd, "mpls_entry %d %s\n", i, buff);
+
+ fprintf(fd,
+ "qinq %d %sable\n",
+ i,
+ (flags & SEND_Q_IN_Q_IDS) ? "en" : "dis");
+ fprintf(fd,
+ "qinqids %d %d %d\n",
+ i,
+ pkt->qinq_outerid,
+ pkt->qinq_innerid);
+
+ fprintf(fd,
+ "gre %d %sable\n",
+ i,
+ (flags & SEND_GRE_IPv4_HEADER) ? "en" : "dis");
+ fprintf(fd, "gre_eth %d %sable\n", i,
+ (flags & SEND_GRE_ETHER_HEADER) ? "en" : "dis");
+ fprintf(fd, "gre_key %d %d\n", i, pkt->gre_key);
+
+ fprintf(fd, "#\n# Port flag values:\n");
+ fprintf(fd, "icmp.echo %d %sable\n", i,
+ (flags & ICMP_ECHO_ENABLE_FLAG) ? "en" : "dis");
+ fprintf(fd,
+ "pcap %d %sable\n",
+ i,
+ (flags & SEND_PCAP_PKTS) ? "en" : "dis");
+ fprintf(fd,
+ "range %d %sable\n",
+ i,
+ (flags & SEND_RANGE_PKTS) ? "en" : "dis");
+ fprintf(fd, "process %d %sable\n", i,
+ (flags & PROCESS_INPUT_PKTS) ? "en" : "dis");
+ fprintf(fd,
+ "capture %d %sable\n",
+ i,
+ (flags & CAPTURE_PKTS) ? "en" : "dis");
+ fprintf(fd,
+ "rxtap %d %sable\n",
+ i,
+ (flags & PROCESS_RX_TAP_PKTS) ? "en" : "dis");
+ fprintf(fd,
+ "txtap %d %sable\n",
+ i,
+ (flags & PROCESS_TX_TAP_PKTS) ? "en" : "dis");
+ fprintf(fd,
+ "vlan %d %sable\n\n",
+ i,
+ (flags & SEND_VLAN_ID) ? "en" : "dis");
+
+ fprintf(fd, "#\n# Range packet information:\n");
+ fprintf(fd, "src.mac start %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->src_mac, &eaddr)));
+ fprintf(fd, "src.mac min %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->src_mac_min, &eaddr)));
+ fprintf(fd, "src.mac max %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->src_mac_max, &eaddr)));
+ fprintf(fd, "src.mac inc %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->src_mac_inc, &eaddr)));
+
+ fprintf(fd, "dst.mac start %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->dst_mac, &eaddr)));
+ fprintf(fd, "dst.mac min %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->dst_mac_min, &eaddr)));
+ fprintf(fd, "dst.mac max %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->dst_mac_max, &eaddr)));
+ fprintf(fd, "dst.mac inc %d %s\n", i,
+ inet_mtoa(buff, sizeof(buff),
+ inet_h64tom(range->dst_mac_inc, &eaddr)));
+
+ fprintf(fd, "\n");
+ fprintf(fd, "src.ip start %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip),
+ 0xFFFFFFFF));
+ fprintf(fd, "src.ip min %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip_min),
+ 0xFFFFFFFF));
+ fprintf(fd, "src.ip max %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip_max),
+ 0xFFFFFFFF));
+ fprintf(fd, "src.ip inc %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->src_ip_inc),
+ 0xFFFFFFFF));
+
+ fprintf(fd, "\n");
+ fprintf(fd, "dst.ip start %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip),
+ 0xFFFFFFFF));
+ fprintf(fd, "dst.ip min %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip_min),
+ 0xFFFFFFFF));
+ fprintf(fd, "dst.ip max %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip_max),
+ 0xFFFFFFFF));
+ fprintf(fd, "dst.ip inc %d %s\n", i,
+ inet_ntop4(buff, sizeof(buff), ntohl(range->dst_ip_inc),
+ 0xFFFFFFFF));
+
+ fprintf(fd, "\n");
+ fprintf(fd, "src.port start %d %d\n", i, range->src_port);
+ fprintf(fd, "src.port min %d %d\n", i, range->src_port_min);
+ fprintf(fd, "src.port max %d %d\n", i, range->src_port_max);
+ fprintf(fd, "src.port inc %d %d\n", i, range->src_port_inc);
+
+ fprintf(fd, "\n");
+ fprintf(fd, "dst.port start %d %d\n", i, range->dst_port);
+ fprintf(fd, "dst.port min %d %d\n", i, range->dst_port_min);
+ fprintf(fd, "dst.port max %d %d\n", i, range->dst_port_max);
+ fprintf(fd, "dst.port inc %d %d\n", i, range->dst_port_inc);
+
+ fprintf(fd, "\n");
+ fprintf(fd, "vlan.id start %d %d\n", i, range->vlan_id);
+ fprintf(fd, "vlan.id min %d %d\n", i, range->vlan_id_min);
+ fprintf(fd, "vlan.id max %d %d\n", i, range->vlan_id_max);
+ fprintf(fd, "vlan.id inc %d %d\n", i, range->vlan_id_inc);
+
+ fprintf(fd, "\n");
+ fprintf(fd,
+ "pkt.size start %d %d\n",
+ i,
+ range->pkt_size + FCS_SIZE);
+ fprintf(fd,
+ "pkt.size min %d %d\n",
+ i,
+ range->pkt_size_min + FCS_SIZE);
+ fprintf(fd,
+ "pkt.size max %d %d\n",
+ i,
+ range->pkt_size_max + FCS_SIZE);
+ fprintf(fd, "pkt.size inc %d %d\n\n", i, range->pkt_size_inc);
+
+ fprintf(fd, "#\n# Set up the sequence data for the port.\n");
+ fprintf(fd, "set %d seqCnt %d\n", info->pid, info->seqCnt);
+ for (j = 0; j < info->seqCnt; j++) {
+ pkt = &info->seq_pkt[j];
+ fprintf(fd, "seq %d %d %s ", j, i,
+ inet_mtoa(buff,
+ sizeof(buff),
+ &pkt->eth_dst_addr));
+ fprintf(fd, "%s ",
+ inet_mtoa(buff,
+ sizeof(buff),
+ &pkt->eth_src_addr));
+ fprintf(fd, "%s ",
+ inet_ntop4(buff, sizeof(buff),
+ htonl(pkt->ip_dst_addr.addr.ipv4.s_addr),
+ 0xFFFFFFFF));
+ fprintf(fd, "%s ",
+ inet_ntop4(buff, sizeof(buff),
+ htonl(pkt->ip_src_addr.addr.ipv4.s_addr),
+ pkt->ip_mask));
+ fprintf(fd,
+ "%d %d %s %s %d %d\n",
+ pkt->sport,
+ pkt->dport,
+ (pkt->ethType == ETHER_TYPE_IPv4) ? "ipv4" :
+ (pkt->ethType == ETHER_TYPE_IPv6) ? "ipv6" :
+ (pkt->ethType == ETHER_TYPE_VLAN) ? "vlan" : "Other",
+ (pkt->ipProto == PG_IPPROTO_TCP) ? "tcp" :
+ (pkt->ipProto == PG_IPPROTO_ICMP) ? "icmp" : "udp",
+ pkt->vlanid,
+ pkt->pktSize + FCS_SIZE);
+ }
+
+ if (pktgen.info[i].pcap) {
+ fprintf(fd, "#\n# PCAP port %d\n", i);
+ fprintf(fd,
+ "# Packet count: %d\n",
+ pktgen.info[i].pcap->pkt_count);
+ fprintf(fd,
+ "# Filename : %s\n",
+ pktgen.info[i].pcap->filename);
+ }
+ fprintf(fd, "\n");
+ }
+ fprintf(fd,
+ "################################ Done #################################\n");
+
+ fclose(fd);
+ return 0;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_port_transmitting - Is the port transmitting packets?
+ *
+ * DESCRIPTION
+ * Is the port transmitting packets.
+ *
+ * RETURNS: 1 for yes and 0 for no.
+ *
+ * SEE ALSO:
+ */
+
+int
+pktgen_port_transmitting(int port)
+{
+ return rte_atomic32_read(&pktgen.info[port].port_flags) &
+ SENDING_PACKETS;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_link_state - Get the ASCII string for the port state.
+ *
+ * DESCRIPTION
+ * Return the port state string for a given port.
+ *
+ * RETURNS: String pointer to link state
+ *
+ * SEE ALSO:
+ */
+
+char *
+pktgen_link_state(int port, char *buff, int len)
+{
+ port_info_t *info = &pktgen.info[port];
+
+ if (info->link.link_status)
+ snprintf(buff, len, "<UP-%u-%s>",
+ (uint32_t)info->link.link_speed,
+ (info->link.link_duplex ==
+ ETH_LINK_FULL_DUPLEX) ? ("FD") : ("HD"));
+ else
+ snprintf(buff, len, "<--Down-->");
+
+ return buff;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_transmit_count_rate - Get a string for the current transmit count and rate
+ *
+ * DESCRIPTION
+ * Current value of the transmit count/%rate as a string.
+ *
+ * RETURNS: String pointer to transmit count/%rate.
+ *
+ * SEE ALSO:
+ */
+
+char *
+pktgen_transmit_count_rate(int port, char *buff, int len)
+{
+ port_info_t *info = &pktgen.info[port];
+
+ if (rte_atomic64_read(&info->transmit_count) == 0)
+ snprintf(buff, len, "Forever /%4d%%", info->tx_rate);
+ else
+ snprintf(buff, len, "%ld /%4d%%",
+ rte_atomic64_read(&info->transmit_count),
+ info->tx_rate);
+
+ return buff;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_port_sizes - Current stats for all port sizes
+ *
+ * DESCRIPTION
+ * Structure returned with all of the counts for each port size.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+int
+pktgen_port_sizes(int port, port_sizes_t *psizes)
+{
+ port_info_t *info = &pktgen.info[port];
+
+ *psizes = info->sizes;
+ return 0;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_pkt_stats - Get the packet stats structure.
+ *
+ * DESCRIPTION
+ * Return the packet statistics values.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+int
+pktgen_pkt_stats(int port, pkt_stats_t *pstats)
+{
+ port_info_t *info = &pktgen.info[port];
+
+ *pstats = info->stats;
+ return 0;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_port_stats - Get the port or rate stats for a given port
+ *
+ * DESCRIPTION
+ * Get the ports or rate stats from a given port.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+int
+pktgen_port_stats(int port, const char *name, eth_stats_t *pstats)
+{
+ port_info_t *info = &pktgen.info[port];
+
+ if (strcmp(name, "port") == 0)
+ *pstats = info->port_stats;
+ else if (strcmp(name, "rate") == 0)
+ *pstats = info->rate_stats;
+
+ return 0;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_flags_string - Return the flags string for display
+ *
+ * DESCRIPTION
+ * Return the current flags string for display for a port.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+char *
+pktgen_flags_string(port_info_t *info)
+{
+ static char buff[32];
+ uint32_t flags = rte_atomic32_read(&info->port_flags);
+
+ snprintf(buff, sizeof(buff), "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ (pktgen.flags & PROMISCUOUS_ON_FLAG) ? 'P' : '-',
+ (flags & ICMP_ECHO_ENABLE_FLAG) ? 'E' : '-',
+ (flags & SEND_ARP_REQUEST) ? 'A' : '-',
+ (flags & SEND_GRATUITOUS_ARP) ? 'G' : '-',
+ (flags & SEND_PCAP_PKTS) ? 'p' : '-',
+ (flags & SEND_SEQ_PKTS) ? 'S' : '-',
+ (flags & SEND_RANGE_PKTS) ? 'R' : '-',
+ (flags & PROCESS_INPUT_PKTS) ? 'I' : '-',
+ "-rt*"[(flags & (PROCESS_RX_TAP_PKTS | PROCESS_TX_TAP_PKTS)) >>
+ 9],
+ (flags & SEND_LATENCY_PKTS) ? 'L' : '-',
+ (flags & SEND_VLAN_ID) ? 'V' :
+ (flags & SEND_MPLS_LABEL) ? 'M' :
+ (flags & SEND_Q_IN_Q_IDS) ? 'Q' : '-',
+ (flags & PROCESS_GARP_PKTS) ? 'g' : '-',
+ (flags & SEND_GRE_IPv4_HEADER) ? 'g' :
+ (flags & SEND_GRE_ETHER_HEADER) ? 'G' : '-',
+ (flags & CAPTURE_PKTS) ? 'C' : '-',
+ (flags & SEND_RANDOM_PKTS) ? 'R' : '-');
+
+ return buff;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_redisplay - Redisplay the screen or clear the screen.
+ *
+ * DESCRIPTION
+ * Redisplay the screen or clear the screen based on flag.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_redisplay(int cls_flag)
+{
+ if (wr_scrn_is_paused() )
+ return;
+
+ wr_scrn_pause();
+ if (cls_flag) {
+ wr_scrn_cls();
+ wr_scrn_pos(100, 1);
+ }
+ pktgen.flags |= PRINT_LABELS_FLAG;
+ wr_scrn_resume();
+
+ pktgen_page_display(NULL, NULL);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_update_display - Update the display, but do not clear screen.
+ *
+ * DESCRIPTION
+ * Update the display, but do not clear the screen.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_update_display(void)
+{
+ pktgen_redisplay(0);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_page_size - Set the number of ports per page.
+ *
+ * DESCRIPTION
+ * Set the max number of ports per page.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_page_size(uint32_t page_size)
+{
+ if ( (page_size > 0) && (page_size <= pktgen.nb_ports) &&
+ (page_size <= 6) ) {
+ pktgen.nb_ports_per_page = page_size;
+ pktgen.ending_port = pktgen.starting_port + page_size;
+ if (pktgen.ending_port >=
+ (pktgen.starting_port + pktgen.nb_ports) )
+ pktgen.ending_port =
+ (pktgen.starting_port + pktgen.nb_ports);
+ pktgen_redisplay(1);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_screen - Enable or Disable screen updates.
+ *
+ * DESCRIPTION
+ * Enable or disable screen updates.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_screen(const char *onOff)
+{
+ uint16_t rows;
+
+ pktgen_display_get_geometry(&rows, NULL);
+
+ if (parseState(onOff) == DISABLE_STATE) {
+ if (!wr_scrn_is_paused() ) {
+ wr_scrn_pause();
+ wr_scrn_cls();
+ wr_scrn_setw(1);
+ wr_scrn_pos(100, 1);
+ }
+ } else {
+ wr_scrn_cls();
+ wr_scrn_pos(100, 1);
+ wr_scrn_setw(pktgen.last_row + 1);
+ wr_scrn_resume();
+ pktgen_redisplay(1);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_port_number - Set the current port number for sequence and range pages
+ *
+ * DESCRIPTION
+ * Set the current port number for sequence and range pages.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_port_number(uint32_t port_number)
+{
+ if (port_number <= pktgen.nb_ports) {
+ pktgen.portNum = port_number;
+ pktgen_redisplay(1);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_icmp_echo - Set the ICMP echo response flag on a port
+ *
+ * DESCRIPTION
+ * Enable or disable the ICMP echo response flags for the given ports.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_icmp_echo(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE)
+ pktgen_set_port_flags(info, ICMP_ECHO_ENABLE_FLAG);
+ else
+ pktgen_clr_port_flags(info, ICMP_ECHO_ENABLE_FLAG);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_rx_tap - Enable or disable the Rx TAP interface
+ *
+ * DESCRIPTION
+ * Create and setup the Rx TAP interface.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_rx_tap(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ struct ifreq ifr;
+ int sockfd, i;
+ static const char *tapdevs[] =
+ { "/dev/net/tun", "/dev/tun", NULL };
+
+ for (i = 0; tapdevs[i]; i++)
+ if ( (info->rx_tapfd = open(tapdevs[i], O_RDWR)) >= 0)
+ break;
+ if (tapdevs[i] == NULL) {
+ pktgen_log_error("Unable to create TUN/TAP interface");
+ return;
+ }
+ memset(&ifr, 0, sizeof(struct ifreq));
+
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s%d", "pg_rxtap", info->pid);
+ if (ioctl(info->rx_tapfd, TUNSETIFF, (void *)&ifr) < 0) {
+ pktgen_log_error("Unable to set TUNSETIFF for %s",
+ ifr.ifr_name);
+ close(info->rx_tapfd);
+ info->rx_tapfd = 0;
+ return;
+ }
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ifr.ifr_flags = IFF_UP | IFF_RUNNING;
+ if (ioctl(sockfd, SIOCSIFFLAGS, (void *)&ifr) < 0) {
+ pktgen_log_error("Unable to set SIOCSIFFLAGS for %s",
+ ifr.ifr_name);
+ close(sockfd);
+ close(info->rx_tapfd);
+ info->rx_tapfd = 0;
+ return;
+ }
+ close(sockfd);
+ pktgen_set_port_flags(info, PROCESS_RX_TAP_PKTS);
+ } else {
+ if (rte_atomic32_read(&info->port_flags) &
+ PROCESS_RX_TAP_PKTS) {
+ close(info->rx_tapfd);
+ info->rx_tapfd = 0;
+ }
+ pktgen_clr_port_flags(info, PROCESS_RX_TAP_PKTS);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_tx_tap - Enable or disable the Tx TAP interface
+ *
+ * DESCRIPTION
+ * Create and setup the Tx TAP interface.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_tx_tap(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ struct ifreq ifr;
+ int sockfd, i;
+ static const char *tapdevs[] =
+ { "/dev/net/tun", "/dev/tun", NULL };
+
+ for (i = 0; tapdevs[i]; i++)
+ if ( (info->tx_tapfd = open(tapdevs[i], O_RDWR)) >= 0)
+ break;
+ if (tapdevs[i] == NULL) {
+ pktgen_log_error("Unable to create TUN/TAP interface.");
+ return;
+ }
+ memset(&ifr, 0, sizeof(struct ifreq));
+
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s%d", "pg_txtap", info->pid);
+ if (ioctl(info->tx_tapfd, TUNSETIFF, (void *)&ifr) < 0) {
+ pktgen_log_error("Unable to set TUNSETIFF for %s",
+ ifr.ifr_name);
+ close(info->tx_tapfd);
+ info->tx_tapfd = 0;
+ return;
+ }
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ifr.ifr_flags = IFF_UP | IFF_RUNNING;
+ if (ioctl(sockfd, SIOCSIFFLAGS, (void *)&ifr) < 0) {
+ pktgen_log_error("Unable to set SIOCSIFFLAGS for %s",
+ ifr.ifr_name);
+ close(sockfd);
+ close(info->tx_tapfd);
+ info->tx_tapfd = 0;
+ return;
+ }
+ close(sockfd);
+ pktgen_set_port_flags(info, PROCESS_TX_TAP_PKTS);
+ } else {
+ if (rte_atomic32_read(&info->port_flags) &
+ PROCESS_TX_TAP_PKTS) {
+ close(info->tx_tapfd);
+ info->tx_tapfd = 0;
+ }
+ pktgen_clr_port_flags(info, PROCESS_TX_TAP_PKTS);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_mac_from_arp - Enable or disable getting MAC from ARP requests.
+ *
+ * DESCRIPTION
+ * Enable or disable getting the MAC address from the ARP request packets.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_mac_from_arp(uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE)
+ pktgen.flags |= MAC_FROM_ARP_FLAG;
+ else
+ pktgen.flags &= ~MAC_FROM_ARP_FLAG;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_random - Enable/disable random bitfield mode
+ *
+ * DESCRIPTION
+ * Enable/disable random bitfield mode
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_random(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE)
+ pktgen_set_port_flags(info, SEND_RANDOM_PKTS);
+ else
+ pktgen_clr_port_flags(info, SEND_RANDOM_PKTS);
+}
+
+/*
+ * Local wrapper function to test mp is NULL and return or continue
+ * to call rte_mempool_dump() routine.
+ */
+static void
+__mempool_dump(FILE *f, struct rte_mempool *mp) {
+ if (mp == NULL)
+ return;
+ rte_mempool_dump(f, mp);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_mempool_dump - Display the mempool information
+ *
+ * DESCRIPTION
+ * Dump out the mempool information.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_mempool_dump(port_info_t *info, char *name)
+{
+ int all;
+ uint16_t q;
+
+ all = !strcmp(name, "all");
+
+ if (info->q[0].tx_mp == NULL)
+ return;
+
+ for (q = 0; q < wr_get_port_rxcnt(pktgen.l2p, info->pid); q++)
+ if (all || !strcmp(name, "rx") )
+ rte_mempool_dump(stdout, info->q[q].rx_mp);
+ for (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++) {
+ if (all ||
+ (!strcmp(name,
+ "tx") &&
+ (q < wr_get_port_txcnt(pktgen.l2p, info->pid))) )
+ __mempool_dump(stdout, info->q[q].tx_mp);
+ if (all || !strcmp(name, "range") )
+ __mempool_dump(stdout, info->q[q].range_mp);
+ if (all || !strcmp(name, "seq") )
+ __mempool_dump(stdout, info->q[q].seq_mp);
+ if (all || !strcmp(name, "arp") )
+ __mempool_dump(stdout, info->q[q].special_mp);
+ if (all || !strcmp(name, "pcap") )
+ __mempool_dump(stdout, info->q[q].pcap_mp);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_start_transmitting - Start a port transmitting packets.
+ *
+ * DESCRIPTION
+ * Start the given ports sending packets.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_start_transmitting(port_info_t *info)
+{
+ uint8_t q;
+
+ if (!(rte_atomic32_read(&info->port_flags) & SENDING_PACKETS) ) {
+ for (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)
+ pktgen_set_q_flags(info, q, CLEAR_FAST_ALLOC_FLAG);
+
+ rte_atomic64_set(&info->current_tx_count,
+ rte_atomic64_read(&info->transmit_count));
+
+ pktgen_set_port_flags(info, SENDING_PACKETS);
+
+ if (rte_atomic64_read(&info->current_tx_count) == 0)
+ pktgen_set_port_flags(info, SEND_FOREVER);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_stop_transmitting - Stop port transmitting packets.
+ *
+ * DESCRIPTION
+ * Stop the given ports from sending traffic.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_stop_transmitting(port_info_t *info)
+{
+ uint8_t q;
+
+ if (rte_atomic32_read(&info->port_flags) & SENDING_PACKETS) {
+ pktgen_clr_port_flags(info, (SENDING_PACKETS | SEND_FOREVER));
+ for (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)
+ pktgen_set_q_flags(info, q, DO_TX_FLUSH);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_prime_ports - Send a small number of packets to setup forwarding tables
+ *
+ * DESCRIPTION
+ * Send a small number of packets from a port to setup the forwarding tables in
+ * the device under test.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_prime_ports(port_info_t *info)
+{
+ uint8_t q;
+
+ for (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)
+ pktgen_set_q_flags(info, q, CLEAR_FAST_ALLOC_FLAG);
+ rte_atomic64_set(&info->current_tx_count, info->prime_cnt);
+ pktgen_set_port_flags(info, SENDING_PACKETS);
+ rte_delay_ms(300);
+ for (q = 0; q < wr_get_port_txcnt(pktgen.l2p, info->pid); q++)
+ pktgen_set_q_flags(info, q, DO_TX_FLUSH);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_proto - Set up the protocol type for a port/packet.
+ *
+ * DESCRIPTION
+ * Setup all single packets with a protocol types with the port list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_proto(port_info_t *info, char type)
+{
+ info->seq_pkt[SINGLE_PKT].ipProto = (type == 'u') ? PG_IPPROTO_UDP :
+ (type == 'i') ? PG_IPPROTO_ICMP :
+ (type == 't') ? PG_IPPROTO_TCP :
+ /* TODO print error: unknown type */ PG_IPPROTO_TCP;
+
+ /* ICMP only works on IPv4 packets. */
+ if (type == 'i')
+ info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
+
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_proto_range - Set up the protocol type for a port/packet.
+ *
+ * DESCRIPTION
+ * Setup all range packets with a protocol types with the port list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_proto_range(port_info_t *info, char type)
+{
+ info->seq_pkt[RANGE_PKT].ipProto = (type == 'u') ? PG_IPPROTO_UDP :
+ (type == 'i') ? PG_IPPROTO_ICMP :
+ (type == 't') ? PG_IPPROTO_TCP :
+ /* TODO print error: unknown type */ PG_IPPROTO_TCP;
+ info->range.ip_proto = info->seq_pkt[RANGE_PKT].ipProto;
+
+ /* ICMP only works on IPv4 packets. */
+ if (type == 'i')
+ info->seq_pkt[RANGE_PKT].ethType = ETHER_TYPE_IPv4;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_pcap_enable_disable - Enable or disable PCAP sending of packets.
+ *
+ * DESCRIPTION
+ * Enable or disable PCAP packet sending.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_pcap_enable_disable(port_info_t *info, char *str)
+{
+ if ( (info->pcap != NULL) && (info->pcap->pkt_count != 0) ) {
+ if (parseState(str) == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_RANGE_PKTS);
+ pktgen_clr_port_flags(info, SEND_SEQ_PKTS);
+ pktgen_set_port_flags(info, SEND_PCAP_PKTS);
+ } else
+ pktgen_clr_port_flags(info, SEND_PCAP_PKTS);
+ pktgen_packet_rate(info);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_pcap_filter - Compile a PCAP filter for a portlist
+ *
+ * DESCRIPTION
+ * Compile a pcap filter for a portlist
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_pcap_filter(port_info_t *info, char *str)
+{
+ pcap_t *pc = pcap_open_dead(DLT_EN10MB, 65535);
+
+ info->pcap_result = pcap_compile(pc,
+ &info->pcap_program,
+ str,
+ 1,
+ PCAP_NETMASK_UNKNOWN);
+
+ pcap_close(pc);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_blink_enable_disable - Enable or disable a port from blinking.
+ *
+ * DESCRIPTION
+ * Enable or disable the given ports from blinking.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_blink_enable_disable(port_info_t *info, char *str)
+{
+ if (parseState(str) == ENABLE_STATE)
+ pktgen.blinklist |= (1 << info->pid);
+ else {
+ pktgen.blinklist &= ~(1 << info->pid);
+ rte_eth_led_on(info->pid);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_process_enable_disable - Enable or disable input packet processing.
+ *
+ * DESCRIPTION
+ * Enable or disable input packet processing of ICMP, ARP, ...
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_process_enable_disable(port_info_t *info, char *str)
+{
+ if (parseState(str) == ENABLE_STATE)
+ pktgen_set_port_flags(info, PROCESS_INPUT_PKTS);
+ else
+ pktgen_clr_port_flags(info, PROCESS_INPUT_PKTS);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_garp_enable_disable - Enable or disable GARP packet processing.
+ *
+ * DESCRIPTION
+ * Enable or disable GARP packet processing of ICMP, ARP, ...
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_garp_enable_disable(port_info_t *info, char *str)
+{
+ if (parseState(str) == ENABLE_STATE)
+ pktgen_set_port_flags(info,
+ PROCESS_GARP_PKTS | PROCESS_INPUT_PKTS);
+ else
+ pktgen_clr_port_flags(info,
+ PROCESS_GARP_PKTS | PROCESS_INPUT_PKTS);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_pkt_type_range - Set the packet type value for range packets.
+ *
+ * DESCRIPTION
+ * Set the packet type value for the given port list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_pkt_type_range(port_info_t *info, const char *type)
+{
+ info->seq_pkt[RANGE_PKT].ethType = (type[0] == 'a') ? ETHER_TYPE_ARP :
+ (type[3] == '4') ? ETHER_TYPE_IPv4 :
+ (type[3] == '6') ? ETHER_TYPE_IPv6 :
+ /* TODO print error: unknown type */ ETHER_TYPE_IPv4;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_pkt_type - Set the packet type value.
+ *
+ * DESCRIPTION
+ * Set the packet type value for the given port list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_pkt_type(port_info_t *info, const char *type)
+{
+ info->seq_pkt[SINGLE_PKT].ethType = (type[0] == 'a') ? ETHER_TYPE_ARP :
+ (type[3] == '4') ? ETHER_TYPE_IPv4 :
+ (type[3] == '6') ? ETHER_TYPE_IPv6 :
+ /* TODO print error: unknown type */ ETHER_TYPE_IPv4;
+
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_vlan - Set the port to send a VLAN ID
+ *
+ * DESCRIPTION
+ * Set the given port list to send VLAN ID packets.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_vlan(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
+ pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
+ pktgen_set_port_flags(info, SEND_VLAN_ID);
+ } else
+ pktgen_clr_port_flags(info, SEND_VLAN_ID);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_vlanid - Set the port VLAN ID value
+ *
+ * DESCRIPTION
+ * Set the given port list with the given VLAN ID.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_vlanid(port_info_t *info, uint16_t vlanid)
+{
+ info->vlanid = vlanid;
+ info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_mpls - Set the port to send a mpls ID
+ *
+ * DESCRIPTION
+ * Set the given port list to send mpls ID packets.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_mpls(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_VLAN_ID);
+ pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
+ pktgen_set_port_flags(info, SEND_MPLS_LABEL);
+ } else
+ pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_mpls_entry - Set the port MPLS entry value
+ *
+ * DESCRIPTION
+ * Set the given port list with the given MPLS entry.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_mpls_entry(port_info_t *info, uint32_t mpls_entry)
+{
+ info->mpls_entry = mpls_entry;
+ info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_qinq - Set the port to send a Q-in-Q header
+ *
+ * DESCRIPTION
+ * Set the given port list to send Q-in-Q ID packets.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_qinq(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_VLAN_ID);
+ pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
+ pktgen_set_port_flags(info, SEND_Q_IN_Q_IDS);
+ } else
+ pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_qinqids - Set the port Q-in-Q ID values
+ *
+ * DESCRIPTION
+ * Set the given port list with the given Q-in-Q ID's.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_qinqids(port_info_t *info, uint16_t outerid, uint16_t innerid)
+{
+ info->qinq_outerid = outerid;
+ info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
+ info->qinq_innerid = innerid;
+ info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_gre - Set the port to send GRE with IPv4 payload
+ *
+ * DESCRIPTION
+ * Set the given port list to send GRE with IPv4 payload
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_gre(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
+ pktgen_set_port_flags(info, SEND_GRE_IPv4_HEADER);
+ } else
+ pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_gre_eth - Set the port to send GRE with Ethernet payload
+ *
+ * DESCRIPTION
+ * Set the given port list to send GRE with Ethernet payload
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_gre_eth(port_info_t *info, uint32_t onOff)
+{
+ if (onOff == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
+ pktgen_set_port_flags(info, SEND_GRE_ETHER_HEADER);
+ } else
+ pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_gre_key - Set the port GRE key
+ *
+ * DESCRIPTION
+ * Set the given port list with the given GRE key.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_gre_key(port_info_t *info, uint32_t gre_key)
+{
+ info->gre_key = gre_key;
+ info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_clear_stats - Clear a given port list of stats.
+ *
+ * DESCRIPTION
+ * Clear the given port list of all statistics.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_clear_stats(port_info_t *info)
+{
+ memset(&info->sizes, 0, sizeof(port_sizes_t));
+ memset(&info->port_stats, 0, sizeof(eth_stats_t));
+ memset(&info->rate_stats, 0, sizeof(eth_stats_t));
+
+ rte_eth_stats_get(info->pid, &info->init_stats);
+ pktgen.max_total_ipackets = 0;
+ pktgen.max_total_opackets = 0;
+ info->max_ipackets = 0;
+ info->max_opackets = 0;
+ info->stats.dropped_pkts = 0;
+ info->stats.arp_pkts = 0;
+ info->stats.echo_pkts = 0;
+ info->stats.ip_pkts = 0;
+ info->stats.ipv6_pkts = 0;
+ info->stats.vlan_pkts = 0;
+ info->stats.unknown_pkts = 0;
+ info->stats.tx_failed = 0;
+
+ memset(&pktgen.cumm_rate_totals, 0, sizeof(eth_stats_t));
+
+ pktgen_update_display();
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_cls - Clear the screen.
+ *
+ * DESCRIPTION
+ * Clear the screen and redisplay the data.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_cls(void)
+{
+ if (wr_scrn_is_paused() ) {
+ wr_scrn_cls();
+ wr_scrn_pos(100, 1);
+ } else /* Update the display quickly. */
+ pktgen_redisplay(1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_update - Update the screen information
+ *
+ * DESCRIPTION
+ * Update the screen information
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_update(void)
+{
+ pktgen_page_display(NULL, NULL);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_port_defaults - Set all ports back to the default values.
+ *
+ * DESCRIPTION
+ * Reset the ports back to the defaults.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_port_defaults(uint32_t pid, uint8_t seq)
+{
+ port_info_t *info = &pktgen.info[pid];
+ pkt_seq_t *pkt = &info->seq_pkt[seq];
+ port_info_t *dst_info;
+
+ pkt->pktSize = MIN_PKT_SIZE;
+ pkt->sport = DEFAULT_SRC_PORT;
+ pkt->dport = DEFAULT_DST_PORT;
+ pkt->ipProto = PG_IPPROTO_TCP;
+ pkt->ethType = ETHER_TYPE_IPv4;
+ pkt->vlanid = DEFAULT_VLAN_ID;
+
+ rte_atomic64_set(&info->transmit_count, DEFAULT_TX_COUNT);
+ rte_atomic64_init(&info->current_tx_count);
+ info->tx_rate = DEFAULT_TX_RATE;
+ info->tx_burst = DEFAULT_PKT_BURST;
+ info->vlanid = DEFAULT_VLAN_ID;
+ info->seqCnt = 0;
+ info->seqIdx = 0;
+ info->prime_cnt = DEFAULT_PRIME_COUNT;
+ info->delta = 0;
+
+ pktgen_packet_rate(info);
+
+ pkt->ip_mask = DEFAULT_NETMASK;
+ if ( (pid & 1) == 0) {
+ pkt->ip_src_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | (pid << 8) | 1;
+ pkt->ip_dst_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | ((pid + 1) << 8) | 1;
+ dst_info = info + 1;
+ } else {
+ pkt->ip_src_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | (pid << 8) | 1;
+ pkt->ip_dst_addr.addr.ipv4.s_addr = DEFAULT_IP_ADDR | ((pid - 1) << 8) | 1;
+ dst_info = info - 1;
+ }
+
+ if (dst_info->seq_pkt != NULL)
+ ether_addr_copy(&dst_info->seq_pkt[SINGLE_PKT].eth_src_addr,
+ &pkt->eth_dst_addr);
+ else
+ memset(&pkt->eth_dst_addr, 0, sizeof(pkt->eth_dst_addr));
+
+ pktgen_packet_ctor(info, seq, -1);
+
+ pktgen.flags |= PRINT_LABELS_FLAG;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_ping4 - Send a IPv4 ICMP echo request.
+ *
+ * DESCRIPTION
+ * Send a IPv4 ICMP echo request packet.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_ping4(port_info_t *info)
+{
+ memcpy(&info->seq_pkt[PING_PKT],
+ &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
+ info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
+ pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
+ pktgen_set_port_flags(info, SEND_PING4_REQUEST);
+}
+
+#ifdef INCLUDE_PING6
+/**************************************************************************//**
+ *
+ * pktgen_ping6 - Send a IPv6 ICMP echo request packet.
+ *
+ * DESCRIPTION
+ * Send a IPv6 ICMP echo request packet for the given ports.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_ping6(port_info_t *info)
+{
+ memcpy(&info->pkt[PING_PKT],
+ &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
+ info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
+ pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
+ pktgen_set_port_flags(info, SEND_PING6_REQUEST);
+}
+
+#endif
+
+/**************************************************************************//**
+ *
+ * pktgen_reset - Reset all ports to the default state
+ *
+ * DESCRIPTION
+ * Reset all ports to the default state.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_reset(port_info_t *info)
+{
+ uint32_t s;
+
+ if (info == NULL)
+ info = &pktgen.info[0];
+
+ pktgen_stop_transmitting(info);
+
+ pktgen.flags &= ~MAC_FROM_ARP_FLAG;
+
+ /* Make sure the port is active and enabled. */
+ if (info->seq_pkt) {
+ info->seq_pkt[SINGLE_PKT].pktSize = MIN_PKT_SIZE;
+
+ for (s = 0; s < NUM_TOTAL_PKTS; s++)
+ pktgen_port_defaults(info->pid, s);
+
+ pktgen_range_setup(info);
+ pktgen_clear_stats(info);
+ }
+
+ pktgen.flags &= ~PRINT_LABELS_FLAG;
+ pktgen_update_display();
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_port_restart - Reset all ports
+ *
+ * DESCRIPTION
+ * Reset all ports
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_port_restart(port_info_t *info)
+{
+ if (info == NULL)
+ info = &pktgen.info[0];
+
+ pktgen_stop_transmitting(info);
+
+ rte_delay_ms(10);
+
+ /* Stop and start the device to flush TX and RX buffers from the device rings. */
+ rte_eth_dev_stop(info->pid);
+
+ rte_delay_us(250);
+
+ rte_eth_dev_start(info->pid);
+
+ pktgen.flags &= ~PRINT_LABELS_FLAG;
+ pktgen_update_display();
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_tx_count - Set the number of packets to transmit on a port.
+ *
+ * DESCRIPTION
+ * Set the transmit count for all ports in the list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_tx_count(port_info_t *info, uint32_t cnt)
+{
+ rte_atomic64_set(&info->transmit_count, cnt);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_port_seqCnt - Set the sequence count for a port
+ *
+ * DESCRIPTION
+ * Set a sequence count of packets for all ports in the list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_port_seqCnt(port_info_t *info, uint32_t cnt)
+{
+ if (cnt > NUM_SEQ_PKTS)
+ cnt = NUM_SEQ_PKTS;
+
+ info->seqCnt = cnt;
+ if (cnt) {
+ pktgen_clr_port_flags(info, SEND_RANGE_PKTS);
+ pktgen_clr_port_flags(info, SEND_PCAP_PKTS);
+ pktgen_set_port_flags(info, SEND_SEQ_PKTS);
+ } else
+ pktgen_clr_port_flags(info, SEND_SEQ_PKTS);
+ pktgen_packet_rate(info);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_port_prime - Set the number of packets to send on a prime command
+ *
+ * DESCRIPTION
+ * Set the number packets to send on the prime command for all ports in list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_port_prime(port_info_t *info, uint32_t cnt)
+{
+ if (cnt > MAX_PRIME_COUNT)
+ cnt = MAX_PRIME_COUNT;
+ else if (cnt == 0)
+ cnt = DEFAULT_PRIME_COUNT;
+
+ info->prime_cnt = cnt;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_port_dump - Set the number of received packets to dump to screen.
+ *
+ * DESCRIPTION
+ * Set the number of received packets to dump to screen.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_port_dump(port_info_t *info, uint32_t cnt)
+{
+ int i;
+
+ if (cnt > MAX_DUMP_PACKETS)
+ cnt = MAX_DUMP_PACKETS;
+
+ /* Prevent concurrency issues by setting the fields in this specific order */
+ info->dump_count = 0;
+ info->dump_tail = 0;
+ info->dump_head = 0;
+
+ for (i = 0; i < MAX_DUMP_PACKETS; ++i)
+ if (info->dump_list->data != NULL) {
+ rte_free(info->dump_list->data);
+ info->dump_list->data = NULL;
+ }
+
+ info->dump_count = cnt;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_tx_burst - Set the transmit burst count.
+ *
+ * DESCRIPTION
+ * Set the transmit burst count for all packets.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_tx_burst(port_info_t *info, uint32_t burst)
+{
+ if (burst == 0)
+ burst = 1;
+ else if (burst > DEFAULT_PKT_BURST)
+ burst = DEFAULT_PKT_BURST;
+ info->tx_burst = burst;
+ pktgen_packet_rate(info);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_tx_cycles - Set the number of Transmit cycles to use.
+ *
+ * DESCRIPTION
+ * Set the number of transmit cycles for the given port list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_tx_cycles(port_info_t *info, uint32_t cycles)
+{
+ info->tx_cycles = cycles;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_pkt_size - Set the size of the packets to send.
+ *
+ * DESCRIPTION
+ * Set the pkt size for the single packet transmit.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_pkt_size(port_info_t *info, uint32_t size)
+{
+ if ( (size - FCS_SIZE) < MIN_PKT_SIZE)
+ size = (MIN_PKT_SIZE + FCS_SIZE);
+ else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
+ size = MAX_PKT_SIZE + FCS_SIZE;
+ info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+ pktgen_packet_rate(info);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_port_value - Set the port value for single or sequence packets.
+ *
+ * DESCRIPTION
+ * Set the port value for single or sequence packets for the ports listed.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_port_value(port_info_t *info, char type, uint32_t portValue)
+{
+ if (type == 'd')
+ info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
+ else
+ info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_tx_rate - Set the transmit rate as a percent value.
+ *
+ * DESCRIPTION
+ * Set the transmit rate as a percent value for all ports listed.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_tx_rate(port_info_t *info, uint32_t rate)
+{
+ if (rate == 0)
+ rate = 1;
+ else if (rate > 100)
+ rate = 100;
+ info->tx_rate = rate;
+ pktgen_packet_rate(info);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_ipaddr - Set the IP address for all ports listed
+ *
+ * DESCRIPTION
+ * Set an IP address for all ports listed in the call.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_ipaddr(port_info_t *info, char type, cmdline_ipaddr_t *ip)
+{
+ if (type == 's') {
+ info->seq_pkt[SINGLE_PKT].ip_mask = size_to_mask(ip->prefixlen);
+ info->seq_pkt[SINGLE_PKT].ip_src_addr.addr.ipv4.s_addr = ntohl(
+ ip->addr.ipv4.s_addr);
+ } else
+ info->seq_pkt[SINGLE_PKT].ip_dst_addr.addr.ipv4.s_addr = ntohl(
+ ip->addr.ipv4.s_addr);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_dst_mac - Setup the destination MAC address
+ *
+ * DESCRIPTION
+ * Set the destination MAC address for all ports given.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_dst_mac(port_info_t *info, cmdline_etheraddr_t *mac)
+{
+ memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
+ pktgen_packet_ctor(info, SINGLE_PKT, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_range_enable_disable - Enable or disable range packet sending.
+ *
+ * DESCRIPTION
+ * Enable or disable range packet sending.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_range_enable_disable(port_info_t *info, char *str)
+{
+ if (parseState(str) == ENABLE_STATE) {
+ pktgen_clr_port_flags(info, SEND_SEQ_PKTS);
+ pktgen_clr_port_flags(info, SEND_PCAP_PKTS);
+ pktgen_set_port_flags(info, SEND_RANGE_PKTS);
+ } else
+ pktgen_clr_port_flags(info, SEND_RANGE_PKTS);
+ pktgen_packet_rate(info);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_latency_enable_disable - Enable or disable latency testing.
+ *
+ * DESCRIPTION
+ * Enable or disable latency testing.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_latency_enable_disable(port_info_t *info, char *str)
+{
+ if (parseState(str) == ENABLE_STATE)
+ pktgen_set_port_flags(info, SEND_LATENCY_PKTS);
+ else
+ pktgen_clr_port_flags(info, SEND_LATENCY_PKTS);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_pattern_type - Set the pattern type per port.
+ *
+ * DESCRIPTION
+ * Set the given pattern type.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_pattern_type(port_info_t *info, char *str)
+{
+ if (strncmp(str, "abc", 3) == 0)
+ info->fill_pattern_type = ABC_FILL_PATTERN;
+ else if (strncmp(str, "none", 4) == 0)
+ info->fill_pattern_type = NO_FILL_PATTERN;
+ else if (strncmp(str, "user", 4) == 0)
+ info->fill_pattern_type = USER_FILL_PATTERN;
+ else if (strncmp(str, "zero", 4) == 0)
+ info->fill_pattern_type = ZERO_FILL_PATTERN;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_user_pattern_set - Set the user pattern string.
+ *
+ * DESCRIPTION
+ * Set the given user pattern string.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_user_pattern_set(port_info_t *info, char *str)
+{
+ char copy[USER_PATTERN_SIZE + 1], *cp;
+
+ memset(copy, 0, sizeof(copy));
+ strcpy(copy, str);
+ cp = ©[0];
+ if ( (cp[0] == '"') || (cp[0] == '\'') ) {
+ cp[strlen(cp) - 1] = 0;
+ cp++;
+ }
+ memset(info->user_pattern, 0, USER_PATTERN_SIZE);
+ strncpy(info->user_pattern, cp, USER_PATTERN_SIZE);
+ info->fill_pattern_type = USER_FILL_PATTERN;
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_dest_mac - Set the destination MAC address
+ *
+ * DESCRIPTION
+ * Set the destination MAC address for all ports given.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_dest_mac(port_info_t *info,
+ const char *what,
+ cmdline_etheraddr_t *mac)
+{
+ if (!strcmp(what, "min") )
+ inet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac_min);
+ else if (!strcmp(what, "max") )
+ inet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac_max);
+ else if (!strcmp(what, "inc") )
+ inet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac_inc);
+ else if (!strcmp(what, "start") ) {
+ inet_mtoh64((struct ether_addr *)mac, &info->range.dst_mac);
+ /* Changes add below to reflect MAC value in range */
+ memcpy(&info->seq_pkt[RANGE_PKT].eth_dst_addr, mac->mac, 6);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_src_mac - Set the source MAC address for the ports.
+ *
+ * DESCRIPTION
+ * Set the source MAC address for the ports given in the list.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_src_mac(port_info_t *info, const char *what,
+ cmdline_etheraddr_t *mac)
+{
+ if (!strcmp(what, "min") )
+ inet_mtoh64((struct ether_addr *)mac, &info->range.src_mac_min);
+ else if (!strcmp(what, "max") )
+ inet_mtoh64((struct ether_addr *)mac, &info->range.src_mac_max);
+ else if (!strcmp(what, "inc") )
+ inet_mtoh64((struct ether_addr *)mac, &info->range.src_mac_inc);
+ else if (!strcmp(what, "start") ) {
+ inet_mtoh64((struct ether_addr *)mac, &info->range.src_mac);
+ /* Changes add below to reflect MAC value in range */
+ memcpy(&info->seq_pkt[RANGE_PKT].eth_src_addr, mac->mac, 6);
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_src_ip - Set the source IP address value.
+ *
+ * DESCRIPTION
+ * Set the source IP address for all of the ports listed.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_src_ip(port_info_t *info, char *what, cmdline_ipaddr_t *ip)
+{
+ if (!strcmp(what, "min") )
+ info->range.src_ip_min = ntohl(ip->addr.ipv4.s_addr);
+ else if (!strcmp(what, "max") )
+ info->range.src_ip_max = ntohl(ip->addr.ipv4.s_addr);
+ else if (!strcmp(what, "inc") )
+ info->range.src_ip_inc = ntohl(ip->addr.ipv4.s_addr);
+ else if (!strcmp(what, "start") )
+ info->range.src_ip = ntohl(ip->addr.ipv4.s_addr);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_dst_ip - Set the destination IP address values
+ *
+ * DESCRIPTION
+ * Set the destination IP address values.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_dst_ip(port_info_t *info, char *what, cmdline_ipaddr_t *ip)
+{
+ if (!strcmp(what, "min") )
+ info->range.dst_ip_min = ntohl(ip->addr.ipv4.s_addr);
+ else if (!strcmp(what, "max") )
+ info->range.dst_ip_max = ntohl(ip->addr.ipv4.s_addr);
+ else if (!strcmp(what, "inc") )
+ info->range.dst_ip_inc = ntohl(ip->addr.ipv4.s_addr);
+ else if (!strcmp(what, "start") )
+ info->range.dst_ip = ntohl(ip->addr.ipv4.s_addr);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_src_port - Set the source IP port number for the ports
+ *
+ * DESCRIPTION
+ * Set the source IP port number for the ports listed.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_src_port(port_info_t *info, char *what, uint16_t port)
+{
+ if (!strcmp(what, "inc") ) {
+ if (port > 64)
+ port = 64;
+ info->range.src_port_inc = port;
+ } else {
+ if (!strcmp(what, "min") )
+ info->range.src_port_min = port;
+ else if (!strcmp(what, "max") )
+ info->range.src_port_max = port;
+ else if (!strcmp(what, "start") )
+ info->range.src_port = port;
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_gtpu_teid - Set the TEID for GTPU header
+ *
+ * DESCRIPTION
+ * Set the GTP-U TEID for the ports listed.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_gtpu_teid(port_info_t *info, char *what, uint32_t teid)
+{
+ if (!strcmp(what, "inc") ) {
+ if (teid != 0)
+ info->range.gtpu_teid_inc = teid;
+ } else {
+ if (!strcmp(what, "min") )
+ info->range.gtpu_teid_min = teid;
+ else if (!strcmp(what, "max") )
+ info->range.gtpu_teid_max = teid;
+ else if (!strcmp(what, "start") ) {
+ info->range.gtpu_teid = teid;
+ info->seq_pkt[RANGE_PKT].gtpu_teid = teid;
+ }
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_dst_port - Set the destination port value
+ *
+ * DESCRIPTION
+ * Set the destination port values.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_dst_port(port_info_t *info, char *what, uint16_t port)
+{
+ if (!strcmp(what, "inc") ) {
+ if (port > 64)
+ port = 64;
+ info->range.dst_port_inc = port;
+ } else {
+ if (!strcmp(what, "min") )
+ info->range.dst_port_min = port;
+ else if (!strcmp(what, "max") )
+ info->range.dst_port_max = port;
+ else if (!strcmp(what, "start") )
+ info->range.dst_port = port;
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_vlan_id - Set the VLAN id value
+ *
+ * DESCRIPTION
+ * Set the VLAN id values.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_vlan_id(port_info_t *info, char *what, uint16_t id)
+{
+ if (!strcmp(what, "inc") ) {
+ if (id > 64)
+ id = 64;
+ info->range.vlan_id_inc = id;
+ } else {
+ if ( (id < MIN_VLAN_ID) || (id > MAX_VLAN_ID) )
+ id = MIN_VLAN_ID;
+
+ if (!strcmp(what, "min") )
+ info->range.vlan_id_min = id;
+ else if (!strcmp(what, "max") )
+ info->range.vlan_id_max = id;
+ else if (!strcmp(what, "start") )
+ info->range.vlan_id = id;
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_range_pkt_size - Set the Packet size value
+ *
+ * DESCRIPTION
+ * Set the packet size values.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_range_pkt_size(port_info_t *info, char *what, uint16_t size)
+{
+ if (!strcmp(what, "inc") ) {
+ if (size > ETHER_MIN_LEN)
+ size = ETHER_MIN_LEN;
+
+ info->range.pkt_size_inc = size;
+ } else {
+ if (size < ETHER_MIN_LEN)
+ size = MIN_PKT_SIZE;
+ else if (size > ETHER_MAX_LEN)
+ size = MAX_PKT_SIZE;
+ else
+ size -= FCS_SIZE;
+
+ if (!strcmp(what, "start") )
+ info->range.pkt_size = size;
+ else if (!strcmp(what, "min") )
+ info->range.pkt_size_min = size;
+ else if (!strcmp(what, "max") )
+ info->range.pkt_size_max = size;
+ }
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_send_arp_requests - Send an ARP request for a given port.
+ *
+ * DESCRIPTION
+ * Using the port list do an ARp send for all ports.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_send_arp_requests(port_info_t *info, uint32_t type)
+{
+ if (type == GRATUITOUS_ARP)
+ pktgen_set_port_flags(info, SEND_GRATUITOUS_ARP);
+ else
+ pktgen_set_port_flags(info, SEND_ARP_REQUEST);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_page - Set the page type to display
+ *
+ * DESCRIPTION
+ * Set the page type ot display
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_page(char *str)
+{
+ uint16_t page;
+
+ if (str == NULL)
+ return;
+
+ page = atoi(str);
+ if (page > pktgen.nb_ports)
+ return;
+
+ /* Switch to the correct page */
+ if (str[0] == 'n') {
+ pcap_info_t *pcap = pktgen.info[pktgen.portNum].pcap;
+
+ if (pcap) {
+ if ( (pcap->pkt_idx + PCAP_PAGE_SIZE) < pcap->pkt_count)
+ pcap->pkt_idx += PCAP_PAGE_SIZE;
+ else
+ pcap->pkt_idx = 0;
+ }
+ pktgen.flags |= PRINT_LABELS_FLAG;
+ } else if ( (str[0] == 'c') && (str[1] == 'p') ) {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= CPU_PAGE_FLAG;
+ } else if (str[0] == 'p') {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= PCAP_PAGE_FLAG;
+ if (pktgen.info[pktgen.portNum].pcap)
+ pktgen.info[pktgen.portNum].pcap->pkt_idx = 0;
+ } else if ( ( str[0] == 'r' ) && (str[1] == 'a') ) {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= RANGE_PAGE_FLAG;
+ } else if (str[0] == 'c') {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= CONFIG_PAGE_FLAG;
+ } else if (str[0] == 's') {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= SEQUENCE_PAGE_FLAG;
+ } else if (str[0] == 'r') {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= RND_BITFIELD_PAGE_FLAG;
+ } else if (str[0] == 'l') {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= LOG_PAGE_FLAG;
+ } else {
+ uint16_t start_port;
+ if (str[0] == 'm')
+ page = 0;
+ start_port = (page * pktgen.nb_ports_per_page);
+ if ( (pktgen.starting_port != start_port) &&
+ (start_port < pktgen.nb_ports) ) {
+ pktgen.starting_port = start_port;
+ pktgen.ending_port = start_port +
+ pktgen.nb_ports_per_page;
+ if (pktgen.ending_port >
+ (pktgen.starting_port + pktgen.nb_ports) )
+ pktgen.ending_port =
+ (pktgen.starting_port +
+ pktgen.nb_ports);
+ }
+ if (pktgen.flags & PAGE_MASK_BITS) {
+ pktgen.flags &= ~PAGE_MASK_BITS;
+ pktgen.flags |= PRINT_LABELS_FLAG;
+ }
+ }
+ pktgen_redisplay(1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_set_seq - Set a sequence packet for given port
+ *
+ * DESCRIPTION
+ * Set the sequence packet information for all ports listed.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_set_seq(port_info_t *info, uint32_t seqnum,
+ cmdline_etheraddr_t *daddr, cmdline_etheraddr_t *saddr,
+ cmdline_ipaddr_t *ip_daddr, cmdline_ipaddr_t *ip_saddr,
+ uint32_t sport, uint32_t dport, char type, char proto,
+ uint16_t vlanid, uint32_t pktsize, uint32_t gtpu_teid)
+{
+ pkt_seq_t *pkt;
+
+ pkt = &info->seq_pkt[seqnum];
+ memcpy(&pkt->eth_dst_addr, daddr->mac, 6);
+ memcpy(&pkt->eth_src_addr, saddr->mac, 6);
+ pkt->ip_mask = size_to_mask(ip_saddr->prefixlen);
+ if (type == '4') {
+ pkt->ip_src_addr.addr.ipv4.s_addr = htonl(ip_saddr->addr.ipv4.s_addr);
+ pkt->ip_dst_addr.addr.ipv4.s_addr = htonl(ip_daddr->addr.ipv4.s_addr);
+ } else {
+ memcpy(&pkt->ip_src_addr.addr.ipv6.__in6_u.__u6_addr8,
+ ip_saddr->addr.ipv6.__in6_u.__u6_addr8, sizeof(struct in6_addr));
+ memcpy(&pkt->ip_dst_addr.addr.ipv6.__in6_u.__u6_addr8,
+ ip_daddr->addr.ipv6.__in6_u.__u6_addr8, sizeof(struct in6_addr));
+ }
+ pkt->dport = dport;
+ pkt->sport = sport;
+ pkt->pktSize = pktsize - FCS_SIZE;
+ pkt->ipProto = (proto == 'u') ? PG_IPPROTO_UDP :
+ (proto == 'i') ? PG_IPPROTO_ICMP : PG_IPPROTO_TCP;
+ /* Force the IP protocol to IPv4 if this is a ICMP packet. */
+ if (proto == 'i')
+ type = '4';
+ pkt->ethType = (type == '6') ? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
+ pkt->vlanid = vlanid;
+ pkt->gtpu_teid = gtpu_teid;
+ pktgen_packet_ctor(info, seqnum, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_compile_pkt - Compile a packet for a given port.
+ *
+ * DESCRIPTION
+ * Compile a packet for a given port.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_compile_pkt(port_info_t *info, uint32_t seqnum,
+ cmdline_etheraddr_t *daddr, cmdline_etheraddr_t *saddr,
+ cmdline_ipaddr_t *ip_daddr, cmdline_ipaddr_t *ip_saddr,
+ uint32_t sport, uint32_t dport, char type, char proto,
+ uint16_t vlanid, uint32_t pktsize, uint32_t gtpu_teid)
+{
+ pkt_seq_t *pkt;
+
+ if (seqnum >= NUM_EXTRA_TX_PKTS)
+ return;
+
+ pkt = &info->seq_pkt[seqnum + EXTRA_TX_PKT];
+
+ memcpy(&pkt->eth_dst_addr, daddr->mac, 6);
+ memcpy(&pkt->eth_src_addr, saddr->mac, 6);
+ pkt->ip_mask = size_to_mask(ip_saddr->prefixlen);
+ pkt->ip_src_addr.addr.ipv4.s_addr = htonl(ip_saddr->addr.ipv4.s_addr);
+ pkt->ip_dst_addr.addr.ipv4.s_addr = htonl(ip_daddr->addr.ipv4.s_addr);
+ pkt->dport = dport;
+ pkt->sport = sport;
+ pkt->pktSize = pktsize - FCS_SIZE;
+ pkt->ipProto = (proto == 'u') ? PG_IPPROTO_UDP :
+ (proto == 'i') ? PG_IPPROTO_ICMP : PG_IPPROTO_TCP;
+ /* Force the IP protocol to IPv4 if this is a ICMP packet. */
+ if (proto == 'i')
+ type = '4';
+ pkt->ethType = (type == '4') ? ETHER_TYPE_IPv4 :
+ (type == '6') ? ETHER_TYPE_IPv6 :
+ (type == 'n') ? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
+ pkt->vlanid = vlanid;
+ pkt->gtpu_teid = gtpu_teid;
+ pktgen_packet_ctor(info, seqnum, -1);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_send_pkt - Send a packet from the sequence array.
+ *
+ * DESCRIPTION
+ * Send a packet from the special pkt_seq_t structures. Seqnum is the 0-N
+ * index value into the info.seq_pkt[] array for EXTRA_TX_PKTS.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_send_pkt(port_info_t *info, uint32_t seqnum)
+{
+ pktgen_send_seq_pkt(info, seqnum + EXTRA_TX_PKT);
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_recv_pkt - Receive a packet from the sequence array.
+ *
+ * DESCRIPTION
+ * Receive a packet from the special pkt_seq_t structures.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_recv_pkt(port_info_t *info __rte_unused)
+{
+ pktgen_log_warning("Not working yet!");
+}
+
+/**************************************************************************//**
+ *
+ * pktgen_quit - Exit pktgen.
+ *
+ * DESCRIPTION
+ * Close and exit Pktgen.
+ *
+ * RETURNS: N/A
+ *
+ * SEE ALSO:
+ */
+
+void
+pktgen_quit(void)
+{
+ cmdline_quit(pktgen.cl);
+}
diff --git a/app/pktgen-cmds.h b/app/pktgen-cmds.h
index 683abc3..1c50e59 100644
--- a/app/pktgen-cmds.h
+++ b/app/pktgen-cmds.h
@@ -135,7 +135,7 @@ extern void pktgen_set_pkt_size(port_info_t *info, uint32_t size);
extern void pktgen_set_port_value(port_info_t *info,
char type,
uint32_t portValue);
-extern void pktgen_set_tx_rate(port_info_t *info, uint32_t rate);
+extern void pktgen_set_tx_rate(port_info_t *info, float rate);
extern void pktgen_set_ipaddr(port_info_t *info, char type,
cmdline_ipaddr_t *ip);
extern void pktgen_set_dst_mac(port_info_t *info, cmdline_etheraddr_t *mac);
diff --git a/app/pktgen-port-cfg.h b/app/pktgen-port-cfg.h
index bd5876c..a20286d 100644
--- a/app/pktgen-port-cfg.h
+++ b/app/pktgen-port-cfg.h
@@ -193,7 +193,7 @@ typedef struct port_info_s {
uint16_t pid; /**< Port ID value */
uint16_t tx_burst; /**< Number of TX burst packets */
uint8_t pad0;
- uint8_t tx_rate; /**< Percentage rate for tx packets */
+ float tx_rate; /**< Percentage rate for tx packets */
rte_atomic32_t port_flags; /**< Special send flags for ARP and other */
rte_atomic64_t transmit_count; /**< Packets to transmit loaded into current_tx_count */
diff --git a/app/pktgen.c b/app/pktgen.c
index a0705ab..a64e0ca 100644
--- a/app/pktgen.c
+++ b/app/pktgen.c
@@ -143,7 +143,7 @@ pktgen_packet_rate(port_info_t *info)
info->tx_pps = pps;
info->tx_cycles = ((cpp * info->tx_burst) /
wr_get_port_txcnt(pktgen.l2p, info->pid));
- info->tx_cycles -= ff[info->tx_rate / 10];
+ info->tx_cycles -= ff[(int)info->tx_rate / 10];
}
/**************************************************************************//**
--
1.9.1
next reply other threads:[~2016-04-21 15:34 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-21 15:33 inaki.murillo [this message]
2016-04-21 16:59 ` Wiles, Keith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1461252824-21992-1-git-send-email-inaki.murilloa@ehu.eus \
--to=inaki.murilloa@ehu.eus \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).