From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 9DBE81AEF4 for ; Fri, 8 Dec 2017 09:23:11 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from xuemingl@mellanox.com) with ESMTPS (AES256-SHA encrypted); 8 Dec 2017 10:23:10 +0200 Received: from dev-r630-06.mtbc.labs.mlnx (dev-r630-06.mtbc.labs.mlnx [10.12.205.180]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id vB88N9uX001040; Fri, 8 Dec 2017 10:23:09 +0200 Received: from dev-r630-06.mtbc.labs.mlnx (localhost [127.0.0.1]) by dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7) with ESMTP id vB88N8PC045204; Fri, 8 Dec 2017 16:23:09 +0800 Received: (from xuemingl@localhost) by dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7/Submit) id vB88N89O045203; Fri, 8 Dec 2017 16:23:08 +0800 From: Xueming Li To: Wu Jingjing , Harry van Haaren Cc: Xueming Li , dev@dpdk.org Date: Fri, 8 Dec 2017 16:22:23 +0800 Message-Id: <20171208082225.44913-8-xuemingl@mellanox.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20171208082225.44913-1-xuemingl@mellanox.com> References: <20171208082225.44913-1-xuemingl@mellanox.com> In-Reply-To: <20171019140649.26668-2-xuemingl@mellanox.com> References: <20171019140649.26668-2-xuemingl@mellanox.com> Subject: [dpdk-dev] [RFC v1 7/9] app/testpmd: add pktgen engine scapy commands X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Dec 2017 08:23:12 -0000 new commands: tx: send packets rx: receive packets expect: send and expect back Signed-off-by: Xueming Li Conflicts: app/test-pmd/Makefile app/test-pmd/testpmd.h --- app/test-pmd/Makefile | 5 + app/test-pmd/cmdline.c | 14 +- app/test-pmd/pktgen.c | 493 ++++++++++++++++++++++++++++++++++++++++++++++++- app/test-pmd/testpmd.h | 4 + 4 files changed, 512 insertions(+), 4 deletions(-) diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile index 2610a8d49..462f97418 100644 --- a/app/test-pmd/Makefile +++ b/app/test-pmd/Makefile @@ -65,6 +65,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c ifeq ($(CONFIG_RTE_LIBRTE_PMD_SOFTNIC)$(CONFIG_RTE_LIBRTE_SCHED),yy) SRCS-y += tm.c endif +ifeq ($(CONFIG_RTE_LIBRTE_PYTHON),y) +LDLIBS += -l$(CONFIG_RTE_LIBRTE_PYTHON_VERSION) +CFLAGS += -I/usr/include/$(CONFIG_RTE_LIBRTE_PYTHON_VERSION) +endif + ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index d0eb00c1f..b40fe1ac7 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -105,7 +105,7 @@ #include "cmdline_mtr.h" #include "cmdline_tm.h" -static struct cmdline *testpmd_cl; +struct cmdline *testpmd_cl; static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue); @@ -15595,6 +15595,12 @@ cmdline_parse_inst_t cmd_py_run = { /* ******************************************************************************** */ extern cmdline_parse_inst_t cmd_pktgen_cmd; +extern cmdline_parse_inst_t cmd_expect_short; +extern cmdline_parse_inst_t cmd_expect; +extern cmdline_parse_inst_t cmd_tx; +extern cmdline_parse_inst_t cmd_tx_short; +extern cmdline_parse_inst_t cmd_rx; +extern cmdline_parse_inst_t cmd_rx_short; /* list of instructions */ cmdline_parse_ctx_t main_ctx[] = { @@ -15604,6 +15610,12 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_load_from_file, #ifdef RTE_LIBRTE_PYTHON (cmdline_parse_inst_t *)&cmd_py_run, + (cmdline_parse_inst_t *)&cmd_expect_short, + (cmdline_parse_inst_t *)&cmd_expect, + (cmdline_parse_inst_t *)&cmd_tx_short, + (cmdline_parse_inst_t *)&cmd_tx, + (cmdline_parse_inst_t *)&cmd_rx_short, + (cmdline_parse_inst_t *)&cmd_rx, #endif (cmdline_parse_inst_t *)&cmd_pktgen_cmd, (cmdline_parse_inst_t *)&cmd_showport, diff --git a/app/test-pmd/pktgen.c b/app/test-pmd/pktgen.c index f4a1b00a9..423459b37 100644 --- a/app/test-pmd/pktgen.c +++ b/app/test-pmd/pktgen.c @@ -83,7 +83,6 @@ #define PKTGEN_ROUND_END 0x1 #define PKTGEN_TASK_END 0x0 #define PKTGEN_TASK_START 0x3 - struct pktgen_task_stats{ uint8_t active; uint16_t round; /* number txrx */ @@ -566,6 +565,495 @@ struct fwd_engine pktgen_engine = { /* Control thread functions */ /********************************************************/ +#ifdef RTE_LIBRTE_PYTHON + +#define US_TSC(us) ((us) * (rte_get_timer_hz() / 1000000L)); +#define TSC_US(tsc) ((tsc) * 1e6 / rte_get_timer_hz()) + +struct cmd_pktgen_cmd { + cmdline_fixed_string_t cmd; + cmdline_fixed_string_t pattern; + portid_t port; + uint64_t count; + uint64_t round; + uint16_t timeout; /* unit: ms */ + uint16_t verbose; + struct pktgen_task_stats stats; +}; + +struct cmd_pg_txrx_cmd { + cmdline_fixed_string_t expect; + struct cmd_pktgen_cmd tx; + struct cmd_pktgen_cmd rx; + cmdline_fixed_string_t field; + uint64_t val; +}; + +/* + * get min/max time and count sum + */ +static void +cmd_pg_port_poll(portid_t port, struct pktgen_task_stats *sum, int tx) +{ + struct pktgen_task* task; + queueid_t i, n; + + n = tx ? nb_txq : nb_rxq; + for (i = 0, sum->count = 0; i < n; i++) { + task = tx ? task_tx(port, i) : task_rx(port, i); + sum->count += task->stats.count; + if (task->stats.round > sum->round) + sum->round = task->stats.round; + if (task->stats.start) { + if (sum->start && task->stats.start < sum->start) + sum->start = task->stats.start; + if (!sum->start) + sum->start = task->stats.start; + if (sum->end < task->stats.end) + sum->end = task->stats.end; + } + } +} + +static int +cmd_pg_scapy_to_mbuf(char *scapy, portid_t port, struct pktgen_task *task) +{ + int socket; + struct rte_mempool *pool; + + socket = port_numa[port]; + if (socket == NUMA_NO_CONFIG) + socket = ports[port].socket_id; + pool = mbuf_pool_find(socket); + task->data = rte_python_scapy_to_mbufs(pool, scapy, &task->cnt_mbufs); + return !task->data; +} + +static inline int +cmd_pg_init(void) +{ + if (rte_python_init()) + return -1; + if (pktgen_idle_mode != 0) { + pg_idle_set(0); + rte_delay_ms(1); + } + if (cur_fwd_eng != &pktgen_engine) { + set_pkt_forwarding_mode(pktgen_engine.fwd_mode_name); + if (!test_done) + stop_packet_forwarding(); + } + if (test_done) + start_packet_forwarding(0); + /* reset task memory */ + RTE_ASSERT(pktgen_tx_tasks && pktgen_rx_tasks); + memset(pktgen_tx_tasks, 0, + nb_ports * nb_txq * sizeof(struct pktgen_task)); + memset(pktgen_rx_tasks, 0, + nb_ports * nb_rxq * sizeof(struct pktgen_task)); + return 0; +} + +static void +cmd_pg_cleanup(struct cmd_pg_txrx_cmd *cmd) +{ + struct pktgen_task *task; + queueid_t q; + uint16_t m; + + RTE_ASSERT(pktgen_tx_tasks && pktgen_rx_tasks); + /* free all tx queue mbufs */ + for (q = 0; cmd->tx.count && q < nb_txq; q++) { + task = task_tx(cmd->tx.port, q); + if (!task->data) + continue; + m = task->cnt_mbufs; + while(m) + rte_pktmbuf_free(pg_task_template_get(task, --m)); + task->data = NULL; + } +} + +static void +cmd_pg_rx(struct cmd_pg_txrx_cmd *cmd) +{ + struct pktgen_task *task; + int i; + + RTE_ASSERT(cmd); + memset(&cmd->rx.stats, 0, sizeof(cmd->rx.stats)); + for (i = 0; i < nb_rxq; i++) { + task = task_rx(cmd->rx.port, i); + if (cmd->tx.count) + task->data = task_tx(cmd->tx.port, 0); + task->count = cmd->rx.count; + task->round = cmd->rx.round; + task->verbose = cmd->rx.verbose & 0xff; + if (cmd->field && strlen(cmd->field)) { + task->field = cmd->field; + task->val = cmd->val; + } + task->stats.active = PKTGEN_TASK_START; + } +} + +static int +cmd_pg_tx(struct cmd_pktgen_cmd* cmd, int txrx) +{ + struct pktgen_task *task; + + RTE_ASSERT(cmd); + task = task_tx(cmd->port, 0); + if (cmd_pg_scapy_to_mbuf(cmd->pattern, cmd->port, task)) + return -1; + /* send out using queue 0 */ + memset(&cmd->stats, 0, sizeof(cmd->stats)); + if (cmd->count == UINT64_MAX) + cmd->count = task->cnt_mbufs; + task->count = cmd->count; + task->round = cmd->round; + task->verbose = cmd->verbose & 0xff; + task->txrx = txrx; + task->stats.active = PKTGEN_TASK_START; + return 0; +} + +static void +cmd_pg_wait(struct cmdline *cl, struct cmd_pktgen_cmd* cmd, + uint64_t timeout, int tx) +{ + char c = 0; + int flags; + + flags = fcntl(cl->s_in, F_GETFL, 0); + RTE_ASSERT(flags >= 0); + fcntl(cl->s_in, F_SETFL, flags | O_NONBLOCK); + memset(&cmd->stats, 0, sizeof(cmd->stats)); + while (1) { + cmd_pg_port_poll(cmd->port, &cmd->stats, tx); + if (cmd->count && cmd->round == cmd->stats.round) + break; + if (timeout && rte_rdtsc() > timeout) + break; + /* detect ctrl+c or ctrl+d */ + if (!timeout && read(cl->s_in, &c, 1) && (c == 3 || c == 4)) + break; + rte_delay_ms(1); + } + if (!cmd->stats.end) + cmd->stats.end = rte_rdtsc(); + fcntl(cl->s_in, F_SETFL, flags); +} + +/* expect command */ +cmdline_parse_token_string_t cmd_expect_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_pg_txrx_cmd, expect, "expect"); +cmdline_parse_token_num_t cmd_expect_tx_port = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.port, UINT16); +cmdline_parse_token_num_t cmd_expect_rx_port = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, rx.port, UINT16); +cmdline_parse_token_string_t cmd_expect_pattern = + TOKEN_STRING_INITIALIZER(struct cmd_pg_txrx_cmd, tx.pattern, NULL); +cmdline_parse_token_num_t cmd_expect_count = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.count, UINT64); +cmdline_parse_token_num_t cmd_expect_round = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.round, UINT64); +cmdline_parse_token_num_t cmd_expect_rx_timeout = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, rx.timeout, UINT64); +cmdline_parse_token_num_t cmd_expect_verbose = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.verbose, UINT16); +cmdline_parse_token_string_t cmd_expect_field = + TOKEN_STRING_INITIALIZER(struct cmd_pg_txrx_cmd, field, NULL); +cmdline_parse_token_num_t cmd_expect_val = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, val, UINT64); + +static void +cmd_expect_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pg_txrx_cmd *cmd = parsed_result; + struct pktgen_task_stats *stats_tx = &cmd->tx.stats; + struct pktgen_task_stats *stats_rx = &cmd->rx.stats; + uint64_t timeout = 0; + + if (port_id_is_invalid(cmd->tx.port, ENABLED_WARN) || + port_id_is_invalid(cmd->rx.port, ENABLED_WARN)) + return; + if (cmd_pg_init()) + return; + if (!strcmp(cmd->field, "non") || !strcmp(cmd->field, "0")) + cmd->field[0] = 0; + cmd->rx.verbose = cmd->tx.verbose & 0xff; + cmd->tx.verbose = cmd->tx.verbose >> 8; + cmd->rx.round = cmd->tx.round; + cmd->rx.count = cmd->tx.count; + if (cmd->tx.count == 0) + cmd->tx.count = UINT64_MAX; + /* prepare task */ + if (cmd_pg_tx(&cmd->tx, 1)) + return; + if (cmd->rx.count == UINT64_MAX) + cmd->rx.count = cmd->tx.count; + cmd_pg_rx(cmd); + /* wait task */ + if (cmd->rx.timeout) + timeout = rte_rdtsc() + US_TSC(cmd->rx.timeout * 1000) ; + pktgen_busy = 1; + cmd_pg_wait(cl, &cmd->tx, timeout, 1); + cmd_pg_wait(cl, &cmd->rx, timeout, 0); + pktgen_busy = 0; + /* print stats */ + float t_tx = TSC_US(stats_tx->end - stats_tx->start); + float t_rx = TSC_US(stats_rx->end - stats_rx->start); + float t_ttl = TSC_US(RTE_MAX(stats_rx->end, stats_tx->end) - + RTE_MIN(stats_rx->start, stats_tx->start)); + if (cmd->rx.count == 0) + stats_rx->round = 1; + int failed = (stats_tx->round != cmd->tx.round || + stats_rx->round != cmd->rx.round || + stats_rx->count != cmd->rx.count); + if (stats_tx->round == 0) + stats_tx->round = 1; + if (stats_rx->round == 0) + stats_rx->round = 1; + uint64_t nb_tx = stats_tx->count + cmd->tx.count * (stats_tx->round - 1); + uint64_t nb_rx = stats_rx->count + cmd->rx.count * (stats_rx->round - 1); + if (failed || !(verbose_level & 0x40)) /* mute */ + printf("%s" + "tx: %lu/%lu %.3fus %fmpps" + "\trx: %lu/%lu %.3fus %fmpps" + "\tround: %u/%lu %.3fus" + "\ttotal: %.3fus %fmpps\n", + failed ? "Failed " : "", + nb_tx, cmd->tx.count * cmd->tx.round, t_tx, nb_tx/t_tx, + nb_rx, cmd->rx.count * cmd->rx.round, t_rx, nb_rx/t_rx, + stats_rx->round, cmd->rx.round, t_ttl / stats_rx->round, + t_ttl, nb_rx / t_ttl); + /* clean up */ + cmd_pg_cleanup(cmd); +} + +cmdline_parse_inst_t cmd_expect = { + .f = cmd_expect_parsed, + .data = NULL, + .help_str = "expect \n" + "\t\t\tSend packet and expecting same back", + .tokens = { + (void *)&cmd_expect_cmd, + (void *)&cmd_expect_tx_port, + (void *)&cmd_expect_rx_port, + (void *)&cmd_expect_pattern, + (void *)&cmd_expect_count, + (void *)&cmd_expect_round, + (void *)&cmd_expect_rx_timeout, + (void *)&cmd_expect_verbose, + (void *)&cmd_expect_field, + (void *)&cmd_expect_val, + NULL, + }, +}; + +static void +cmd_expect_short_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pg_txrx_cmd *res = parsed_result; + + /* memory not clean, have to clear unused fields */ + res->tx.round = 1; + res->tx.count = UINT64_MAX; /* detect from pattern */ + res->tx.verbose = verbose_level; + res->rx.timeout = 20; + res->rx.verbose = verbose_level & 0xff; + res->field[0] = 0; + cmd_expect_parsed(res, cl, data); + +} + +cmdline_parse_inst_t cmd_expect_short = { + .f = cmd_expect_short_parsed, + .data = NULL, + .help_str = "expect : tx 1 and expect 1", + .tokens = { + (void *)&cmd_expect_cmd, + (void *)&cmd_expect_tx_port, + (void *)&cmd_expect_rx_port, + (void *)&cmd_expect_pattern, + NULL, + }, +}; + +/* tx command */ + +cmdline_parse_token_string_t cmd_tx_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_pg_txrx_cmd, tx.cmd, "tx"); +cmdline_parse_token_string_t cmd_tx_pattern = + TOKEN_STRING_INITIALIZER(struct cmd_pg_txrx_cmd, tx.pattern, NULL); +cmdline_parse_token_num_t cmd_tx_port = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.port, UINT16); +cmdline_parse_token_num_t cmd_tx_count = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.count, UINT64); +cmdline_parse_token_num_t cmd_tx_verbose = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, tx.verbose, UINT16); + +static void +cmd_tx_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pg_txrx_cmd *cmd = parsed_result; + + if (port_id_is_invalid(cmd->tx.port, ENABLED_WARN)) + return; + if (cmd_pg_init()) + return; + memset(&cmd->rx, 0, sizeof(cmd->rx)); + cmd->tx.round = 1; + if (cmd_pg_tx(&cmd->tx, 0)) + return; + pktgen_busy = 1; + cmd_pg_wait(cl, &cmd->tx, 0, 1); + pktgen_busy = 0; + double t = TSC_US(cmd->tx.stats.end - cmd->tx.stats.start); + printf("%s%lu/%lu packets sent in %.3fus %fmpps\n", + cmd->tx.count && cmd->tx.stats.count != cmd->tx.count ? + "Failed: " : "", + cmd->tx.stats.count, cmd->tx.count, t, + cmd->tx.stats.count / t); + cmd_pg_cleanup(cmd); +} + +cmdline_parse_inst_t cmd_tx = { + .f = cmd_tx_parsed, + .data = NULL, + .help_str = "tx ", + .tokens = { + (void *)&cmd_tx_cmd, + (void *)&cmd_tx_port, + (void *)&cmd_tx_pattern, + (void *)&cmd_tx_count, + (void *)&cmd_tx_verbose, + NULL, + }, +}; + +static void +cmd_tx_short_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pg_txrx_cmd *cmd = parsed_result; + + cmd->tx.count = 0; + cmd->tx.verbose = verbose_level >> 8; + cmd_tx_parsed(cmd, cl, data); +} + +cmdline_parse_inst_t cmd_tx_short = { + .f = cmd_tx_short_parsed, + .data = NULL, + .help_str = "tx : tx 0 Ether()/IP()/UDP()", + .tokens = { + (void *)&cmd_tx_cmd, + (void *)&cmd_tx_port, + (void *)&cmd_tx_pattern, + NULL, + }, +}; + +/* rx command */ +cmdline_parse_token_string_t cmd_rx_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_pg_txrx_cmd, rx, "rx"); +cmdline_parse_token_num_t cmd_rx_port = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, rx.port, UINT16); +cmdline_parse_token_num_t cmd_rx_count = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, rx.count, UINT64); +cmdline_parse_token_num_t cmd_rx_timeout = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, rx.timeout, UINT16); +cmdline_parse_token_num_t cmd_rx_verbose = + TOKEN_NUM_INITIALIZER(struct cmd_pg_txrx_cmd, rx.verbose, UINT16); + +/* Common result structure for rx commands */ +static void +cmd_rx_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pg_txrx_cmd *cmd = parsed_result; + uint64_t timeout = 0; + + if (port_id_is_invalid(cmd->rx.port, ENABLED_WARN)) + return; + if (cmd_pg_init()) + return; + memset(&cmd->tx, 0, sizeof(cmd->tx)); + cmd->field[0] = 0; + cmd->rx.round = 1; + cmd_pg_rx(cmd); + if (cmd->rx.timeout) + timeout = rte_rdtsc() + US_TSC(cmd->rx.timeout * 1e6); + pktgen_busy = 1; + cmd_pg_wait(cl, &cmd->rx, timeout, 0); + pktgen_busy = 0; + /* print stats */ + float t = TSC_US(cmd->rx.stats.end - cmd->rx.stats.start); + printf("%s%lu/%lu packets received in %.3fus %fmpps\n", + cmd->rx.count && cmd->rx.stats.count != cmd->rx.count ? + "Failed: " : "", + cmd->rx.stats.count, cmd->rx.count, t, + t ? cmd->rx.stats.count / t : 0); + /* clean up */ + cmd_pg_cleanup(cmd); +} + +cmdline_parse_inst_t cmd_rx = { + .f = cmd_rx_parsed, + .data = NULL, + .help_str = "rx ", + .tokens = { + (void *)&cmd_rx_cmd, + (void *)&cmd_rx_port, + (void *)&cmd_rx_count, + (void *)&cmd_rx_timeout, + (void *)&cmd_rx_verbose, + NULL, + }, +}; + +static void +cmd_rx_short_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pg_txrx_cmd *cmd = parsed_result; + + cmd->rx.count = 0; /* endless */ + cmd->rx.timeout = 0; /* endless */ + cmd->rx.verbose = verbose_level; + cmd_rx_parsed(cmd, cl, data); +} + +cmdline_parse_inst_t cmd_rx_short = { + .f = cmd_rx_short_parsed, + .data = NULL, + .help_str = "rx ", + .tokens = { + (void *)&cmd_rx_cmd, + (void *)&cmd_rx_port, + NULL, + }, +}; + +#endif + /* "pktgen loopback" command */ struct cmd_pktgen_cmd_result { cmdline_fixed_string_t pktgen; @@ -588,8 +1076,7 @@ cmd_pktgen_cmd_parsed( { struct cmd_pktgen_cmd_result *res = parsed_result; - pktgen_idle_mode = res->mode; - printf("PktGen idle mode: %hhu\n", res->mode); + pg_idle_set(res->mode); } cmdline_parse_inst_t cmd_pktgen_cmd = { diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index ec83c212d..daa5d4e0c 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -34,6 +34,8 @@ #ifndef _TESTPMD_H_ #define _TESTPMD_H_ +#include + #include #include #include @@ -365,6 +367,8 @@ extern uint8_t flow_isolate_all; /**< set by "--flow-isolate-all */ extern uint8_t mp_anon; /**< set by "--mp-anon" parameter */ extern uint8_t no_link_check; /**