[RFC,2/4] net/bonding: move testpmd commands

Message ID 20220513075718.18674-3-david.marchand@redhat.com (mailing list archive)
State Superseded, archived
Delegated to: Andrew Rybchenko
Headers
Series Split driver specific commands out of testpmd |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

David Marchand May 13, 2022, 7:57 a.m. UTC
  Move related specific testpmd commands into this driver directory.
While at it, fix checkpatch warnings.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 app/test-pmd/cmdline.c                     | 1035 -------------------
 app/test-pmd/meson.build                   |    3 -
 drivers/net/bonding/meson.build            |    1 +
 drivers/net/bonding/rte_eth_bond_testpmd.c | 1037 ++++++++++++++++++++
 4 files changed, 1038 insertions(+), 1038 deletions(-)
 create mode 100644 drivers/net/bonding/rte_eth_bond_testpmd.c
  

Comments

humin (Q) May 13, 2022, 10:09 a.m. UTC | #1
Hi, David,

  I think net/bonding offer 'API' for APP to use the bonding.
    and use the specific PMD as slave device.
  The software framwork is like:
   APP
   ethdev
   bonding PMD
   PMD
   hardware

so, I think cmdlines for testpmd should not put in net/bonding.
  Thanks.

在 2022/5/13 15:57, David Marchand 写道:
> Move related specific testpmd commands into this driver directory.
> While at it, fix checkpatch warnings.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>   app/test-pmd/cmdline.c                     | 1035 -------------------
>   app/test-pmd/meson.build                   |    3 -
>   drivers/net/bonding/meson.build            |    1 +
>   drivers/net/bonding/rte_eth_bond_testpmd.c | 1037 ++++++++++++++++++++
>   4 files changed, 1038 insertions(+), 1038 deletions(-)
>   create mode 100644 drivers/net/bonding/rte_eth_bond_testpmd.c
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index ed62027834..ae4759fbfe 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -47,10 +47,6 @@
>   #include <cmdline_parse_etheraddr.h>
>   #include <cmdline_socket.h>
>   #include <cmdline.h>
> -#ifdef RTE_NET_BOND
> -#include <rte_eth_bond.h>
> -#include <rte_eth_bond_8023ad.h>
> -#endif
>   #if defined RTE_BUS_DPAA && defined RTE_NET_DPAA
>   #include <rte_pmd_dpaa.h>
>   #endif
> @@ -614,44 +610,6 @@ static void cmd_help_long_parsed(void *parsed_result,
>   			"   Show the bypass configuration for a bypass enabled NIC"
>   			" using the lowest port on the NIC.\n\n"
>   
> -#ifdef RTE_NET_BOND
> -			"create bonded device (mode) (socket)\n"
> -			"	Create a new bonded device with specific bonding mode and socket.\n\n"
> -
> -			"add bonding slave (slave_id) (port_id)\n"
> -			"	Add a slave device to a bonded device.\n\n"
> -
> -			"remove bonding slave (slave_id) (port_id)\n"
> -			"	Remove a slave device from a bonded device.\n\n"
> -
> -			"set bonding mode (value) (port_id)\n"
> -			"	Set the bonding mode on a bonded device.\n\n"
> -
> -			"set bonding primary (slave_id) (port_id)\n"
> -			"	Set the primary slave for a bonded device.\n\n"
> -
> -			"show bonding config (port_id)\n"
> -			"	Show the bonding config for port_id.\n\n"
> -
> -			"show bonding lacp info (port_id)\n"
> -			"	Show the bonding lacp information for port_id.\n\n"
> -
> -			"set bonding mac_addr (port_id) (address)\n"
> -			"	Set the MAC address of a bonded device.\n\n"
> -
> -			"set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)"
> -			"	Set Aggregation mode for IEEE802.3AD (mode 4)"
> -
> -			"set bonding balance_xmit_policy (port_id) (l2|l23|l34)\n"
> -			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
> -
> -			"set bonding mon_period (port_id) (value)\n"
> -			"	Set the bonding link status monitoring polling period in ms.\n\n"
> -
> -			"set bonding lacp dedicated_queues <port_id> (enable|disable)\n"
> -			"	Enable/disable dedicated queues for LACP control traffic.\n\n"
> -
> -#endif
>   			"set link-up port (port_id)\n"
>   			"	Set link up for a port.\n\n"
>   
> @@ -5925,985 +5883,6 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
>   	},
>   };
>   
> -#ifdef RTE_NET_BOND
> -/* *** SET BONDING MODE *** */
> -struct cmd_set_bonding_mode_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t mode;
> -	uint8_t value;
> -	portid_t port_id;
> -};
> -
> -static void cmd_set_bonding_mode_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bonding_mode_result *res = parsed_result;
> -	portid_t port_id = res->port_id;
> -	struct rte_port *port = &ports[port_id];
> -
> -	/*
> -	 * Bonding mode changed means resources of device changed, like whether
> -	 * started rte timer or not. Device should be restarted when resources
> -	 * of device changed.
> -	 */
> -	if (port->port_status != RTE_PORT_STOPPED) {
> -		fprintf(stderr,
> -			"\t Error: Can't set bonding mode when port %d is not stopped\n",
> -			port_id);
> -		return;
> -	}
> -
> -	/* Set the bonding mode for the relevant port. */
> -	if (0 != rte_eth_bond_mode_set(port_id, res->value))
> -		fprintf(stderr, "\t Failed to set bonding mode for port = %d.\n",
> -			port_id);
> -}
> -
> -cmdline_parse_token_string_t cmd_setbonding_mode_set =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
> -		set, "set");
> -cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_setbonding_mode_mode =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
> -		mode, "mode");
> -cmdline_parse_token_num_t cmd_setbonding_mode_value =
> -TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
> -		value, RTE_UINT8);
> -cmdline_parse_token_num_t cmd_setbonding_mode_port =
> -TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
> -		port_id, RTE_UINT16);
> -
> -cmdline_parse_inst_t cmd_set_bonding_mode = {
> -		.f = cmd_set_bonding_mode_parsed,
> -		.help_str = "set bonding mode <mode_value> <port_id>: "
> -			"Set the bonding mode for port_id",
> -		.data = NULL,
> -		.tokens = {
> -				(void *) &cmd_setbonding_mode_set,
> -				(void *) &cmd_setbonding_mode_bonding,
> -				(void *) &cmd_setbonding_mode_mode,
> -				(void *) &cmd_setbonding_mode_value,
> -				(void *) &cmd_setbonding_mode_port,
> -				NULL
> -		}
> -};
> -
> -/* *** SET BONDING SLOW_QUEUE SW/HW *** */
> -struct cmd_set_bonding_lacp_dedicated_queues_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t lacp;
> -	cmdline_fixed_string_t dedicated_queues;
> -	portid_t port_id;
> -	cmdline_fixed_string_t mode;
> -};
> -
> -static void cmd_set_bonding_lacp_dedicated_queues_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bonding_lacp_dedicated_queues_result *res = parsed_result;
> -	portid_t port_id = res->port_id;
> -	struct rte_port *port;
> -
> -	port = &ports[port_id];
> -
> -	/** Check if the port is not started **/
> -	if (port->port_status != RTE_PORT_STOPPED) {
> -		fprintf(stderr, "Please stop port %d first\n", port_id);
> -		return;
> -	}
> -
> -	if (!strcmp(res->mode, "enable")) {
> -		if (rte_eth_bond_8023ad_dedicated_queues_enable(port_id) == 0)
> -			printf("Dedicate queues for LACP control packets"
> -					" enabled\n");
> -		else
> -			printf("Enabling dedicate queues for LACP control "
> -					"packets on port %d failed\n", port_id);
> -	} else if (!strcmp(res->mode, "disable")) {
> -		if (rte_eth_bond_8023ad_dedicated_queues_disable(port_id) == 0)
> -			printf("Dedicated queues for LACP control packets "
> -					"disabled\n");
> -		else
> -			printf("Disabling dedicated queues for LACP control "
> -					"traffic on port %d failed\n", port_id);
> -	}
> -}
> -
> -cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_set =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> -		set, "set");
> -cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_lacp =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> -		lacp, "lacp");
> -cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_dedicated_queues =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> -		dedicated_queues, "dedicated_queues");
> -cmdline_parse_token_num_t cmd_setbonding_lacp_dedicated_queues_port_id =
> -TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> -		port_id, RTE_UINT16);
> -cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_mode =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> -		mode, "enable#disable");
> -
> -cmdline_parse_inst_t cmd_set_lacp_dedicated_queues = {
> -		.f = cmd_set_bonding_lacp_dedicated_queues_parsed,
> -		.help_str = "set bonding lacp dedicated_queues <port_id> "
> -			"enable|disable: "
> -			"Enable/disable dedicated queues for LACP control traffic for port_id",
> -		.data = NULL,
> -		.tokens = {
> -			(void *)&cmd_setbonding_lacp_dedicated_queues_set,
> -			(void *)&cmd_setbonding_lacp_dedicated_queues_bonding,
> -			(void *)&cmd_setbonding_lacp_dedicated_queues_lacp,
> -			(void *)&cmd_setbonding_lacp_dedicated_queues_dedicated_queues,
> -			(void *)&cmd_setbonding_lacp_dedicated_queues_port_id,
> -			(void *)&cmd_setbonding_lacp_dedicated_queues_mode,
> -			NULL
> -		}
> -};
> -
> -/* *** SET BALANCE XMIT POLICY *** */
> -struct cmd_set_bonding_balance_xmit_policy_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t balance_xmit_policy;
> -	portid_t port_id;
> -	cmdline_fixed_string_t policy;
> -};
> -
> -static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
> -	portid_t port_id = res->port_id;
> -	uint8_t policy;
> -
> -	if (!strcmp(res->policy, "l2")) {
> -		policy = BALANCE_XMIT_POLICY_LAYER2;
> -	} else if (!strcmp(res->policy, "l23")) {
> -		policy = BALANCE_XMIT_POLICY_LAYER23;
> -	} else if (!strcmp(res->policy, "l34")) {
> -		policy = BALANCE_XMIT_POLICY_LAYER34;
> -	} else {
> -		fprintf(stderr, "\t Invalid xmit policy selection");
> -		return;
> -	}
> -
> -	/* Set the bonding mode for the relevant port. */
> -	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
> -		fprintf(stderr,
> -			"\t Failed to set bonding balance xmit policy for port = %d.\n",
> -			port_id);
> -	}
> -}
> -
> -cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> -		set, "set");
> -cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> -		balance_xmit_policy, "balance_xmit_policy");
> -cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
> -TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> -		port_id, RTE_UINT16);
> -cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> -		policy, "l2#l23#l34");
> -
> -cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
> -		.f = cmd_set_bonding_balance_xmit_policy_parsed,
> -		.help_str = "set bonding balance_xmit_policy <port_id> "
> -			"l2|l23|l34: "
> -			"Set the bonding balance_xmit_policy for port_id",
> -		.data = NULL,
> -		.tokens = {
> -				(void *)&cmd_setbonding_balance_xmit_policy_set,
> -				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
> -				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
> -				(void *)&cmd_setbonding_balance_xmit_policy_port,
> -				(void *)&cmd_setbonding_balance_xmit_policy_policy,
> -				NULL
> -		}
> -};
> -
> -/* *** SHOW IEEE802.3 BONDING INFORMATION *** */
> -struct cmd_show_bonding_lacp_info_result {
> -	cmdline_fixed_string_t show;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t lacp;
> -	cmdline_fixed_string_t info;
> -	portid_t port_id;
> -};
> -
> -static void port_param_show(struct port_params *params)
> -{
> -	char buf[RTE_ETHER_ADDR_FMT_SIZE];
> -
> -	printf("\t\tsystem priority: %u\n", params->system_priority);
> -	rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, &params->system);
> -	printf("\t\tsystem mac address: %s\n", buf);
> -	printf("\t\tport key: %u\n", params->key);
> -	printf("\t\tport priority: %u\n", params->port_priority);
> -	printf("\t\tport number: %u\n", params->port_number);
> -}
> -
> -static void lacp_slave_info_show(struct rte_eth_bond_8023ad_slave_info *info)
> -{
> -	char a_state[256] = { 0 };
> -	char p_state[256] = { 0 };
> -	int a_len = 0;
> -	int p_len = 0;
> -	uint32_t i;
> -
> -	static const char * const state[] = {
> -		"ACTIVE",
> -		"TIMEOUT",
> -		"AGGREGATION",
> -		"SYNCHRONIZATION",
> -		"COLLECTING",
> -		"DISTRIBUTING",
> -		"DEFAULTED",
> -		"EXPIRED"
> -	};
> -	static const char * const selection[] = {
> -		"UNSELECTED",
> -		"STANDBY",
> -		"SELECTED"
> -	};
> -
> -	for (i = 0; i < RTE_DIM(state); i++) {
> -		if ((info->actor_state >> i) & 1)
> -			a_len += snprintf(&a_state[a_len],
> -						RTE_DIM(a_state) - a_len, "%s ",
> -						state[i]);
> -
> -		if ((info->partner_state >> i) & 1)
> -			p_len += snprintf(&p_state[p_len],
> -						RTE_DIM(p_state) - p_len, "%s ",
> -						state[i]);
> -	}
> -	printf("\tAggregator port id: %u\n", info->agg_port_id);
> -	printf("\tselection: %s\n", selection[info->selected]);
> -	printf("\tActor detail info:\n");
> -	port_param_show(&info->actor);
> -	printf("\t\tport state: %s\n", a_state);
> -	printf("\tPartner detail info:\n");
> -	port_param_show(&info->partner);
> -	printf("\t\tport state: %s\n", p_state);
> -	printf("\n");
> -}
> -
> -static void lacp_conf_show(struct rte_eth_bond_8023ad_conf *conf)
> -{
> -	printf("\tfast period: %u ms\n", conf->fast_periodic_ms);
> -	printf("\tslow period: %u ms\n", conf->slow_periodic_ms);
> -	printf("\tshort timeout: %u ms\n", conf->short_timeout_ms);
> -	printf("\tlong timeout: %u ms\n", conf->long_timeout_ms);
> -	printf("\taggregate wait timeout: %u ms\n",
> -			conf->aggregate_wait_timeout_ms);
> -	printf("\ttx period: %u ms\n", conf->tx_period_ms);
> -	printf("\trx marker period: %u ms\n", conf->rx_marker_period_ms);
> -	printf("\tupdate timeout: %u ms\n", conf->update_timeout_ms);
> -	switch (conf->agg_selection) {
> -	case AGG_BANDWIDTH:
> -		printf("\taggregation mode: bandwidth\n");
> -		break;
> -	case AGG_STABLE:
> -		printf("\taggregation mode: stable\n");
> -		break;
> -	case AGG_COUNT:
> -		printf("\taggregation mode: count\n");
> -		break;
> -	default:
> -		printf("\taggregation mode: invalid\n");
> -		break;
> -	}
> -
> -	printf("\n");
> -}
> -
> -static void cmd_show_bonding_lacp_info_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_show_bonding_lacp_info_result *res = parsed_result;
> -	struct rte_eth_bond_8023ad_slave_info slave_info;
> -	struct rte_eth_bond_8023ad_conf port_conf;
> -	portid_t slaves[RTE_MAX_ETHPORTS];
> -	portid_t port_id = res->port_id;
> -	int num_active_slaves;
> -	int bonding_mode;
> -	int i;
> -	int ret;
> -
> -	bonding_mode = rte_eth_bond_mode_get(port_id);
> -	if (bonding_mode != BONDING_MODE_8023AD) {
> -		fprintf(stderr, "\tBonding mode is not mode 4\n");
> -		return;
> -	}
> -
> -	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
> -			RTE_MAX_ETHPORTS);
> -	if (num_active_slaves < 0) {
> -		fprintf(stderr, "\tFailed to get active slave list for port = %u\n",
> -				port_id);
> -		return;
> -	}
> -	if (num_active_slaves == 0)
> -		fprintf(stderr, "\tIEEE802.3 port %u has no active slave\n",
> -			port_id);
> -
> -	printf("\tIEEE802.3 port: %u\n", port_id);
> -	ret = rte_eth_bond_8023ad_conf_get(port_id, &port_conf);
> -	if (ret) {
> -		fprintf(stderr, "\tGet bonded device %u info failed\n",
> -			port_id);
> -		return;
> -	}
> -	lacp_conf_show(&port_conf);
> -
> -	for (i = 0; i < num_active_slaves; i++) {
> -		ret = rte_eth_bond_8023ad_slave_info(port_id, slaves[i],
> -				&slave_info);
> -		if (ret) {
> -			fprintf(stderr, "\tGet slave device %u info failed\n",
> -				slaves[i]);
> -			return;
> -		}
> -		printf("\tSlave Port: %u\n", slaves[i]);
> -		lacp_slave_info_show(&slave_info);
> -	}
> -}
> -
> -cmdline_parse_token_string_t cmd_show_bonding_lacp_info_show =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> -		show, "show");
> -cmdline_parse_token_string_t cmd_show_bonding_lacp_info_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_show_bonding_lacp_info_lacp =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> -		bonding, "lacp");
> -cmdline_parse_token_string_t cmd_show_bonding_lacp_info_info =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> -		info, "info");
> -cmdline_parse_token_num_t cmd_show_bonding_lacp_info_port_id =
> -TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> -		port_id, RTE_UINT16);
> -
> -cmdline_parse_inst_t cmd_show_bonding_lacp_info = {
> -		.f = cmd_show_bonding_lacp_info_parsed,
> -		.help_str = "show bonding lacp info <port_id> : "
> -			"Show bonding IEEE802.3 information for port_id",
> -		.data = NULL,
> -		.tokens = {
> -			(void *)&cmd_show_bonding_lacp_info_show,
> -			(void *)&cmd_show_bonding_lacp_info_bonding,
> -			(void *)&cmd_show_bonding_lacp_info_lacp,
> -			(void *)&cmd_show_bonding_lacp_info_info,
> -			(void *)&cmd_show_bonding_lacp_info_port_id,
> -			NULL
> -		}
> -};
> -
> -/* *** SHOW NIC BONDING CONFIGURATION *** */
> -struct cmd_show_bonding_config_result {
> -	cmdline_fixed_string_t show;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t config;
> -	portid_t port_id;
> -};
> -
> -static void cmd_show_bonding_config_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_show_bonding_config_result *res = parsed_result;
> -	int bonding_mode, agg_mode;
> -	portid_t slaves[RTE_MAX_ETHPORTS];
> -	int num_slaves, num_active_slaves;
> -	int primary_id;
> -	int i;
> -	portid_t port_id = res->port_id;
> -
> -	/* Display the bonding mode.*/
> -	bonding_mode = rte_eth_bond_mode_get(port_id);
> -	if (bonding_mode < 0) {
> -		fprintf(stderr, "\tFailed to get bonding mode for port = %d\n",
> -			port_id);
> -		return;
> -	} else
> -		printf("\tBonding mode: %d\n", bonding_mode);
> -
> -	if (bonding_mode == BONDING_MODE_BALANCE ||
> -		bonding_mode == BONDING_MODE_8023AD) {
> -		int balance_xmit_policy;
> -
> -		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
> -		if (balance_xmit_policy < 0) {
> -			fprintf(stderr,
> -				"\tFailed to get balance xmit policy for port = %d\n",
> -				port_id);
> -			return;
> -		} else {
> -			printf("\tBalance Xmit Policy: ");
> -
> -			switch (balance_xmit_policy) {
> -			case BALANCE_XMIT_POLICY_LAYER2:
> -				printf("BALANCE_XMIT_POLICY_LAYER2");
> -				break;
> -			case BALANCE_XMIT_POLICY_LAYER23:
> -				printf("BALANCE_XMIT_POLICY_LAYER23");
> -				break;
> -			case BALANCE_XMIT_POLICY_LAYER34:
> -				printf("BALANCE_XMIT_POLICY_LAYER34");
> -				break;
> -			}
> -			printf("\n");
> -		}
> -	}
> -
> -	if (bonding_mode == BONDING_MODE_8023AD) {
> -		agg_mode = rte_eth_bond_8023ad_agg_selection_get(port_id);
> -		printf("\tIEEE802.3AD Aggregator Mode: ");
> -		switch (agg_mode) {
> -		case AGG_BANDWIDTH:
> -			printf("bandwidth");
> -			break;
> -		case AGG_STABLE:
> -			printf("stable");
> -			break;
> -		case AGG_COUNT:
> -			printf("count");
> -			break;
> -		}
> -		printf("\n");
> -	}
> -
> -	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
> -
> -	if (num_slaves < 0) {
> -		fprintf(stderr, "\tFailed to get slave list for port = %d\n",
> -			port_id);
> -		return;
> -	}
> -	if (num_slaves > 0) {
> -		printf("\tSlaves (%d): [", num_slaves);
> -		for (i = 0; i < num_slaves - 1; i++)
> -			printf("%d ", slaves[i]);
> -
> -		printf("%d]\n", slaves[num_slaves - 1]);
> -	} else {
> -		printf("\tSlaves: []\n");
> -
> -	}
> -
> -	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
> -			RTE_MAX_ETHPORTS);
> -
> -	if (num_active_slaves < 0) {
> -		fprintf(stderr,
> -			"\tFailed to get active slave list for port = %d\n",
> -			port_id);
> -		return;
> -	}
> -	if (num_active_slaves > 0) {
> -		printf("\tActive Slaves (%d): [", num_active_slaves);
> -		for (i = 0; i < num_active_slaves - 1; i++)
> -			printf("%d ", slaves[i]);
> -
> -		printf("%d]\n", slaves[num_active_slaves - 1]);
> -
> -	} else {
> -		printf("\tActive Slaves: []\n");
> -
> -	}
> -
> -	primary_id = rte_eth_bond_primary_get(port_id);
> -	if (primary_id < 0) {
> -		fprintf(stderr, "\tFailed to get primary slave for port = %d\n",
> -			port_id);
> -		return;
> -	} else
> -		printf("\tPrimary: [%d]\n", primary_id);
> -
> -}
> -
> -cmdline_parse_token_string_t cmd_showbonding_config_show =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
> -		show, "show");
> -cmdline_parse_token_string_t cmd_showbonding_config_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_showbonding_config_config =
> -TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
> -		config, "config");
> -cmdline_parse_token_num_t cmd_showbonding_config_port =
> -TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
> -		port_id, RTE_UINT16);
> -
> -cmdline_parse_inst_t cmd_show_bonding_config = {
> -		.f = cmd_show_bonding_config_parsed,
> -		.help_str = "show bonding config <port_id>: "
> -			"Show the bonding config for port_id",
> -		.data = NULL,
> -		.tokens = {
> -				(void *)&cmd_showbonding_config_show,
> -				(void *)&cmd_showbonding_config_bonding,
> -				(void *)&cmd_showbonding_config_config,
> -				(void *)&cmd_showbonding_config_port,
> -				NULL
> -		}
> -};
> -
> -/* *** SET BONDING PRIMARY *** */
> -struct cmd_set_bonding_primary_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t primary;
> -	portid_t slave_id;
> -	portid_t port_id;
> -};
> -
> -static void cmd_set_bonding_primary_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bonding_primary_result *res = parsed_result;
> -	portid_t master_port_id = res->port_id;
> -	portid_t slave_port_id = res->slave_id;
> -
> -	/* Set the primary slave for a bonded device. */
> -	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
> -		fprintf(stderr, "\t Failed to set primary slave for port = %d.\n",
> -			master_port_id);
> -		return;
> -	}
> -	init_port_config();
> -}
> -
> -cmdline_parse_token_string_t cmd_setbonding_primary_set =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
> -		set, "set");
> -cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_setbonding_primary_primary =
> -TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
> -		primary, "primary");
> -cmdline_parse_token_num_t cmd_setbonding_primary_slave =
> -TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
> -		slave_id, RTE_UINT16);
> -cmdline_parse_token_num_t cmd_setbonding_primary_port =
> -TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
> -		port_id, RTE_UINT16);
> -
> -cmdline_parse_inst_t cmd_set_bonding_primary = {
> -		.f = cmd_set_bonding_primary_parsed,
> -		.help_str = "set bonding primary <slave_id> <port_id>: "
> -			"Set the primary slave for port_id",
> -		.data = NULL,
> -		.tokens = {
> -				(void *)&cmd_setbonding_primary_set,
> -				(void *)&cmd_setbonding_primary_bonding,
> -				(void *)&cmd_setbonding_primary_primary,
> -				(void *)&cmd_setbonding_primary_slave,
> -				(void *)&cmd_setbonding_primary_port,
> -				NULL
> -		}
> -};
> -
> -/* *** ADD SLAVE *** */
> -struct cmd_add_bonding_slave_result {
> -	cmdline_fixed_string_t add;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t slave;
> -	portid_t slave_id;
> -	portid_t port_id;
> -};
> -
> -static void cmd_add_bonding_slave_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_add_bonding_slave_result *res = parsed_result;
> -	portid_t master_port_id = res->port_id;
> -	portid_t slave_port_id = res->slave_id;
> -
> -	/* add the slave for a bonded device. */
> -	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
> -		fprintf(stderr,
> -			"\t Failed to add slave %d to master port = %d.\n",
> -			slave_port_id, master_port_id);
> -		return;
> -	}
> -	init_port_config();
> -	set_port_slave_flag(slave_port_id);
> -}
> -
> -cmdline_parse_token_string_t cmd_addbonding_slave_add =
> -TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
> -		add, "add");
> -cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
> -TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
> -		bonding, "bonding");
> -cmdline_parse_token_string_t cmd_addbonding_slave_slave =
> -TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
> -		slave, "slave");
> -cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
> -TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
> -		slave_id, RTE_UINT16);
> -cmdline_parse_token_num_t cmd_addbonding_slave_port =
> -TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
> -		port_id, RTE_UINT16);
> -
> -cmdline_parse_inst_t cmd_add_bonding_slave = {
> -		.f = cmd_add_bonding_slave_parsed,
> -		.help_str = "add bonding slave <slave_id> <port_id>: "
> -			"Add a slave device to a bonded device",
> -		.data = NULL,
> -		.tokens = {
> -				(void *)&cmd_addbonding_slave_add,
> -				(void *)&cmd_addbonding_slave_bonding,
> -				(void *)&cmd_addbonding_slave_slave,
> -				(void *)&cmd_addbonding_slave_slaveid,
> -				(void *)&cmd_addbonding_slave_port,
> -				NULL
> -		}
> -};
> -
> -/* *** REMOVE SLAVE *** */
> -struct cmd_remove_bonding_slave_result {
> -	cmdline_fixed_string_t remove;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t slave;
> -	portid_t slave_id;
> -	portid_t port_id;
> -};
> -
> -static void cmd_remove_bonding_slave_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_remove_bonding_slave_result *res = parsed_result;
> -	portid_t master_port_id = res->port_id;
> -	portid_t slave_port_id = res->slave_id;
> -
> -	/* remove the slave from a bonded device. */
> -	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
> -		fprintf(stderr,
> -			"\t Failed to remove slave %d from master port = %d.\n",
> -			slave_port_id, master_port_id);
> -		return;
> -	}
> -	init_port_config();
> -	clear_port_slave_flag(slave_port_id);
> -}
> -
> -cmdline_parse_token_string_t cmd_removebonding_slave_remove =
> -		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
> -				remove, "remove");
> -cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
> -		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
> -				bonding, "bonding");
> -cmdline_parse_token_string_t cmd_removebonding_slave_slave =
> -		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
> -				slave, "slave");
> -cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
> -		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
> -				slave_id, RTE_UINT16);
> -cmdline_parse_token_num_t cmd_removebonding_slave_port =
> -		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
> -				port_id, RTE_UINT16);
> -
> -cmdline_parse_inst_t cmd_remove_bonding_slave = {
> -		.f = cmd_remove_bonding_slave_parsed,
> -		.help_str = "remove bonding slave <slave_id> <port_id>: "
> -			"Remove a slave device from a bonded device",
> -		.data = NULL,
> -		.tokens = {
> -				(void *)&cmd_removebonding_slave_remove,
> -				(void *)&cmd_removebonding_slave_bonding,
> -				(void *)&cmd_removebonding_slave_slave,
> -				(void *)&cmd_removebonding_slave_slaveid,
> -				(void *)&cmd_removebonding_slave_port,
> -				NULL
> -		}
> -};
> -
> -/* *** CREATE BONDED DEVICE *** */
> -struct cmd_create_bonded_device_result {
> -	cmdline_fixed_string_t create;
> -	cmdline_fixed_string_t bonded;
> -	cmdline_fixed_string_t device;
> -	uint8_t mode;
> -	uint8_t socket;
> -};
> -
> -static int bond_dev_num = 0;
> -
> -static void cmd_create_bonded_device_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_create_bonded_device_result *res = parsed_result;
> -	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
> -	int port_id;
> -	int ret;
> -
> -	if (test_done == 0) {
> -		fprintf(stderr, "Please stop forwarding first\n");
> -		return;
> -	}
> -
> -	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d",
> -			bond_dev_num++);
> -
> -	/* Create a new bonded device. */
> -	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
> -	if (port_id < 0) {
> -		fprintf(stderr, "\t Failed to create bonded device.\n");
> -		return;
> -	} else {
> -		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
> -				port_id);
> -
> -		/* Update number of ports */
> -		nb_ports = rte_eth_dev_count_avail();
> -		reconfig(port_id, res->socket);
> -		ret = rte_eth_promiscuous_enable(port_id);
> -		if (ret != 0)
> -			fprintf(stderr,
> -				"Failed to enable promiscuous mode for port %u: %s - ignore\n",
> -				port_id, rte_strerror(-ret));
> -
> -		ports[port_id].need_setup = 0;
> -		ports[port_id].port_status = RTE_PORT_STOPPED;
> -	}
> -
> -}
> -
> -cmdline_parse_token_string_t cmd_createbonded_device_create =
> -		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
> -				create, "create");
> -cmdline_parse_token_string_t cmd_createbonded_device_bonded =
> -		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
> -				bonded, "bonded");
> -cmdline_parse_token_string_t cmd_createbonded_device_device =
> -		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
> -				device, "device");
> -cmdline_parse_token_num_t cmd_createbonded_device_mode =
> -		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
> -				mode, RTE_UINT8);
> -cmdline_parse_token_num_t cmd_createbonded_device_socket =
> -		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
> -				socket, RTE_UINT8);
> -
> -cmdline_parse_inst_t cmd_create_bonded_device = {
> -		.f = cmd_create_bonded_device_parsed,
> -		.help_str = "create bonded device <mode> <socket>: "
> -			"Create a new bonded device with specific bonding mode and socket",
> -		.data = NULL,
> -		.tokens = {
> -				(void *)&cmd_createbonded_device_create,
> -				(void *)&cmd_createbonded_device_bonded,
> -				(void *)&cmd_createbonded_device_device,
> -				(void *)&cmd_createbonded_device_mode,
> -				(void *)&cmd_createbonded_device_socket,
> -				NULL
> -		}
> -};
> -
> -/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
> -struct cmd_set_bond_mac_addr_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t mac_addr;
> -	uint16_t port_num;
> -	struct rte_ether_addr address;
> -};
> -
> -static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bond_mac_addr_result *res = parsed_result;
> -	int ret;
> -
> -	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
> -		return;
> -
> -	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
> -
> -	/* check the return value and print it if is < 0 */
> -	if (ret < 0)
> -		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
> -			strerror(-ret));
> -}
> -
> -cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
> -		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
> -cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
> -		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
> -				"bonding");
> -cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
> -		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
> -				"mac_addr");
> -cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
> -		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result,
> -				port_num, RTE_UINT16);
> -cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
> -		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
> -
> -cmdline_parse_inst_t cmd_set_bond_mac_addr = {
> -		.f = cmd_set_bond_mac_addr_parsed,
> -		.data = (void *) 0,
> -		.help_str = "set bonding mac_addr <port_id> <mac_addr>",
> -		.tokens = {
> -				(void *)&cmd_set_bond_mac_addr_set,
> -				(void *)&cmd_set_bond_mac_addr_bonding,
> -				(void *)&cmd_set_bond_mac_addr_mac,
> -				(void *)&cmd_set_bond_mac_addr_portnum,
> -				(void *)&cmd_set_bond_mac_addr_addr,
> -				NULL
> -		}
> -};
> -
> -
> -/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
> -struct cmd_set_bond_mon_period_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t mon_period;
> -	uint16_t port_num;
> -	uint32_t period_ms;
> -};
> -
> -static void cmd_set_bond_mon_period_parsed(void *parsed_result,
> -		__rte_unused  struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bond_mon_period_result *res = parsed_result;
> -	int ret;
> -
> -	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
> -
> -	/* check the return value and print it if is < 0 */
> -	if (ret < 0)
> -		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
> -			strerror(-ret));
> -}
> -
> -cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
> -		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
> -				set, "set");
> -cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
> -		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
> -				bonding, "bonding");
> -cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
> -		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
> -				mon_period,	"mon_period");
> -cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
> -		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
> -				port_num, RTE_UINT16);
> -cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
> -		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
> -				period_ms, RTE_UINT32);
> -
> -cmdline_parse_inst_t cmd_set_bond_mon_period = {
> -		.f = cmd_set_bond_mon_period_parsed,
> -		.data = (void *) 0,
> -		.help_str = "set bonding mon_period <port_id> <period_ms>",
> -		.tokens = {
> -				(void *)&cmd_set_bond_mon_period_set,
> -				(void *)&cmd_set_bond_mon_period_bonding,
> -				(void *)&cmd_set_bond_mon_period_mon_period,
> -				(void *)&cmd_set_bond_mon_period_portnum,
> -				(void *)&cmd_set_bond_mon_period_period_ms,
> -				NULL
> -		}
> -};
> -
> -
> -
> -struct cmd_set_bonding_agg_mode_policy_result {
> -	cmdline_fixed_string_t set;
> -	cmdline_fixed_string_t bonding;
> -	cmdline_fixed_string_t agg_mode;
> -	uint16_t port_num;
> -	cmdline_fixed_string_t policy;
> -};
> -
> -
> -static void
> -cmd_set_bonding_agg_mode(void *parsed_result,
> -		__rte_unused struct cmdline *cl,
> -		__rte_unused void *data)
> -{
> -	struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result;
> -	uint8_t policy = AGG_BANDWIDTH;
> -
> -	if (!strcmp(res->policy, "bandwidth"))
> -		policy = AGG_BANDWIDTH;
> -	else if (!strcmp(res->policy, "stable"))
> -		policy = AGG_STABLE;
> -	else if (!strcmp(res->policy, "count"))
> -		policy = AGG_COUNT;
> -
> -	rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy);
> -}
> -
> -
> -cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set =
> -	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> -				set, "set");
> -cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding =
> -	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> -				bonding, "bonding");
> -
> -cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode =
> -	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> -				agg_mode, "agg_mode");
> -
> -cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum =
> -	TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> -				port_num, RTE_UINT16);
> -
> -cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string =
> -	TOKEN_STRING_INITIALIZER(
> -			struct cmd_set_bonding_balance_xmit_policy_result,
> -		policy, "stable#bandwidth#count");
> -
> -cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = {
> -	.f = cmd_set_bonding_agg_mode,
> -	.data = (void *) 0,
> -	.help_str = "set bonding mode IEEE802.3AD aggregator policy <port_id> <agg_name>",
> -	.tokens = {
> -			(void *)&cmd_set_bonding_agg_mode_set,
> -			(void *)&cmd_set_bonding_agg_mode_bonding,
> -			(void *)&cmd_set_bonding_agg_mode_agg_mode,
> -			(void *)&cmd_set_bonding_agg_mode_portnum,
> -			(void *)&cmd_set_bonding_agg_mode_policy_string,
> -			NULL
> -		}
> -};
> -
> -
> -#endif /* RTE_NET_BOND */
> -
>   /* *** SET FORWARDING MODE *** */
>   struct cmd_set_fwd_mode_result {
>   	cmdline_fixed_string_t set;
> @@ -17870,20 +16849,6 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
>   	(cmdline_parse_inst_t *)&cmd_set_bypass_event,
>   	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
>   	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
> -#ifdef RTE_NET_BOND
> -	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
> -	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
> -	(cmdline_parse_inst_t *) &cmd_show_bonding_lacp_info,
> -	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
> -	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
> -	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
> -	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
> -	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
> -	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
> -	(cmdline_parse_inst_t *) &cmd_set_bond_mon_period,
> -	(cmdline_parse_inst_t *) &cmd_set_lacp_dedicated_queues,
> -	(cmdline_parse_inst_t *) &cmd_set_bonding_agg_mode_policy,
> -#endif
>   	(cmdline_parse_inst_t *)&cmd_vlan_offload,
>   	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
>   	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
> diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
> index 46a7511e9a..07634332f3 100644
> --- a/app/test-pmd/meson.build
> +++ b/app/test-pmd/meson.build
> @@ -58,9 +58,6 @@ endif
>   if dpdk_conf.has('RTE_LIB_PDUMP')
>       deps += 'pdump'
>   endif
> -if dpdk_conf.has('RTE_NET_BOND')
> -    deps += 'net_bond'
> -endif
>   if dpdk_conf.has('RTE_NET_BNXT')
>       deps += 'net_bnxt'
>   endif
> diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
> index 402b44be1a..faea892295 100644
> --- a/drivers/net/bonding/meson.build
> +++ b/drivers/net/bonding/meson.build
> @@ -16,6 +16,7 @@ sources = files(
>           'rte_eth_bond_flow.c',
>           'rte_eth_bond_pmd.c',
>   )
> +testpmd_sources = files('rte_eth_bond_testpmd.c')
>   
>   deps += 'sched' # needed for rte_bitmap.h
>   deps += ['ip_frag']
> diff --git a/drivers/net/bonding/rte_eth_bond_testpmd.c b/drivers/net/bonding/rte_eth_bond_testpmd.c
> new file mode 100644
> index 0000000000..834e2da4e6
> --- /dev/null
> +++ b/drivers/net/bonding/rte_eth_bond_testpmd.c
> @@ -0,0 +1,1037 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2016 Intel Corporation.
> + */
> +
> +#include <rte_eth_bond.h>
> +#include <rte_eth_bond_8023ad.h>
> +
> +#include <cmdline_parse.h>
> +#include <cmdline_parse_etheraddr.h>
> +#include <cmdline_parse_num.h>
> +#include <cmdline_parse_string.h>
> +
> +#include "testpmd.h"
> +
> +/* *** SET BONDING MODE *** */
> +struct cmd_set_bonding_mode_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t mode;
> +	uint8_t value;
> +	portid_t port_id;
> +};
> +
> +static void cmd_set_bonding_mode_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bonding_mode_result *res = parsed_result;
> +	portid_t port_id = res->port_id;
> +	struct rte_port *port = &ports[port_id];
> +
> +	/*
> +	 * Bonding mode changed means resources of device changed, like whether
> +	 * started rte timer or not. Device should be restarted when resources
> +	 * of device changed.
> +	 */
> +	if (port->port_status != RTE_PORT_STOPPED) {
> +		fprintf(stderr,
> +			"\t Error: Can't set bonding mode when port %d is not stopped\n",
> +			port_id);
> +		return;
> +	}
> +
> +	/* Set the bonding mode for the relevant port. */
> +	if (rte_eth_bond_mode_set(port_id, res->value) != 0)
> +		fprintf(stderr, "\t Failed to set bonding mode for port = %d.\n",
> +			port_id);
> +}
> +
> +cmdline_parse_token_string_t cmd_setbonding_mode_set =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
> +		set, "set");
> +cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_setbonding_mode_mode =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
> +		mode, "mode");
> +cmdline_parse_token_num_t cmd_setbonding_mode_value =
> +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
> +		value, RTE_UINT8);
> +cmdline_parse_token_num_t cmd_setbonding_mode_port =
> +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
> +		port_id, RTE_UINT16);
> +
> +cmdline_parse_inst_t cmd_set_bonding_mode = {
> +		.f = cmd_set_bonding_mode_parsed,
> +		.help_str = "set bonding mode <mode_value> <port_id>: "
> +			"Set the bonding mode for port_id",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_setbonding_mode_set,
> +				(void *)&cmd_setbonding_mode_bonding,
> +				(void *)&cmd_setbonding_mode_mode,
> +				(void *)&cmd_setbonding_mode_value,
> +				(void *)&cmd_setbonding_mode_port,
> +				NULL
> +		}
> +};
> +
> +/* *** SET BONDING SLOW_QUEUE SW/HW *** */
> +struct cmd_set_bonding_lacp_dedicated_queues_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t lacp;
> +	cmdline_fixed_string_t dedicated_queues;
> +	portid_t port_id;
> +	cmdline_fixed_string_t mode;
> +};
> +
> +static void cmd_set_bonding_lacp_dedicated_queues_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bonding_lacp_dedicated_queues_result *res = parsed_result;
> +	portid_t port_id = res->port_id;
> +	struct rte_port *port;
> +
> +	port = &ports[port_id];
> +
> +	/** Check if the port is not started **/
> +	if (port->port_status != RTE_PORT_STOPPED) {
> +		fprintf(stderr, "Please stop port %d first\n", port_id);
> +		return;
> +	}
> +
> +	if (!strcmp(res->mode, "enable")) {
> +		if (rte_eth_bond_8023ad_dedicated_queues_enable(port_id) == 0)
> +			printf("Dedicate queues for LACP control packets"
> +					" enabled\n");
> +		else
> +			printf("Enabling dedicate queues for LACP control "
> +					"packets on port %d failed\n", port_id);
> +	} else if (!strcmp(res->mode, "disable")) {
> +		if (rte_eth_bond_8023ad_dedicated_queues_disable(port_id) == 0)
> +			printf("Dedicated queues for LACP control packets "
> +					"disabled\n");
> +		else
> +			printf("Disabling dedicated queues for LACP control "
> +					"traffic on port %d failed\n", port_id);
> +	}
> +}
> +
> +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_set =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> +		set, "set");
> +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_lacp =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> +		lacp, "lacp");
> +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_dedicated_queues =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> +		dedicated_queues, "dedicated_queues");
> +cmdline_parse_token_num_t cmd_setbonding_lacp_dedicated_queues_port_id =
> +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> +		port_id, RTE_UINT16);
> +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_mode =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
> +		mode, "enable#disable");
> +
> +cmdline_parse_inst_t cmd_set_lacp_dedicated_queues = {
> +		.f = cmd_set_bonding_lacp_dedicated_queues_parsed,
> +		.help_str = "set bonding lacp dedicated_queues <port_id> "
> +			"enable|disable: "
> +			"Enable/disable dedicated queues for LACP control traffic for port_id",
> +		.data = NULL,
> +		.tokens = {
> +			(void *)&cmd_setbonding_lacp_dedicated_queues_set,
> +			(void *)&cmd_setbonding_lacp_dedicated_queues_bonding,
> +			(void *)&cmd_setbonding_lacp_dedicated_queues_lacp,
> +			(void *)&cmd_setbonding_lacp_dedicated_queues_dedicated_queues,
> +			(void *)&cmd_setbonding_lacp_dedicated_queues_port_id,
> +			(void *)&cmd_setbonding_lacp_dedicated_queues_mode,
> +			NULL
> +		}
> +};
> +
> +/* *** SET BALANCE XMIT POLICY *** */
> +struct cmd_set_bonding_balance_xmit_policy_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t balance_xmit_policy;
> +	portid_t port_id;
> +	cmdline_fixed_string_t policy;
> +};
> +
> +static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
> +	portid_t port_id = res->port_id;
> +	uint8_t policy;
> +
> +	if (!strcmp(res->policy, "l2")) {
> +		policy = BALANCE_XMIT_POLICY_LAYER2;
> +	} else if (!strcmp(res->policy, "l23")) {
> +		policy = BALANCE_XMIT_POLICY_LAYER23;
> +	} else if (!strcmp(res->policy, "l34")) {
> +		policy = BALANCE_XMIT_POLICY_LAYER34;
> +	} else {
> +		fprintf(stderr, "\t Invalid xmit policy selection");
> +		return;
> +	}
> +
> +	/* Set the bonding mode for the relevant port. */
> +	if (rte_eth_bond_xmit_policy_set(port_id, policy) != 0) {
> +		fprintf(stderr,
> +			"\t Failed to set bonding balance xmit policy for port = %d.\n",
> +			port_id);
> +	}
> +}
> +
> +cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> +		set, "set");
> +cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> +		balance_xmit_policy, "balance_xmit_policy");
> +cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
> +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> +		port_id, RTE_UINT16);
> +cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> +		policy, "l2#l23#l34");
> +
> +cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
> +		.f = cmd_set_bonding_balance_xmit_policy_parsed,
> +		.help_str = "set bonding balance_xmit_policy <port_id> "
> +			"l2|l23|l34: "
> +			"Set the bonding balance_xmit_policy for port_id",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_setbonding_balance_xmit_policy_set,
> +				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
> +				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
> +				(void *)&cmd_setbonding_balance_xmit_policy_port,
> +				(void *)&cmd_setbonding_balance_xmit_policy_policy,
> +				NULL
> +		}
> +};
> +
> +/* *** SHOW IEEE802.3 BONDING INFORMATION *** */
> +struct cmd_show_bonding_lacp_info_result {
> +	cmdline_fixed_string_t show;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t lacp;
> +	cmdline_fixed_string_t info;
> +	portid_t port_id;
> +};
> +
> +static void port_param_show(struct port_params *params)
> +{
> +	char buf[RTE_ETHER_ADDR_FMT_SIZE];
> +
> +	printf("\t\tsystem priority: %u\n", params->system_priority);
> +	rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, &params->system);
> +	printf("\t\tsystem mac address: %s\n", buf);
> +	printf("\t\tport key: %u\n", params->key);
> +	printf("\t\tport priority: %u\n", params->port_priority);
> +	printf("\t\tport number: %u\n", params->port_number);
> +}
> +
> +static void lacp_slave_info_show(struct rte_eth_bond_8023ad_slave_info *info)
> +{
> +	char a_state[256] = { 0 };
> +	char p_state[256] = { 0 };
> +	int a_len = 0;
> +	int p_len = 0;
> +	uint32_t i;
> +
> +	static const char * const state[] = {
> +		"ACTIVE",
> +		"TIMEOUT",
> +		"AGGREGATION",
> +		"SYNCHRONIZATION",
> +		"COLLECTING",
> +		"DISTRIBUTING",
> +		"DEFAULTED",
> +		"EXPIRED"
> +	};
> +	static const char * const selection[] = {
> +		"UNSELECTED",
> +		"STANDBY",
> +		"SELECTED"
> +	};
> +
> +	for (i = 0; i < RTE_DIM(state); i++) {
> +		if ((info->actor_state >> i) & 1)
> +			a_len += snprintf(&a_state[a_len],
> +						RTE_DIM(a_state) - a_len, "%s ",
> +						state[i]);
> +
> +		if ((info->partner_state >> i) & 1)
> +			p_len += snprintf(&p_state[p_len],
> +						RTE_DIM(p_state) - p_len, "%s ",
> +						state[i]);
> +	}
> +	printf("\tAggregator port id: %u\n", info->agg_port_id);
> +	printf("\tselection: %s\n", selection[info->selected]);
> +	printf("\tActor detail info:\n");
> +	port_param_show(&info->actor);
> +	printf("\t\tport state: %s\n", a_state);
> +	printf("\tPartner detail info:\n");
> +	port_param_show(&info->partner);
> +	printf("\t\tport state: %s\n", p_state);
> +	printf("\n");
> +}
> +
> +static void lacp_conf_show(struct rte_eth_bond_8023ad_conf *conf)
> +{
> +	printf("\tfast period: %u ms\n", conf->fast_periodic_ms);
> +	printf("\tslow period: %u ms\n", conf->slow_periodic_ms);
> +	printf("\tshort timeout: %u ms\n", conf->short_timeout_ms);
> +	printf("\tlong timeout: %u ms\n", conf->long_timeout_ms);
> +	printf("\taggregate wait timeout: %u ms\n",
> +			conf->aggregate_wait_timeout_ms);
> +	printf("\ttx period: %u ms\n", conf->tx_period_ms);
> +	printf("\trx marker period: %u ms\n", conf->rx_marker_period_ms);
> +	printf("\tupdate timeout: %u ms\n", conf->update_timeout_ms);
> +	switch (conf->agg_selection) {
> +	case AGG_BANDWIDTH:
> +		printf("\taggregation mode: bandwidth\n");
> +		break;
> +	case AGG_STABLE:
> +		printf("\taggregation mode: stable\n");
> +		break;
> +	case AGG_COUNT:
> +		printf("\taggregation mode: count\n");
> +		break;
> +	default:
> +		printf("\taggregation mode: invalid\n");
> +		break;
> +	}
> +
> +	printf("\n");
> +}
> +
> +static void cmd_show_bonding_lacp_info_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_show_bonding_lacp_info_result *res = parsed_result;
> +	struct rte_eth_bond_8023ad_slave_info slave_info;
> +	struct rte_eth_bond_8023ad_conf port_conf;
> +	portid_t slaves[RTE_MAX_ETHPORTS];
> +	portid_t port_id = res->port_id;
> +	int num_active_slaves;
> +	int bonding_mode;
> +	int i;
> +	int ret;
> +
> +	bonding_mode = rte_eth_bond_mode_get(port_id);
> +	if (bonding_mode != BONDING_MODE_8023AD) {
> +		fprintf(stderr, "\tBonding mode is not mode 4\n");
> +		return;
> +	}
> +
> +	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
> +			RTE_MAX_ETHPORTS);
> +	if (num_active_slaves < 0) {
> +		fprintf(stderr, "\tFailed to get active slave list for port = %u\n",
> +				port_id);
> +		return;
> +	}
> +	if (num_active_slaves == 0)
> +		fprintf(stderr, "\tIEEE802.3 port %u has no active slave\n",
> +			port_id);
> +
> +	printf("\tIEEE802.3 port: %u\n", port_id);
> +	ret = rte_eth_bond_8023ad_conf_get(port_id, &port_conf);
> +	if (ret) {
> +		fprintf(stderr, "\tGet bonded device %u info failed\n",
> +			port_id);
> +		return;
> +	}
> +	lacp_conf_show(&port_conf);
> +
> +	for (i = 0; i < num_active_slaves; i++) {
> +		ret = rte_eth_bond_8023ad_slave_info(port_id, slaves[i],
> +				&slave_info);
> +		if (ret) {
> +			fprintf(stderr, "\tGet slave device %u info failed\n",
> +				slaves[i]);
> +			return;
> +		}
> +		printf("\tSlave Port: %u\n", slaves[i]);
> +		lacp_slave_info_show(&slave_info);
> +	}
> +}
> +
> +cmdline_parse_token_string_t cmd_show_bonding_lacp_info_show =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> +		show, "show");
> +cmdline_parse_token_string_t cmd_show_bonding_lacp_info_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_show_bonding_lacp_info_lacp =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> +		bonding, "lacp");
> +cmdline_parse_token_string_t cmd_show_bonding_lacp_info_info =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> +		info, "info");
> +cmdline_parse_token_num_t cmd_show_bonding_lacp_info_port_id =
> +TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
> +		port_id, RTE_UINT16);
> +
> +cmdline_parse_inst_t cmd_show_bonding_lacp_info = {
> +		.f = cmd_show_bonding_lacp_info_parsed,
> +		.help_str = "show bonding lacp info <port_id> : "
> +			"Show bonding IEEE802.3 information for port_id",
> +		.data = NULL,
> +		.tokens = {
> +			(void *)&cmd_show_bonding_lacp_info_show,
> +			(void *)&cmd_show_bonding_lacp_info_bonding,
> +			(void *)&cmd_show_bonding_lacp_info_lacp,
> +			(void *)&cmd_show_bonding_lacp_info_info,
> +			(void *)&cmd_show_bonding_lacp_info_port_id,
> +			NULL
> +		}
> +};
> +
> +/* *** SHOW NIC BONDING CONFIGURATION *** */
> +struct cmd_show_bonding_config_result {
> +	cmdline_fixed_string_t show;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t config;
> +	portid_t port_id;
> +};
> +
> +static void cmd_show_bonding_config_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_show_bonding_config_result *res = parsed_result;
> +	int bonding_mode, agg_mode;
> +	portid_t slaves[RTE_MAX_ETHPORTS];
> +	int num_slaves, num_active_slaves;
> +	int primary_id;
> +	int i;
> +	portid_t port_id = res->port_id;
> +
> +	/* Display the bonding mode.*/
> +	bonding_mode = rte_eth_bond_mode_get(port_id);
> +	if (bonding_mode < 0) {
> +		fprintf(stderr, "\tFailed to get bonding mode for port = %d\n",
> +			port_id);
> +		return;
> +	}
> +	printf("\tBonding mode: %d\n", bonding_mode);
> +
> +	if (bonding_mode == BONDING_MODE_BALANCE ||
> +		bonding_mode == BONDING_MODE_8023AD) {
> +		int balance_xmit_policy;
> +
> +		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
> +		if (balance_xmit_policy < 0) {
> +			fprintf(stderr,
> +				"\tFailed to get balance xmit policy for port = %d\n",
> +				port_id);
> +			return;
> +		}
> +		printf("\tBalance Xmit Policy: ");
> +
> +		switch (balance_xmit_policy) {
> +		case BALANCE_XMIT_POLICY_LAYER2:
> +			printf("BALANCE_XMIT_POLICY_LAYER2");
> +			break;
> +		case BALANCE_XMIT_POLICY_LAYER23:
> +			printf("BALANCE_XMIT_POLICY_LAYER23");
> +			break;
> +		case BALANCE_XMIT_POLICY_LAYER34:
> +			printf("BALANCE_XMIT_POLICY_LAYER34");
> +			break;
> +		}
> +		printf("\n");
> +	}
> +
> +	if (bonding_mode == BONDING_MODE_8023AD) {
> +		agg_mode = rte_eth_bond_8023ad_agg_selection_get(port_id);
> +		printf("\tIEEE802.3AD Aggregator Mode: ");
> +		switch (agg_mode) {
> +		case AGG_BANDWIDTH:
> +			printf("bandwidth");
> +			break;
> +		case AGG_STABLE:
> +			printf("stable");
> +			break;
> +		case AGG_COUNT:
> +			printf("count");
> +			break;
> +		}
> +		printf("\n");
> +	}
> +
> +	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
> +
> +	if (num_slaves < 0) {
> +		fprintf(stderr, "\tFailed to get slave list for port = %d\n",
> +			port_id);
> +		return;
> +	}
> +	if (num_slaves > 0) {
> +		printf("\tSlaves (%d): [", num_slaves);
> +		for (i = 0; i < num_slaves - 1; i++)
> +			printf("%d ", slaves[i]);
> +
> +		printf("%d]\n", slaves[num_slaves - 1]);
> +	} else {
> +		printf("\tSlaves: []\n");
> +	}
> +
> +	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
> +			RTE_MAX_ETHPORTS);
> +
> +	if (num_active_slaves < 0) {
> +		fprintf(stderr,
> +			"\tFailed to get active slave list for port = %d\n",
> +			port_id);
> +		return;
> +	}
> +	if (num_active_slaves > 0) {
> +		printf("\tActive Slaves (%d): [", num_active_slaves);
> +		for (i = 0; i < num_active_slaves - 1; i++)
> +			printf("%d ", slaves[i]);
> +
> +		printf("%d]\n", slaves[num_active_slaves - 1]);
> +
> +	} else {
> +		printf("\tActive Slaves: []\n");
> +	}
> +
> +	primary_id = rte_eth_bond_primary_get(port_id);
> +	if (primary_id < 0) {
> +		fprintf(stderr, "\tFailed to get primary slave for port = %d\n",
> +			port_id);
> +		return;
> +	}
> +	printf("\tPrimary: [%d]\n", primary_id);
> +}
> +
> +cmdline_parse_token_string_t cmd_showbonding_config_show =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
> +		show, "show");
> +cmdline_parse_token_string_t cmd_showbonding_config_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_showbonding_config_config =
> +TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
> +		config, "config");
> +cmdline_parse_token_num_t cmd_showbonding_config_port =
> +TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
> +		port_id, RTE_UINT16);
> +
> +cmdline_parse_inst_t cmd_show_bonding_config = {
> +		.f = cmd_show_bonding_config_parsed,
> +		.help_str = "show bonding config <port_id>: "
> +			"Show the bonding config for port_id",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_showbonding_config_show,
> +				(void *)&cmd_showbonding_config_bonding,
> +				(void *)&cmd_showbonding_config_config,
> +				(void *)&cmd_showbonding_config_port,
> +				NULL
> +		}
> +};
> +
> +/* *** SET BONDING PRIMARY *** */
> +struct cmd_set_bonding_primary_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t primary;
> +	portid_t slave_id;
> +	portid_t port_id;
> +};
> +
> +static void cmd_set_bonding_primary_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bonding_primary_result *res = parsed_result;
> +	portid_t master_port_id = res->port_id;
> +	portid_t slave_port_id = res->slave_id;
> +
> +	/* Set the primary slave for a bonded device. */
> +	if (rte_eth_bond_primary_set(master_port_id, slave_port_id) != 0) {
> +		fprintf(stderr, "\t Failed to set primary slave for port = %d.\n",
> +			master_port_id);
> +		return;
> +	}
> +	init_port_config();
> +}
> +
> +cmdline_parse_token_string_t cmd_setbonding_primary_set =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
> +		set, "set");
> +cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_setbonding_primary_primary =
> +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
> +		primary, "primary");
> +cmdline_parse_token_num_t cmd_setbonding_primary_slave =
> +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
> +		slave_id, RTE_UINT16);
> +cmdline_parse_token_num_t cmd_setbonding_primary_port =
> +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
> +		port_id, RTE_UINT16);
> +
> +cmdline_parse_inst_t cmd_set_bonding_primary = {
> +		.f = cmd_set_bonding_primary_parsed,
> +		.help_str = "set bonding primary <slave_id> <port_id>: "
> +			"Set the primary slave for port_id",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_setbonding_primary_set,
> +				(void *)&cmd_setbonding_primary_bonding,
> +				(void *)&cmd_setbonding_primary_primary,
> +				(void *)&cmd_setbonding_primary_slave,
> +				(void *)&cmd_setbonding_primary_port,
> +				NULL
> +		}
> +};
> +
> +/* *** ADD SLAVE *** */
> +struct cmd_add_bonding_slave_result {
> +	cmdline_fixed_string_t add;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t slave;
> +	portid_t slave_id;
> +	portid_t port_id;
> +};
> +
> +static void cmd_add_bonding_slave_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_add_bonding_slave_result *res = parsed_result;
> +	portid_t master_port_id = res->port_id;
> +	portid_t slave_port_id = res->slave_id;
> +
> +	/* add the slave for a bonded device. */
> +	if (rte_eth_bond_slave_add(master_port_id, slave_port_id) != 0) {
> +		fprintf(stderr,
> +			"\t Failed to add slave %d to master port = %d.\n",
> +			slave_port_id, master_port_id);
> +		return;
> +	}
> +	init_port_config();
> +	set_port_slave_flag(slave_port_id);
> +}
> +
> +cmdline_parse_token_string_t cmd_addbonding_slave_add =
> +TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
> +		add, "add");
> +cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
> +TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
> +		bonding, "bonding");
> +cmdline_parse_token_string_t cmd_addbonding_slave_slave =
> +TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
> +		slave, "slave");
> +cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
> +TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
> +		slave_id, RTE_UINT16);
> +cmdline_parse_token_num_t cmd_addbonding_slave_port =
> +TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
> +		port_id, RTE_UINT16);
> +
> +cmdline_parse_inst_t cmd_add_bonding_slave = {
> +		.f = cmd_add_bonding_slave_parsed,
> +		.help_str = "add bonding slave <slave_id> <port_id>: "
> +			"Add a slave device to a bonded device",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_addbonding_slave_add,
> +				(void *)&cmd_addbonding_slave_bonding,
> +				(void *)&cmd_addbonding_slave_slave,
> +				(void *)&cmd_addbonding_slave_slaveid,
> +				(void *)&cmd_addbonding_slave_port,
> +				NULL
> +		}
> +};
> +
> +/* *** REMOVE SLAVE *** */
> +struct cmd_remove_bonding_slave_result {
> +	cmdline_fixed_string_t remove;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t slave;
> +	portid_t slave_id;
> +	portid_t port_id;
> +};
> +
> +static void cmd_remove_bonding_slave_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_remove_bonding_slave_result *res = parsed_result;
> +	portid_t master_port_id = res->port_id;
> +	portid_t slave_port_id = res->slave_id;
> +
> +	/* remove the slave from a bonded device. */
> +	if (rte_eth_bond_slave_remove(master_port_id, slave_port_id) != 0) {
> +		fprintf(stderr,
> +			"\t Failed to remove slave %d from master port = %d.\n",
> +			slave_port_id, master_port_id);
> +		return;
> +	}
> +	init_port_config();
> +	clear_port_slave_flag(slave_port_id);
> +}
> +
> +cmdline_parse_token_string_t cmd_removebonding_slave_remove =
> +		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
> +				remove, "remove");
> +cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
> +		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
> +				bonding, "bonding");
> +cmdline_parse_token_string_t cmd_removebonding_slave_slave =
> +		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
> +				slave, "slave");
> +cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
> +		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
> +				slave_id, RTE_UINT16);
> +cmdline_parse_token_num_t cmd_removebonding_slave_port =
> +		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
> +				port_id, RTE_UINT16);
> +
> +cmdline_parse_inst_t cmd_remove_bonding_slave = {
> +		.f = cmd_remove_bonding_slave_parsed,
> +		.help_str = "remove bonding slave <slave_id> <port_id>: "
> +			"Remove a slave device from a bonded device",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_removebonding_slave_remove,
> +				(void *)&cmd_removebonding_slave_bonding,
> +				(void *)&cmd_removebonding_slave_slave,
> +				(void *)&cmd_removebonding_slave_slaveid,
> +				(void *)&cmd_removebonding_slave_port,
> +				NULL
> +		}
> +};
> +
> +/* *** CREATE BONDED DEVICE *** */
> +struct cmd_create_bonded_device_result {
> +	cmdline_fixed_string_t create;
> +	cmdline_fixed_string_t bonded;
> +	cmdline_fixed_string_t device;
> +	uint8_t mode;
> +	uint8_t socket;
> +};
> +
> +static int bond_dev_num;
> +
> +static void cmd_create_bonded_device_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_create_bonded_device_result *res = parsed_result;
> +	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
> +	int port_id;
> +	int ret;
> +
> +	if (test_done == 0) {
> +		fprintf(stderr, "Please stop forwarding first\n");
> +		return;
> +	}
> +
> +	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d",
> +			bond_dev_num++);
> +
> +	/* Create a new bonded device. */
> +	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
> +	if (port_id < 0) {
> +		fprintf(stderr, "\t Failed to create bonded device.\n");
> +		return;
> +	}
> +	printf("Created new bonded device %s on (port %d).\n", ethdev_name,
> +		port_id);
> +
> +	/* Update number of ports */
> +	nb_ports = rte_eth_dev_count_avail();
> +	reconfig(port_id, res->socket);
> +	ret = rte_eth_promiscuous_enable(port_id);
> +	if (ret != 0)
> +		fprintf(stderr, "Failed to enable promiscuous mode for port %u: %s - ignore\n",
> +			port_id, rte_strerror(-ret));
> +
> +	ports[port_id].need_setup = 0;
> +	ports[port_id].port_status = RTE_PORT_STOPPED;
> +}
> +
> +cmdline_parse_token_string_t cmd_createbonded_device_create =
> +		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
> +				create, "create");
> +cmdline_parse_token_string_t cmd_createbonded_device_bonded =
> +		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
> +				bonded, "bonded");
> +cmdline_parse_token_string_t cmd_createbonded_device_device =
> +		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
> +				device, "device");
> +cmdline_parse_token_num_t cmd_createbonded_device_mode =
> +		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
> +				mode, RTE_UINT8);
> +cmdline_parse_token_num_t cmd_createbonded_device_socket =
> +		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
> +				socket, RTE_UINT8);
> +
> +cmdline_parse_inst_t cmd_create_bonded_device = {
> +		.f = cmd_create_bonded_device_parsed,
> +		.help_str = "create bonded device <mode> <socket>: "
> +			"Create a new bonded device with specific bonding mode and socket",
> +		.data = NULL,
> +		.tokens = {
> +				(void *)&cmd_createbonded_device_create,
> +				(void *)&cmd_createbonded_device_bonded,
> +				(void *)&cmd_createbonded_device_device,
> +				(void *)&cmd_createbonded_device_mode,
> +				(void *)&cmd_createbonded_device_socket,
> +				NULL
> +		}
> +};
> +
> +/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
> +struct cmd_set_bond_mac_addr_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t mac_addr;
> +	uint16_t port_num;
> +	struct rte_ether_addr address;
> +};
> +
> +static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bond_mac_addr_result *res = parsed_result;
> +	int ret;
> +
> +	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
> +		return;
> +
> +	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
> +
> +	/* check the return value and print it if is < 0 */
> +	if (ret < 0)
> +		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
> +			strerror(-ret));
> +}
> +
> +cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
> +		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
> +cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
> +		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
> +				"bonding");
> +cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
> +		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
> +				"mac_addr");
> +cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
> +		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result,
> +				port_num, RTE_UINT16);
> +cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
> +		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
> +
> +cmdline_parse_inst_t cmd_set_bond_mac_addr = {
> +		.f = cmd_set_bond_mac_addr_parsed,
> +		.data = NULL,
> +		.help_str = "set bonding mac_addr <port_id> <mac_addr>",
> +		.tokens = {
> +				(void *)&cmd_set_bond_mac_addr_set,
> +				(void *)&cmd_set_bond_mac_addr_bonding,
> +				(void *)&cmd_set_bond_mac_addr_mac,
> +				(void *)&cmd_set_bond_mac_addr_portnum,
> +				(void *)&cmd_set_bond_mac_addr_addr,
> +				NULL
> +		}
> +};
> +
> +/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
> +struct cmd_set_bond_mon_period_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t mon_period;
> +	uint16_t port_num;
> +	uint32_t period_ms;
> +};
> +
> +static void cmd_set_bond_mon_period_parsed(void *parsed_result,
> +		__rte_unused  struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bond_mon_period_result *res = parsed_result;
> +	int ret;
> +
> +	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
> +
> +	/* check the return value and print it if is < 0 */
> +	if (ret < 0)
> +		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
> +			strerror(-ret));
> +}
> +
> +cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
> +		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
> +				set, "set");
> +cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
> +		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
> +				bonding, "bonding");
> +cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
> +		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
> +				mon_period,	"mon_period");
> +cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
> +		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
> +				port_num, RTE_UINT16);
> +cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
> +		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
> +				period_ms, RTE_UINT32);
> +
> +cmdline_parse_inst_t cmd_set_bond_mon_period = {
> +		.f = cmd_set_bond_mon_period_parsed,
> +		.data = NULL,
> +		.help_str = "set bonding mon_period <port_id> <period_ms>",
> +		.tokens = {
> +				(void *)&cmd_set_bond_mon_period_set,
> +				(void *)&cmd_set_bond_mon_period_bonding,
> +				(void *)&cmd_set_bond_mon_period_mon_period,
> +				(void *)&cmd_set_bond_mon_period_portnum,
> +				(void *)&cmd_set_bond_mon_period_period_ms,
> +				NULL
> +		}
> +};
> +
> +struct cmd_set_bonding_agg_mode_policy_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t bonding;
> +	cmdline_fixed_string_t agg_mode;
> +	uint16_t port_num;
> +	cmdline_fixed_string_t policy;
> +};
> +
> +static void
> +cmd_set_bonding_agg_mode(void *parsed_result,
> +		__rte_unused struct cmdline *cl,
> +		__rte_unused void *data)
> +{
> +	struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result;
> +	uint8_t policy = AGG_BANDWIDTH;
> +
> +	if (!strcmp(res->policy, "bandwidth"))
> +		policy = AGG_BANDWIDTH;
> +	else if (!strcmp(res->policy, "stable"))
> +		policy = AGG_STABLE;
> +	else if (!strcmp(res->policy, "count"))
> +		policy = AGG_COUNT;
> +
> +	rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy);
> +}
> +
> +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> +				set, "set");
> +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> +				bonding, "bonding");
> +
> +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> +				agg_mode, "agg_mode");
> +
> +cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
> +				port_num, RTE_UINT16);
> +
> +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
> +		policy, "stable#bandwidth#count");
> +
> +cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = {
> +	.f = cmd_set_bonding_agg_mode,
> +	.data = NULL,
> +	.help_str = "set bonding mode IEEE802.3AD aggregator policy <port_id> <agg_name>",
> +	.tokens = {
> +			(void *)&cmd_set_bonding_agg_mode_set,
> +			(void *)&cmd_set_bonding_agg_mode_bonding,
> +			(void *)&cmd_set_bonding_agg_mode_agg_mode,
> +			(void *)&cmd_set_bonding_agg_mode_portnum,
> +			(void *)&cmd_set_bonding_agg_mode_policy_string,
> +			NULL
> +		}
> +};
> +
> +static struct testpmd_cmdline_parser driver_parser = {
> +	.ctx = (cmdline_parse_ctx_t[]) {
> +		(cmdline_parse_inst_t *)&cmd_set_bonding_mode,
> +		(cmdline_parse_inst_t *)&cmd_show_bonding_config,
> +		(cmdline_parse_inst_t *)&cmd_show_bonding_lacp_info,
> +		(cmdline_parse_inst_t *)&cmd_set_bonding_primary,
> +		(cmdline_parse_inst_t *)&cmd_add_bonding_slave,
> +		(cmdline_parse_inst_t *)&cmd_remove_bonding_slave,
> +		(cmdline_parse_inst_t *)&cmd_create_bonded_device,
> +		(cmdline_parse_inst_t *)&cmd_set_bond_mac_addr,
> +		(cmdline_parse_inst_t *)&cmd_set_balance_xmit_policy,
> +		(cmdline_parse_inst_t *)&cmd_set_bond_mon_period,
> +		(cmdline_parse_inst_t *)&cmd_set_lacp_dedicated_queues,
> +		(cmdline_parse_inst_t *)&cmd_set_bonding_agg_mode_policy,
> +		NULL
> +	},
> +	.help = {
> +		"set bonding mode (value) (port_id)\n"
> +		"	Set the bonding mode on a bonded device.\n",
> +
> +		"show bonding config (port_id)\n"
> +		"	Show the bonding config for port_id.\n",
> +
> +		"show bonding lacp info (port_id)\n"
> +		"	Show the bonding lacp information for port_id.\n",
> +
> +		"set bonding primary (slave_id) (port_id)\n"
> +		"	Set the primary slave for a bonded device.\n",
> +
> +		"add bonding slave (slave_id) (port_id)\n"
> +		"	Add a slave device to a bonded device.\n",
> +
> +		"remove bonding slave (slave_id) (port_id)\n"
> +		"	Remove a slave device from a bonded device.\n",
> +
> +		"create bonded device (mode) (socket)\n"
> +		"	Create a new bonded device with specific bonding mode and socket.\n",
> +
> +		"set bonding mac_addr (port_id) (address)\n"
> +		"	Set the MAC address of a bonded device.\n",
> +
> +		"set bonding balance_xmit_policy (port_id) (l2|l23|l34)\n"
> +		"	Set the transmit balance policy for bonded device running in balance mode.\n",
> +
> +		"set bonding mon_period (port_id) (value)\n"
> +		"	Set the bonding link status monitoring polling period in ms.\n",
> +
> +		"set bonding lacp dedicated_queues <port_id> (enable|disable)\n"
> +		"	Enable/disable dedicated queues for LACP control traffic.\n",
> +
> +		"set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)\n"
> +		"	Set Aggregation mode for IEEE802.3AD (mode 4)\n",
> +
> +		NULL
> +	},
> +};
> +
> +RTE_INIT(bonding_testpmd)
> +{
> +	testpmd_add_commands(&driver_parser);
> +}
>
  
David Marchand May 18, 2022, 5:24 p.m. UTC | #2
On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) <humin29@huawei.com> wrote:
>
>   I think net/bonding offer 'API' for APP to use the bonding.
>     and use the specific PMD as slave device.
>   The software framwork is like:
>    APP
>    ethdev
>    bonding PMD
>    PMD
>    hardware
>
> so, I think cmdlines for testpmd should not put in net/bonding.

Sorry, but the distinction is vague.

Those commands are specific to this driver/library.
I don't see the problem with hosting the commands in the bonding driver/library.

This is still a RFC, I don't mind dropping this patch (in the end) if
others think it does not make sense.
For now I'll keep it in a v2 series fixing the registering issue in patch 1.
  
Konstantin Ananyev May 18, 2022, 11:25 p.m. UTC | #3
18/05/2022 18:24, David Marchand пишет:
> On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) <humin29@huawei.com> wrote:
>>
>>    I think net/bonding offer 'API' for APP to use the bonding.
>>      and use the specific PMD as slave device.
>>    The software framwork is like:
>>     APP
>>     ethdev
>>     bonding PMD
>>     PMD
>>     hardware
>>
>> so, I think cmdlines for testpmd should not put in net/bonding.be

Actually, I feel the same.
I do understand the intention, and I do realize it is just location,
but still doesn't look right for me.
can't we have a special sub-folder in testpmd instead?
Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...


> 
> Sorry, but the distinction is vague.
> 
> Those commands are specific to this driver/library.
> I don't see the problem with hosting the commands in the bonding driver/library.
> 
> This is still a RFC, I don't mind dropping this patch (in the end) if
> others think it does not make sense.
> For now I'll keep it in a v2 series fixing the registering issue in patch 1.
> 
>
  
David Marchand May 19, 2022, 7:40 a.m. UTC | #4
On Thu, May 19, 2022 at 1:25 AM Konstantin Ananyev
<konstantin.v.ananyev@yandex.ru> wrote:
> 18/05/2022 18:24, David Marchand пишет:
> > On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) <humin29@huawei.com> wrote:
> >>
> >>    I think net/bonding offer 'API' for APP to use the bonding.
> >>      and use the specific PMD as slave device.
> >>    The software framwork is like:
> >>     APP
> >>     ethdev
> >>     bonding PMD
> >>     PMD
> >>     hardware
> >>
> >> so, I think cmdlines for testpmd should not put in net/bonding.be
>
> Actually, I feel the same.
> I do understand the intention, and I do realize it is just location,
> but still doesn't look right for me.
> can't we have a special sub-folder in testpmd instead?
> Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...

That should not pose a problem, indeed.
And, on the plus side, it avoids putting some testpmd global variables
in meson (which I was not entirely happy with).


But, on the other side, I have a concern about MAINTAINERS updates.

(almost) everything in app/test-pmd has been under the testpmd
maintainer responsibility.
Separating the driver specific code from testpmd is a way to clearly
shift this responsibility to the driver maintenance.
One advantage of moving the code to the driver directory is that there
is no MAINTAINERS update needed.

If we keep those in app/test-pmd, it is still possible to mark the
driver-specific sources in MAINTAINERS, but such updates are often
missed.
I can probably add something in devtools/ to catch those updates in
the future...

I'll try for RFC v3.
  
Thomas Monjalon May 19, 2022, 11:26 a.m. UTC | #5
19/05/2022 09:40, David Marchand:
> On Thu, May 19, 2022 at 1:25 AM Konstantin Ananyev
> <konstantin.v.ananyev@yandex.ru> wrote:
> > 18/05/2022 18:24, David Marchand пишет:
> > > On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) <humin29@huawei.com> wrote:
> > >>
> > >>    I think net/bonding offer 'API' for APP to use the bonding.
> > >>      and use the specific PMD as slave device.
> > >>    The software framwork is like:
> > >>     APP
> > >>     ethdev
> > >>     bonding PMD
> > >>     PMD
> > >>     hardware
> > >>
> > >> so, I think cmdlines for testpmd should not put in net/bonding.be

The bonding API is specific to drivers/net/bonding/,
so according to the techboard decision,
the testpmd code should go in the driver directory.

> > Actually, I feel the same.
> > I do understand the intention, and I do realize it is just location,
> > but still doesn't look right for me.
> > can't we have a special sub-folder in testpmd instead?
> > Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...
> 
> That should not pose a problem, indeed.
> And, on the plus side, it avoids putting some testpmd global variables
> in meson (which I was not entirely happy with).

I like the global variables approach.

> But, on the other side, I have a concern about MAINTAINERS updates.
> 
> (almost) everything in app/test-pmd has been under the testpmd
> maintainer responsibility.
> Separating the driver specific code from testpmd is a way to clearly
> shift this responsibility to the driver maintenance.

I agree.

> One advantage of moving the code to the driver directory is that there
> is no MAINTAINERS update needed.

Yes I think moving test code in the driver directory is smart.
We already have this approach for some self tests run with app/test.
And more important, the techboard has decided to move code in the driver
or lib directory:
	https://mails.dpdk.org/archives/dev/2022-April/239191.html

> If we keep those in app/test-pmd, it is still possible to mark the
> driver-specific sources in MAINTAINERS, but such updates are often
> missed.
> I can probably add something in devtools/ to catch those updates in
> the future...
> 
> I'll try for RFC v3.
  
Andrew Rybchenko May 20, 2022, 6:59 a.m. UTC | #6
On 5/19/22 14:26, Thomas Monjalon wrote:
> 19/05/2022 09:40, David Marchand:
>> On Thu, May 19, 2022 at 1:25 AM Konstantin Ananyev
>> <konstantin.v.ananyev@yandex.ru> wrote:
>>> 18/05/2022 18:24, David Marchand пишет:
>>>> On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) <humin29@huawei.com> wrote:
>>>>>
>>>>>     I think net/bonding offer 'API' for APP to use the bonding.
>>>>>       and use the specific PMD as slave device.
>>>>>     The software framwork is like:
>>>>>      APP
>>>>>      ethdev
>>>>>      bonding PMD
>>>>>      PMD
>>>>>      hardware
>>>>>
>>>>> so, I think cmdlines for testpmd should not put in net/bonding.be
> 
> The bonding API is specific to drivers/net/bonding/,
> so according to the techboard decision,
> the testpmd code should go in the driver directory.

+1

> 
>>> Actually, I feel the same.
>>> I do understand the intention, and I do realize it is just location,
>>> but still doesn't look right for me.
>>> can't we have a special sub-folder in testpmd instead?
>>> Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...
>>
>> That should not pose a problem, indeed.
>> And, on the plus side, it avoids putting some testpmd global variables
>> in meson (which I was not entirely happy with).
> 
> I like the global variables approach.

+1

> 
>> But, on the other side, I have a concern about MAINTAINERS updates.
>>
>> (almost) everything in app/test-pmd has been under the testpmd
>> maintainer responsibility.
>> Separating the driver specific code from testpmd is a way to clearly
>> shift this responsibility to the driver maintenance.
> 
> I agree.

+1

> 
>> One advantage of moving the code to the driver directory is that there
>> is no MAINTAINERS update needed.
> 
> Yes I think moving test code in the driver directory is smart.
> We already have this approach for some self tests run with app/test.
> And more important, the techboard has decided to move code in the driver
> or lib directory:
> 	https://mails.dpdk.org/archives/dev/2022-April/239191.html
> 
>> If we keep those in app/test-pmd, it is still possible to mark the
>> driver-specific sources in MAINTAINERS, but such updates are often
>> missed.
>> I can probably add something in devtools/ to catch those updates in
>> the future...
>>
>> I'll try for RFC v3.
> 
> 
>
  
Konstantin Ananyev May 24, 2022, 9:40 a.m. UTC | #7
20/05/2022 07:59, Andrew Rybchenko пишет:
> On 5/19/22 14:26, Thomas Monjalon wrote:
>> 19/05/2022 09:40, David Marchand:
>>> On Thu, May 19, 2022 at 1:25 AM Konstantin Ananyev
>>> <konstantin.v.ananyev@yandex.ru> wrote:
>>>> 18/05/2022 18:24, David Marchand пишет:
>>>>> On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) 
>>>>> <humin29@huawei.com> wrote:
>>>>>>
>>>>>>     I think net/bonding offer 'API' for APP to use the bonding.
>>>>>>       and use the specific PMD as slave device.
>>>>>>     The software framwork is like:
>>>>>>      APP
>>>>>>      ethdev
>>>>>>      bonding PMD
>>>>>>      PMD
>>>>>>      hardware
>>>>>>
>>>>>> so, I think cmdlines for testpmd should not put in net/bonding.be
>>
>> The bonding API is specific to drivers/net/bonding/,
>> so according to the techboard decision,
>> the testpmd code should go in the driver directory.
> 
> +1
> 
>>
>>>> Actually, I feel the same.
>>>> I do understand the intention, and I do realize it is just location,
>>>> but still doesn't look right for me.
>>>> can't we have a special sub-folder in testpmd instead?
>>>> Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...
>>>
>>> That should not pose a problem, indeed.
>>> And, on the plus side, it avoids putting some testpmd global variables
>>> in meson (which I was not entirely happy with).
>>
>> I like the global variables approach.
> 
> +1
> 
>>
>>> But, on the other side, I have a concern about MAINTAINERS updates.
>>>
>>> (almost) everything in app/test-pmd has been under the testpmd
>>> maintainer responsibility.
>>> Separating the driver specific code from testpmd is a way to clearly
>>> shift this responsibility to the driver maintenance.
>>
>> I agree.
> 
> +1
> 
>>
>>> One advantage of moving the code to the driver directory is that there
>>> is no MAINTAINERS update needed.
>>
>> Yes I think moving test code in the driver directory is smart.
>> We already have this approach for some self tests run with app/test.
>> And more important, the techboard has decided to move code in the driver
>> or lib directory:
>>     https://mails.dpdk.org/archives/dev/2022-April/239191.html

Yep, I remember that discussion, though from my impression
(probably wrong) people talked more about need for some smart
testpmd plugin approach.
I didn't realize that it would mean literally dump all
current cmd-line related code straight into drivers/net.
I agree that testpmd code for PMD-specific API should be
responsibility of this PMD maintainer.
I just don't feel that drivers/net is the best place for it.
As another thing to consider: what would happen if we'll decide
to rework testpmd interface (from CLI to gRPC or so), or introduce
new app for PMD testing - would we need to inject all these things
into drivers/net too?

>>
>>> If we keep those in app/test-pmd, it is still possible to mark the
>>> driver-specific sources in MAINTAINERS, but such updates are often
>>> missed.
>>> I can probably add something in devtools/ to catch those updates in
>>> the future...
>>>
>>> I'll try for RFC v3.
>>
>>
>>
>
  
Thomas Monjalon May 24, 2022, 10:15 a.m. UTC | #8
24/05/2022 11:40, Konstantin Ananyev:
> 20/05/2022 07:59, Andrew Rybchenko пишет:
> > On 5/19/22 14:26, Thomas Monjalon wrote:
> >> 19/05/2022 09:40, David Marchand:
> >>> On Thu, May 19, 2022 at 1:25 AM Konstantin Ananyev
> >>> <konstantin.v.ananyev@yandex.ru> wrote:
> >>>> 18/05/2022 18:24, David Marchand пишет:
> >>>>> On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor) 
> >>>>> <humin29@huawei.com> wrote:
> >>>>>>
> >>>>>>     I think net/bonding offer 'API' for APP to use the bonding.
> >>>>>>       and use the specific PMD as slave device.
> >>>>>>     The software framwork is like:
> >>>>>>      APP
> >>>>>>      ethdev
> >>>>>>      bonding PMD
> >>>>>>      PMD
> >>>>>>      hardware
> >>>>>>
> >>>>>> so, I think cmdlines for testpmd should not put in net/bonding.be
> >>
> >> The bonding API is specific to drivers/net/bonding/,
> >> so according to the techboard decision,
> >> the testpmd code should go in the driver directory.
> > 
> > +1
> > 
> >>
> >>>> Actually, I feel the same.
> >>>> I do understand the intention, and I do realize it is just location,
> >>>> but still doesn't look right for me.
> >>>> can't we have a special sub-folder in testpmd instead?
> >>>> Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...
> >>>
> >>> That should not pose a problem, indeed.
> >>> And, on the plus side, it avoids putting some testpmd global variables
> >>> in meson (which I was not entirely happy with).
> >>
> >> I like the global variables approach.
> > 
> > +1
> > 
> >>
> >>> But, on the other side, I have a concern about MAINTAINERS updates.
> >>>
> >>> (almost) everything in app/test-pmd has been under the testpmd
> >>> maintainer responsibility.
> >>> Separating the driver specific code from testpmd is a way to clearly
> >>> shift this responsibility to the driver maintenance.
> >>
> >> I agree.
> > 
> > +1
> > 
> >>
> >>> One advantage of moving the code to the driver directory is that there
> >>> is no MAINTAINERS update needed.
> >>
> >> Yes I think moving test code in the driver directory is smart.
> >> We already have this approach for some self tests run with app/test.
> >> And more important, the techboard has decided to move code in the driver
> >> or lib directory:
> >>     https://mails.dpdk.org/archives/dev/2022-April/239191.html
> 
> Yep, I remember that discussion, though from my impression
> (probably wrong) people talked more about need for some smart
> testpmd plugin approach.
> I didn't realize that it would mean literally dump all
> current cmd-line related code straight into drivers/net.
> I agree that testpmd code for PMD-specific API should be
> responsibility of this PMD maintainer.
> I just don't feel that drivers/net is the best place for it.
> As another thing to consider: what would happen if we'll decide
> to rework testpmd interface (from CLI to gRPC or so), or introduce
> new app for PMD testing - would we need to inject all these things
> into drivers/net too?

Yes I think it's OK to have driver-specific test code
in the driver directory.
This is what is already done for eventdev and rawdev drivers:
	git ls-files drivers | grep test
  
Konstantin Ananyev May 24, 2022, 10:41 p.m. UTC | #9
24/05/2022 11:15, Thomas Monjalon пишет:
> 24/05/2022 11:40, Konstantin Ananyev:
>> 20/05/2022 07:59, Andrew Rybchenko пишет:
>>> On 5/19/22 14:26, Thomas Monjalon wrote:
>>>> 19/05/2022 09:40, David Marchand:
>>>>> On Thu, May 19, 2022 at 1:25 AM Konstantin Ananyev
>>>>> <konstantin.v.ananyev@yandex.ru> wrote:
>>>>>> 18/05/2022 18:24, David Marchand пишет:
>>>>>>> On Fri, May 13, 2022 at 12:10 PM Min Hu (Connor)
>>>>>>> <humin29@huawei.com> wrote:
>>>>>>>>
>>>>>>>>      I think net/bonding offer 'API' for APP to use the bonding.
>>>>>>>>        and use the specific PMD as slave device.
>>>>>>>>      The software framwork is like:
>>>>>>>>       APP
>>>>>>>>       ethdev
>>>>>>>>       bonding PMD
>>>>>>>>       PMD
>>>>>>>>       hardware
>>>>>>>>
>>>>>>>> so, I think cmdlines for testpmd should not put in net/bonding.be
>>>>
>>>> The bonding API is specific to drivers/net/bonding/,
>>>> so according to the techboard decision,
>>>> the testpmd code should go in the driver directory.
>>>
>>> +1
>>>
>>>>
>>>>>> Actually, I feel the same.
>>>>>> I do understand the intention, and I do realize it is just location,
>>>>>> but still doesn't look right for me.
>>>>>> can't we have a special sub-folder in testpmd instead?
>>>>>> Something like app/testpmd/driver_specific/(ixgbe)|(i40e)|(bonding)...
>>>>>
>>>>> That should not pose a problem, indeed.
>>>>> And, on the plus side, it avoids putting some testpmd global variables
>>>>> in meson (which I was not entirely happy with).
>>>>
>>>> I like the global variables approach.
>>>
>>> +1
>>>
>>>>
>>>>> But, on the other side, I have a concern about MAINTAINERS updates.
>>>>>
>>>>> (almost) everything in app/test-pmd has been under the testpmd
>>>>> maintainer responsibility.
>>>>> Separating the driver specific code from testpmd is a way to clearly
>>>>> shift this responsibility to the driver maintenance.
>>>>
>>>> I agree.
>>>
>>> +1
>>>
>>>>
>>>>> One advantage of moving the code to the driver directory is that there
>>>>> is no MAINTAINERS update needed.
>>>>
>>>> Yes I think moving test code in the driver directory is smart.
>>>> We already have this approach for some self tests run with app/test.
>>>> And more important, the techboard has decided to move code in the driver
>>>> or lib directory:
>>>>      https://mails.dpdk.org/archives/dev/2022-April/239191.html
>>
>> Yep, I remember that discussion, though from my impression
>> (probably wrong) people talked more about need for some smart
>> testpmd plugin approach.
>> I didn't realize that it would mean literally dump all
>> current cmd-line related code straight into drivers/net.
>> I agree that testpmd code for PMD-specific API should be
>> responsibility of this PMD maintainer.
>> I just don't feel that drivers/net is the best place for it.
>> As another thing to consider: what would happen if we'll decide
>> to rework testpmd interface (from CLI to gRPC or so), or introduce
>> new app for PMD testing - would we need to inject all these things
>> into drivers/net too?
> 
> Yes I think it's OK to have driver-specific test code
> in the driver directory.
> This is what is already done for eventdev and rawdev drivers:
> 	git ls-files drivers | grep test

Ok, if we already doing it that way for some dev types,
then probably no point to do it differently for netdev.
  

Patch

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ed62027834..ae4759fbfe 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -47,10 +47,6 @@ 
 #include <cmdline_parse_etheraddr.h>
 #include <cmdline_socket.h>
 #include <cmdline.h>
-#ifdef RTE_NET_BOND
-#include <rte_eth_bond.h>
-#include <rte_eth_bond_8023ad.h>
-#endif
 #if defined RTE_BUS_DPAA && defined RTE_NET_DPAA
 #include <rte_pmd_dpaa.h>
 #endif
@@ -614,44 +610,6 @@  static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 
-#ifdef RTE_NET_BOND
-			"create bonded device (mode) (socket)\n"
-			"	Create a new bonded device with specific bonding mode and socket.\n\n"
-
-			"add bonding slave (slave_id) (port_id)\n"
-			"	Add a slave device to a bonded device.\n\n"
-
-			"remove bonding slave (slave_id) (port_id)\n"
-			"	Remove a slave device from a bonded device.\n\n"
-
-			"set bonding mode (value) (port_id)\n"
-			"	Set the bonding mode on a bonded device.\n\n"
-
-			"set bonding primary (slave_id) (port_id)\n"
-			"	Set the primary slave for a bonded device.\n\n"
-
-			"show bonding config (port_id)\n"
-			"	Show the bonding config for port_id.\n\n"
-
-			"show bonding lacp info (port_id)\n"
-			"	Show the bonding lacp information for port_id.\n\n"
-
-			"set bonding mac_addr (port_id) (address)\n"
-			"	Set the MAC address of a bonded device.\n\n"
-
-			"set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)"
-			"	Set Aggregation mode for IEEE802.3AD (mode 4)"
-
-			"set bonding balance_xmit_policy (port_id) (l2|l23|l34)\n"
-			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
-
-			"set bonding mon_period (port_id) (value)\n"
-			"	Set the bonding link status monitoring polling period in ms.\n\n"
-
-			"set bonding lacp dedicated_queues <port_id> (enable|disable)\n"
-			"	Enable/disable dedicated queues for LACP control traffic.\n\n"
-
-#endif
 			"set link-up port (port_id)\n"
 			"	Set link up for a port.\n\n"
 
@@ -5925,985 +5883,6 @@  cmdline_parse_inst_t cmd_show_bypass_config = {
 	},
 };
 
-#ifdef RTE_NET_BOND
-/* *** SET BONDING MODE *** */
-struct cmd_set_bonding_mode_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t mode;
-	uint8_t value;
-	portid_t port_id;
-};
-
-static void cmd_set_bonding_mode_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bonding_mode_result *res = parsed_result;
-	portid_t port_id = res->port_id;
-	struct rte_port *port = &ports[port_id];
-
-	/*
-	 * Bonding mode changed means resources of device changed, like whether
-	 * started rte timer or not. Device should be restarted when resources
-	 * of device changed.
-	 */
-	if (port->port_status != RTE_PORT_STOPPED) {
-		fprintf(stderr,
-			"\t Error: Can't set bonding mode when port %d is not stopped\n",
-			port_id);
-		return;
-	}
-
-	/* Set the bonding mode for the relevant port. */
-	if (0 != rte_eth_bond_mode_set(port_id, res->value))
-		fprintf(stderr, "\t Failed to set bonding mode for port = %d.\n",
-			port_id);
-}
-
-cmdline_parse_token_string_t cmd_setbonding_mode_set =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
-		set, "set");
-cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_setbonding_mode_mode =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
-		mode, "mode");
-cmdline_parse_token_num_t cmd_setbonding_mode_value =
-TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
-		value, RTE_UINT8);
-cmdline_parse_token_num_t cmd_setbonding_mode_port =
-TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
-		port_id, RTE_UINT16);
-
-cmdline_parse_inst_t cmd_set_bonding_mode = {
-		.f = cmd_set_bonding_mode_parsed,
-		.help_str = "set bonding mode <mode_value> <port_id>: "
-			"Set the bonding mode for port_id",
-		.data = NULL,
-		.tokens = {
-				(void *) &cmd_setbonding_mode_set,
-				(void *) &cmd_setbonding_mode_bonding,
-				(void *) &cmd_setbonding_mode_mode,
-				(void *) &cmd_setbonding_mode_value,
-				(void *) &cmd_setbonding_mode_port,
-				NULL
-		}
-};
-
-/* *** SET BONDING SLOW_QUEUE SW/HW *** */
-struct cmd_set_bonding_lacp_dedicated_queues_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t lacp;
-	cmdline_fixed_string_t dedicated_queues;
-	portid_t port_id;
-	cmdline_fixed_string_t mode;
-};
-
-static void cmd_set_bonding_lacp_dedicated_queues_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bonding_lacp_dedicated_queues_result *res = parsed_result;
-	portid_t port_id = res->port_id;
-	struct rte_port *port;
-
-	port = &ports[port_id];
-
-	/** Check if the port is not started **/
-	if (port->port_status != RTE_PORT_STOPPED) {
-		fprintf(stderr, "Please stop port %d first\n", port_id);
-		return;
-	}
-
-	if (!strcmp(res->mode, "enable")) {
-		if (rte_eth_bond_8023ad_dedicated_queues_enable(port_id) == 0)
-			printf("Dedicate queues for LACP control packets"
-					" enabled\n");
-		else
-			printf("Enabling dedicate queues for LACP control "
-					"packets on port %d failed\n", port_id);
-	} else if (!strcmp(res->mode, "disable")) {
-		if (rte_eth_bond_8023ad_dedicated_queues_disable(port_id) == 0)
-			printf("Dedicated queues for LACP control packets "
-					"disabled\n");
-		else
-			printf("Disabling dedicated queues for LACP control "
-					"traffic on port %d failed\n", port_id);
-	}
-}
-
-cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_set =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
-		set, "set");
-cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_lacp =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
-		lacp, "lacp");
-cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_dedicated_queues =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
-		dedicated_queues, "dedicated_queues");
-cmdline_parse_token_num_t cmd_setbonding_lacp_dedicated_queues_port_id =
-TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
-		port_id, RTE_UINT16);
-cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_mode =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
-		mode, "enable#disable");
-
-cmdline_parse_inst_t cmd_set_lacp_dedicated_queues = {
-		.f = cmd_set_bonding_lacp_dedicated_queues_parsed,
-		.help_str = "set bonding lacp dedicated_queues <port_id> "
-			"enable|disable: "
-			"Enable/disable dedicated queues for LACP control traffic for port_id",
-		.data = NULL,
-		.tokens = {
-			(void *)&cmd_setbonding_lacp_dedicated_queues_set,
-			(void *)&cmd_setbonding_lacp_dedicated_queues_bonding,
-			(void *)&cmd_setbonding_lacp_dedicated_queues_lacp,
-			(void *)&cmd_setbonding_lacp_dedicated_queues_dedicated_queues,
-			(void *)&cmd_setbonding_lacp_dedicated_queues_port_id,
-			(void *)&cmd_setbonding_lacp_dedicated_queues_mode,
-			NULL
-		}
-};
-
-/* *** SET BALANCE XMIT POLICY *** */
-struct cmd_set_bonding_balance_xmit_policy_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t balance_xmit_policy;
-	portid_t port_id;
-	cmdline_fixed_string_t policy;
-};
-
-static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
-	portid_t port_id = res->port_id;
-	uint8_t policy;
-
-	if (!strcmp(res->policy, "l2")) {
-		policy = BALANCE_XMIT_POLICY_LAYER2;
-	} else if (!strcmp(res->policy, "l23")) {
-		policy = BALANCE_XMIT_POLICY_LAYER23;
-	} else if (!strcmp(res->policy, "l34")) {
-		policy = BALANCE_XMIT_POLICY_LAYER34;
-	} else {
-		fprintf(stderr, "\t Invalid xmit policy selection");
-		return;
-	}
-
-	/* Set the bonding mode for the relevant port. */
-	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
-		fprintf(stderr,
-			"\t Failed to set bonding balance xmit policy for port = %d.\n",
-			port_id);
-	}
-}
-
-cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
-		set, "set");
-cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
-		balance_xmit_policy, "balance_xmit_policy");
-cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
-TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
-		port_id, RTE_UINT16);
-cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
-		policy, "l2#l23#l34");
-
-cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
-		.f = cmd_set_bonding_balance_xmit_policy_parsed,
-		.help_str = "set bonding balance_xmit_policy <port_id> "
-			"l2|l23|l34: "
-			"Set the bonding balance_xmit_policy for port_id",
-		.data = NULL,
-		.tokens = {
-				(void *)&cmd_setbonding_balance_xmit_policy_set,
-				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
-				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
-				(void *)&cmd_setbonding_balance_xmit_policy_port,
-				(void *)&cmd_setbonding_balance_xmit_policy_policy,
-				NULL
-		}
-};
-
-/* *** SHOW IEEE802.3 BONDING INFORMATION *** */
-struct cmd_show_bonding_lacp_info_result {
-	cmdline_fixed_string_t show;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t lacp;
-	cmdline_fixed_string_t info;
-	portid_t port_id;
-};
-
-static void port_param_show(struct port_params *params)
-{
-	char buf[RTE_ETHER_ADDR_FMT_SIZE];
-
-	printf("\t\tsystem priority: %u\n", params->system_priority);
-	rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, &params->system);
-	printf("\t\tsystem mac address: %s\n", buf);
-	printf("\t\tport key: %u\n", params->key);
-	printf("\t\tport priority: %u\n", params->port_priority);
-	printf("\t\tport number: %u\n", params->port_number);
-}
-
-static void lacp_slave_info_show(struct rte_eth_bond_8023ad_slave_info *info)
-{
-	char a_state[256] = { 0 };
-	char p_state[256] = { 0 };
-	int a_len = 0;
-	int p_len = 0;
-	uint32_t i;
-
-	static const char * const state[] = {
-		"ACTIVE",
-		"TIMEOUT",
-		"AGGREGATION",
-		"SYNCHRONIZATION",
-		"COLLECTING",
-		"DISTRIBUTING",
-		"DEFAULTED",
-		"EXPIRED"
-	};
-	static const char * const selection[] = {
-		"UNSELECTED",
-		"STANDBY",
-		"SELECTED"
-	};
-
-	for (i = 0; i < RTE_DIM(state); i++) {
-		if ((info->actor_state >> i) & 1)
-			a_len += snprintf(&a_state[a_len],
-						RTE_DIM(a_state) - a_len, "%s ",
-						state[i]);
-
-		if ((info->partner_state >> i) & 1)
-			p_len += snprintf(&p_state[p_len],
-						RTE_DIM(p_state) - p_len, "%s ",
-						state[i]);
-	}
-	printf("\tAggregator port id: %u\n", info->agg_port_id);
-	printf("\tselection: %s\n", selection[info->selected]);
-	printf("\tActor detail info:\n");
-	port_param_show(&info->actor);
-	printf("\t\tport state: %s\n", a_state);
-	printf("\tPartner detail info:\n");
-	port_param_show(&info->partner);
-	printf("\t\tport state: %s\n", p_state);
-	printf("\n");
-}
-
-static void lacp_conf_show(struct rte_eth_bond_8023ad_conf *conf)
-{
-	printf("\tfast period: %u ms\n", conf->fast_periodic_ms);
-	printf("\tslow period: %u ms\n", conf->slow_periodic_ms);
-	printf("\tshort timeout: %u ms\n", conf->short_timeout_ms);
-	printf("\tlong timeout: %u ms\n", conf->long_timeout_ms);
-	printf("\taggregate wait timeout: %u ms\n",
-			conf->aggregate_wait_timeout_ms);
-	printf("\ttx period: %u ms\n", conf->tx_period_ms);
-	printf("\trx marker period: %u ms\n", conf->rx_marker_period_ms);
-	printf("\tupdate timeout: %u ms\n", conf->update_timeout_ms);
-	switch (conf->agg_selection) {
-	case AGG_BANDWIDTH:
-		printf("\taggregation mode: bandwidth\n");
-		break;
-	case AGG_STABLE:
-		printf("\taggregation mode: stable\n");
-		break;
-	case AGG_COUNT:
-		printf("\taggregation mode: count\n");
-		break;
-	default:
-		printf("\taggregation mode: invalid\n");
-		break;
-	}
-
-	printf("\n");
-}
-
-static void cmd_show_bonding_lacp_info_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_show_bonding_lacp_info_result *res = parsed_result;
-	struct rte_eth_bond_8023ad_slave_info slave_info;
-	struct rte_eth_bond_8023ad_conf port_conf;
-	portid_t slaves[RTE_MAX_ETHPORTS];
-	portid_t port_id = res->port_id;
-	int num_active_slaves;
-	int bonding_mode;
-	int i;
-	int ret;
-
-	bonding_mode = rte_eth_bond_mode_get(port_id);
-	if (bonding_mode != BONDING_MODE_8023AD) {
-		fprintf(stderr, "\tBonding mode is not mode 4\n");
-		return;
-	}
-
-	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
-			RTE_MAX_ETHPORTS);
-	if (num_active_slaves < 0) {
-		fprintf(stderr, "\tFailed to get active slave list for port = %u\n",
-				port_id);
-		return;
-	}
-	if (num_active_slaves == 0)
-		fprintf(stderr, "\tIEEE802.3 port %u has no active slave\n",
-			port_id);
-
-	printf("\tIEEE802.3 port: %u\n", port_id);
-	ret = rte_eth_bond_8023ad_conf_get(port_id, &port_conf);
-	if (ret) {
-		fprintf(stderr, "\tGet bonded device %u info failed\n",
-			port_id);
-		return;
-	}
-	lacp_conf_show(&port_conf);
-
-	for (i = 0; i < num_active_slaves; i++) {
-		ret = rte_eth_bond_8023ad_slave_info(port_id, slaves[i],
-				&slave_info);
-		if (ret) {
-			fprintf(stderr, "\tGet slave device %u info failed\n",
-				slaves[i]);
-			return;
-		}
-		printf("\tSlave Port: %u\n", slaves[i]);
-		lacp_slave_info_show(&slave_info);
-	}
-}
-
-cmdline_parse_token_string_t cmd_show_bonding_lacp_info_show =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
-		show, "show");
-cmdline_parse_token_string_t cmd_show_bonding_lacp_info_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_show_bonding_lacp_info_lacp =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
-		bonding, "lacp");
-cmdline_parse_token_string_t cmd_show_bonding_lacp_info_info =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
-		info, "info");
-cmdline_parse_token_num_t cmd_show_bonding_lacp_info_port_id =
-TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
-		port_id, RTE_UINT16);
-
-cmdline_parse_inst_t cmd_show_bonding_lacp_info = {
-		.f = cmd_show_bonding_lacp_info_parsed,
-		.help_str = "show bonding lacp info <port_id> : "
-			"Show bonding IEEE802.3 information for port_id",
-		.data = NULL,
-		.tokens = {
-			(void *)&cmd_show_bonding_lacp_info_show,
-			(void *)&cmd_show_bonding_lacp_info_bonding,
-			(void *)&cmd_show_bonding_lacp_info_lacp,
-			(void *)&cmd_show_bonding_lacp_info_info,
-			(void *)&cmd_show_bonding_lacp_info_port_id,
-			NULL
-		}
-};
-
-/* *** SHOW NIC BONDING CONFIGURATION *** */
-struct cmd_show_bonding_config_result {
-	cmdline_fixed_string_t show;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t config;
-	portid_t port_id;
-};
-
-static void cmd_show_bonding_config_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_show_bonding_config_result *res = parsed_result;
-	int bonding_mode, agg_mode;
-	portid_t slaves[RTE_MAX_ETHPORTS];
-	int num_slaves, num_active_slaves;
-	int primary_id;
-	int i;
-	portid_t port_id = res->port_id;
-
-	/* Display the bonding mode.*/
-	bonding_mode = rte_eth_bond_mode_get(port_id);
-	if (bonding_mode < 0) {
-		fprintf(stderr, "\tFailed to get bonding mode for port = %d\n",
-			port_id);
-		return;
-	} else
-		printf("\tBonding mode: %d\n", bonding_mode);
-
-	if (bonding_mode == BONDING_MODE_BALANCE ||
-		bonding_mode == BONDING_MODE_8023AD) {
-		int balance_xmit_policy;
-
-		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
-		if (balance_xmit_policy < 0) {
-			fprintf(stderr,
-				"\tFailed to get balance xmit policy for port = %d\n",
-				port_id);
-			return;
-		} else {
-			printf("\tBalance Xmit Policy: ");
-
-			switch (balance_xmit_policy) {
-			case BALANCE_XMIT_POLICY_LAYER2:
-				printf("BALANCE_XMIT_POLICY_LAYER2");
-				break;
-			case BALANCE_XMIT_POLICY_LAYER23:
-				printf("BALANCE_XMIT_POLICY_LAYER23");
-				break;
-			case BALANCE_XMIT_POLICY_LAYER34:
-				printf("BALANCE_XMIT_POLICY_LAYER34");
-				break;
-			}
-			printf("\n");
-		}
-	}
-
-	if (bonding_mode == BONDING_MODE_8023AD) {
-		agg_mode = rte_eth_bond_8023ad_agg_selection_get(port_id);
-		printf("\tIEEE802.3AD Aggregator Mode: ");
-		switch (agg_mode) {
-		case AGG_BANDWIDTH:
-			printf("bandwidth");
-			break;
-		case AGG_STABLE:
-			printf("stable");
-			break;
-		case AGG_COUNT:
-			printf("count");
-			break;
-		}
-		printf("\n");
-	}
-
-	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
-
-	if (num_slaves < 0) {
-		fprintf(stderr, "\tFailed to get slave list for port = %d\n",
-			port_id);
-		return;
-	}
-	if (num_slaves > 0) {
-		printf("\tSlaves (%d): [", num_slaves);
-		for (i = 0; i < num_slaves - 1; i++)
-			printf("%d ", slaves[i]);
-
-		printf("%d]\n", slaves[num_slaves - 1]);
-	} else {
-		printf("\tSlaves: []\n");
-
-	}
-
-	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
-			RTE_MAX_ETHPORTS);
-
-	if (num_active_slaves < 0) {
-		fprintf(stderr,
-			"\tFailed to get active slave list for port = %d\n",
-			port_id);
-		return;
-	}
-	if (num_active_slaves > 0) {
-		printf("\tActive Slaves (%d): [", num_active_slaves);
-		for (i = 0; i < num_active_slaves - 1; i++)
-			printf("%d ", slaves[i]);
-
-		printf("%d]\n", slaves[num_active_slaves - 1]);
-
-	} else {
-		printf("\tActive Slaves: []\n");
-
-	}
-
-	primary_id = rte_eth_bond_primary_get(port_id);
-	if (primary_id < 0) {
-		fprintf(stderr, "\tFailed to get primary slave for port = %d\n",
-			port_id);
-		return;
-	} else
-		printf("\tPrimary: [%d]\n", primary_id);
-
-}
-
-cmdline_parse_token_string_t cmd_showbonding_config_show =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
-		show, "show");
-cmdline_parse_token_string_t cmd_showbonding_config_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_showbonding_config_config =
-TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
-		config, "config");
-cmdline_parse_token_num_t cmd_showbonding_config_port =
-TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
-		port_id, RTE_UINT16);
-
-cmdline_parse_inst_t cmd_show_bonding_config = {
-		.f = cmd_show_bonding_config_parsed,
-		.help_str = "show bonding config <port_id>: "
-			"Show the bonding config for port_id",
-		.data = NULL,
-		.tokens = {
-				(void *)&cmd_showbonding_config_show,
-				(void *)&cmd_showbonding_config_bonding,
-				(void *)&cmd_showbonding_config_config,
-				(void *)&cmd_showbonding_config_port,
-				NULL
-		}
-};
-
-/* *** SET BONDING PRIMARY *** */
-struct cmd_set_bonding_primary_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t primary;
-	portid_t slave_id;
-	portid_t port_id;
-};
-
-static void cmd_set_bonding_primary_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bonding_primary_result *res = parsed_result;
-	portid_t master_port_id = res->port_id;
-	portid_t slave_port_id = res->slave_id;
-
-	/* Set the primary slave for a bonded device. */
-	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
-		fprintf(stderr, "\t Failed to set primary slave for port = %d.\n",
-			master_port_id);
-		return;
-	}
-	init_port_config();
-}
-
-cmdline_parse_token_string_t cmd_setbonding_primary_set =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
-		set, "set");
-cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_setbonding_primary_primary =
-TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
-		primary, "primary");
-cmdline_parse_token_num_t cmd_setbonding_primary_slave =
-TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
-		slave_id, RTE_UINT16);
-cmdline_parse_token_num_t cmd_setbonding_primary_port =
-TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
-		port_id, RTE_UINT16);
-
-cmdline_parse_inst_t cmd_set_bonding_primary = {
-		.f = cmd_set_bonding_primary_parsed,
-		.help_str = "set bonding primary <slave_id> <port_id>: "
-			"Set the primary slave for port_id",
-		.data = NULL,
-		.tokens = {
-				(void *)&cmd_setbonding_primary_set,
-				(void *)&cmd_setbonding_primary_bonding,
-				(void *)&cmd_setbonding_primary_primary,
-				(void *)&cmd_setbonding_primary_slave,
-				(void *)&cmd_setbonding_primary_port,
-				NULL
-		}
-};
-
-/* *** ADD SLAVE *** */
-struct cmd_add_bonding_slave_result {
-	cmdline_fixed_string_t add;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t slave;
-	portid_t slave_id;
-	portid_t port_id;
-};
-
-static void cmd_add_bonding_slave_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_add_bonding_slave_result *res = parsed_result;
-	portid_t master_port_id = res->port_id;
-	portid_t slave_port_id = res->slave_id;
-
-	/* add the slave for a bonded device. */
-	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
-		fprintf(stderr,
-			"\t Failed to add slave %d to master port = %d.\n",
-			slave_port_id, master_port_id);
-		return;
-	}
-	init_port_config();
-	set_port_slave_flag(slave_port_id);
-}
-
-cmdline_parse_token_string_t cmd_addbonding_slave_add =
-TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
-		add, "add");
-cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
-TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
-		bonding, "bonding");
-cmdline_parse_token_string_t cmd_addbonding_slave_slave =
-TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
-		slave, "slave");
-cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
-TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
-		slave_id, RTE_UINT16);
-cmdline_parse_token_num_t cmd_addbonding_slave_port =
-TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
-		port_id, RTE_UINT16);
-
-cmdline_parse_inst_t cmd_add_bonding_slave = {
-		.f = cmd_add_bonding_slave_parsed,
-		.help_str = "add bonding slave <slave_id> <port_id>: "
-			"Add a slave device to a bonded device",
-		.data = NULL,
-		.tokens = {
-				(void *)&cmd_addbonding_slave_add,
-				(void *)&cmd_addbonding_slave_bonding,
-				(void *)&cmd_addbonding_slave_slave,
-				(void *)&cmd_addbonding_slave_slaveid,
-				(void *)&cmd_addbonding_slave_port,
-				NULL
-		}
-};
-
-/* *** REMOVE SLAVE *** */
-struct cmd_remove_bonding_slave_result {
-	cmdline_fixed_string_t remove;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t slave;
-	portid_t slave_id;
-	portid_t port_id;
-};
-
-static void cmd_remove_bonding_slave_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_remove_bonding_slave_result *res = parsed_result;
-	portid_t master_port_id = res->port_id;
-	portid_t slave_port_id = res->slave_id;
-
-	/* remove the slave from a bonded device. */
-	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
-		fprintf(stderr,
-			"\t Failed to remove slave %d from master port = %d.\n",
-			slave_port_id, master_port_id);
-		return;
-	}
-	init_port_config();
-	clear_port_slave_flag(slave_port_id);
-}
-
-cmdline_parse_token_string_t cmd_removebonding_slave_remove =
-		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
-				remove, "remove");
-cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
-		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
-				bonding, "bonding");
-cmdline_parse_token_string_t cmd_removebonding_slave_slave =
-		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
-				slave, "slave");
-cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
-		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
-				slave_id, RTE_UINT16);
-cmdline_parse_token_num_t cmd_removebonding_slave_port =
-		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
-				port_id, RTE_UINT16);
-
-cmdline_parse_inst_t cmd_remove_bonding_slave = {
-		.f = cmd_remove_bonding_slave_parsed,
-		.help_str = "remove bonding slave <slave_id> <port_id>: "
-			"Remove a slave device from a bonded device",
-		.data = NULL,
-		.tokens = {
-				(void *)&cmd_removebonding_slave_remove,
-				(void *)&cmd_removebonding_slave_bonding,
-				(void *)&cmd_removebonding_slave_slave,
-				(void *)&cmd_removebonding_slave_slaveid,
-				(void *)&cmd_removebonding_slave_port,
-				NULL
-		}
-};
-
-/* *** CREATE BONDED DEVICE *** */
-struct cmd_create_bonded_device_result {
-	cmdline_fixed_string_t create;
-	cmdline_fixed_string_t bonded;
-	cmdline_fixed_string_t device;
-	uint8_t mode;
-	uint8_t socket;
-};
-
-static int bond_dev_num = 0;
-
-static void cmd_create_bonded_device_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_create_bonded_device_result *res = parsed_result;
-	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-	int port_id;
-	int ret;
-
-	if (test_done == 0) {
-		fprintf(stderr, "Please stop forwarding first\n");
-		return;
-	}
-
-	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d",
-			bond_dev_num++);
-
-	/* Create a new bonded device. */
-	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
-	if (port_id < 0) {
-		fprintf(stderr, "\t Failed to create bonded device.\n");
-		return;
-	} else {
-		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
-				port_id);
-
-		/* Update number of ports */
-		nb_ports = rte_eth_dev_count_avail();
-		reconfig(port_id, res->socket);
-		ret = rte_eth_promiscuous_enable(port_id);
-		if (ret != 0)
-			fprintf(stderr,
-				"Failed to enable promiscuous mode for port %u: %s - ignore\n",
-				port_id, rte_strerror(-ret));
-
-		ports[port_id].need_setup = 0;
-		ports[port_id].port_status = RTE_PORT_STOPPED;
-	}
-
-}
-
-cmdline_parse_token_string_t cmd_createbonded_device_create =
-		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
-				create, "create");
-cmdline_parse_token_string_t cmd_createbonded_device_bonded =
-		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
-				bonded, "bonded");
-cmdline_parse_token_string_t cmd_createbonded_device_device =
-		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
-				device, "device");
-cmdline_parse_token_num_t cmd_createbonded_device_mode =
-		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
-				mode, RTE_UINT8);
-cmdline_parse_token_num_t cmd_createbonded_device_socket =
-		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
-				socket, RTE_UINT8);
-
-cmdline_parse_inst_t cmd_create_bonded_device = {
-		.f = cmd_create_bonded_device_parsed,
-		.help_str = "create bonded device <mode> <socket>: "
-			"Create a new bonded device with specific bonding mode and socket",
-		.data = NULL,
-		.tokens = {
-				(void *)&cmd_createbonded_device_create,
-				(void *)&cmd_createbonded_device_bonded,
-				(void *)&cmd_createbonded_device_device,
-				(void *)&cmd_createbonded_device_mode,
-				(void *)&cmd_createbonded_device_socket,
-				NULL
-		}
-};
-
-/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
-struct cmd_set_bond_mac_addr_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t mac_addr;
-	uint16_t port_num;
-	struct rte_ether_addr address;
-};
-
-static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bond_mac_addr_result *res = parsed_result;
-	int ret;
-
-	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
-		return;
-
-	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
-
-	/* check the return value and print it if is < 0 */
-	if (ret < 0)
-		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
-			strerror(-ret));
-}
-
-cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
-		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
-cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
-		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
-				"bonding");
-cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
-		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
-				"mac_addr");
-cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
-		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result,
-				port_num, RTE_UINT16);
-cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
-		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
-
-cmdline_parse_inst_t cmd_set_bond_mac_addr = {
-		.f = cmd_set_bond_mac_addr_parsed,
-		.data = (void *) 0,
-		.help_str = "set bonding mac_addr <port_id> <mac_addr>",
-		.tokens = {
-				(void *)&cmd_set_bond_mac_addr_set,
-				(void *)&cmd_set_bond_mac_addr_bonding,
-				(void *)&cmd_set_bond_mac_addr_mac,
-				(void *)&cmd_set_bond_mac_addr_portnum,
-				(void *)&cmd_set_bond_mac_addr_addr,
-				NULL
-		}
-};
-
-
-/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
-struct cmd_set_bond_mon_period_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t mon_period;
-	uint16_t port_num;
-	uint32_t period_ms;
-};
-
-static void cmd_set_bond_mon_period_parsed(void *parsed_result,
-		__rte_unused  struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bond_mon_period_result *res = parsed_result;
-	int ret;
-
-	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
-
-	/* check the return value and print it if is < 0 */
-	if (ret < 0)
-		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
-			strerror(-ret));
-}
-
-cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
-		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
-				set, "set");
-cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
-		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
-				bonding, "bonding");
-cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
-		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
-				mon_period,	"mon_period");
-cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
-		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
-				port_num, RTE_UINT16);
-cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
-		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
-				period_ms, RTE_UINT32);
-
-cmdline_parse_inst_t cmd_set_bond_mon_period = {
-		.f = cmd_set_bond_mon_period_parsed,
-		.data = (void *) 0,
-		.help_str = "set bonding mon_period <port_id> <period_ms>",
-		.tokens = {
-				(void *)&cmd_set_bond_mon_period_set,
-				(void *)&cmd_set_bond_mon_period_bonding,
-				(void *)&cmd_set_bond_mon_period_mon_period,
-				(void *)&cmd_set_bond_mon_period_portnum,
-				(void *)&cmd_set_bond_mon_period_period_ms,
-				NULL
-		}
-};
-
-
-
-struct cmd_set_bonding_agg_mode_policy_result {
-	cmdline_fixed_string_t set;
-	cmdline_fixed_string_t bonding;
-	cmdline_fixed_string_t agg_mode;
-	uint16_t port_num;
-	cmdline_fixed_string_t policy;
-};
-
-
-static void
-cmd_set_bonding_agg_mode(void *parsed_result,
-		__rte_unused struct cmdline *cl,
-		__rte_unused void *data)
-{
-	struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result;
-	uint8_t policy = AGG_BANDWIDTH;
-
-	if (!strcmp(res->policy, "bandwidth"))
-		policy = AGG_BANDWIDTH;
-	else if (!strcmp(res->policy, "stable"))
-		policy = AGG_STABLE;
-	else if (!strcmp(res->policy, "count"))
-		policy = AGG_COUNT;
-
-	rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy);
-}
-
-
-cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set =
-	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
-				set, "set");
-cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding =
-	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
-				bonding, "bonding");
-
-cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode =
-	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
-				agg_mode, "agg_mode");
-
-cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum =
-	TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
-				port_num, RTE_UINT16);
-
-cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string =
-	TOKEN_STRING_INITIALIZER(
-			struct cmd_set_bonding_balance_xmit_policy_result,
-		policy, "stable#bandwidth#count");
-
-cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = {
-	.f = cmd_set_bonding_agg_mode,
-	.data = (void *) 0,
-	.help_str = "set bonding mode IEEE802.3AD aggregator policy <port_id> <agg_name>",
-	.tokens = {
-			(void *)&cmd_set_bonding_agg_mode_set,
-			(void *)&cmd_set_bonding_agg_mode_bonding,
-			(void *)&cmd_set_bonding_agg_mode_agg_mode,
-			(void *)&cmd_set_bonding_agg_mode_portnum,
-			(void *)&cmd_set_bonding_agg_mode_policy_string,
-			NULL
-		}
-};
-
-
-#endif /* RTE_NET_BOND */
-
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -17870,20 +16849,6 @@  static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_event,
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
-#ifdef RTE_NET_BOND
-	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
-	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
-	(cmdline_parse_inst_t *) &cmd_show_bonding_lacp_info,
-	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
-	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
-	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
-	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
-	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
-	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
-	(cmdline_parse_inst_t *) &cmd_set_bond_mon_period,
-	(cmdline_parse_inst_t *) &cmd_set_lacp_dedicated_queues,
-	(cmdline_parse_inst_t *) &cmd_set_bonding_agg_mode_policy,
-#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 46a7511e9a..07634332f3 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -58,9 +58,6 @@  endif
 if dpdk_conf.has('RTE_LIB_PDUMP')
     deps += 'pdump'
 endif
-if dpdk_conf.has('RTE_NET_BOND')
-    deps += 'net_bond'
-endif
 if dpdk_conf.has('RTE_NET_BNXT')
     deps += 'net_bnxt'
 endif
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 402b44be1a..faea892295 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -16,6 +16,7 @@  sources = files(
         'rte_eth_bond_flow.c',
         'rte_eth_bond_pmd.c',
 )
+testpmd_sources = files('rte_eth_bond_testpmd.c')
 
 deps += 'sched' # needed for rte_bitmap.h
 deps += ['ip_frag']
diff --git a/drivers/net/bonding/rte_eth_bond_testpmd.c b/drivers/net/bonding/rte_eth_bond_testpmd.c
new file mode 100644
index 0000000000..834e2da4e6
--- /dev/null
+++ b/drivers/net/bonding/rte_eth_bond_testpmd.c
@@ -0,0 +1,1037 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2016 Intel Corporation.
+ */
+
+#include <rte_eth_bond.h>
+#include <rte_eth_bond_8023ad.h>
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_etheraddr.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+
+#include "testpmd.h"
+
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	portid_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port = &ports[port_id];
+
+	/*
+	 * Bonding mode changed means resources of device changed, like whether
+	 * started rte timer or not. Device should be restarted when resources
+	 * of device changed.
+	 */
+	if (port->port_status != RTE_PORT_STOPPED) {
+		fprintf(stderr,
+			"\t Error: Can't set bonding mode when port %d is not stopped\n",
+			port_id);
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (rte_eth_bond_mode_set(port_id, res->value) != 0)
+		fprintf(stderr, "\t Failed to set bonding mode for port = %d.\n",
+			port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, RTE_UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, RTE_UINT16);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+		.f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode <mode_value> <port_id>: "
+			"Set the bonding mode for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_mode_set,
+				(void *)&cmd_setbonding_mode_bonding,
+				(void *)&cmd_setbonding_mode_mode,
+				(void *)&cmd_setbonding_mode_value,
+				(void *)&cmd_setbonding_mode_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING SLOW_QUEUE SW/HW *** */
+struct cmd_set_bonding_lacp_dedicated_queues_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t lacp;
+	cmdline_fixed_string_t dedicated_queues;
+	portid_t port_id;
+	cmdline_fixed_string_t mode;
+};
+
+static void cmd_set_bonding_lacp_dedicated_queues_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bonding_lacp_dedicated_queues_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	struct rte_port *port;
+
+	port = &ports[port_id];
+
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		fprintf(stderr, "Please stop port %d first\n", port_id);
+		return;
+	}
+
+	if (!strcmp(res->mode, "enable")) {
+		if (rte_eth_bond_8023ad_dedicated_queues_enable(port_id) == 0)
+			printf("Dedicate queues for LACP control packets"
+					" enabled\n");
+		else
+			printf("Enabling dedicate queues for LACP control "
+					"packets on port %d failed\n", port_id);
+	} else if (!strcmp(res->mode, "disable")) {
+		if (rte_eth_bond_8023ad_dedicated_queues_disable(port_id) == 0)
+			printf("Dedicated queues for LACP control packets "
+					"disabled\n");
+		else
+			printf("Disabling dedicated queues for LACP control "
+					"traffic on port %d failed\n", port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_lacp =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
+		lacp, "lacp");
+cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_dedicated_queues =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
+		dedicated_queues, "dedicated_queues");
+cmdline_parse_token_num_t cmd_setbonding_lacp_dedicated_queues_port_id =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
+		port_id, RTE_UINT16);
+cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result,
+		mode, "enable#disable");
+
+cmdline_parse_inst_t cmd_set_lacp_dedicated_queues = {
+		.f = cmd_set_bonding_lacp_dedicated_queues_parsed,
+		.help_str = "set bonding lacp dedicated_queues <port_id> "
+			"enable|disable: "
+			"Enable/disable dedicated queues for LACP control traffic for port_id",
+		.data = NULL,
+		.tokens = {
+			(void *)&cmd_setbonding_lacp_dedicated_queues_set,
+			(void *)&cmd_setbonding_lacp_dedicated_queues_bonding,
+			(void *)&cmd_setbonding_lacp_dedicated_queues_lacp,
+			(void *)&cmd_setbonding_lacp_dedicated_queues_dedicated_queues,
+			(void *)&cmd_setbonding_lacp_dedicated_queues_port_id,
+			(void *)&cmd_setbonding_lacp_dedicated_queues_mode,
+			NULL
+		}
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	portid_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		fprintf(stderr, "\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (rte_eth_bond_xmit_policy_set(port_id, policy) != 0) {
+		fprintf(stderr,
+			"\t Failed to set bonding balance xmit policy for port = %d.\n",
+			port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, RTE_UINT16);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+		.f = cmd_set_bonding_balance_xmit_policy_parsed,
+		.help_str = "set bonding balance_xmit_policy <port_id> "
+			"l2|l23|l34: "
+			"Set the bonding balance_xmit_policy for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_balance_xmit_policy_set,
+				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
+				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+				(void *)&cmd_setbonding_balance_xmit_policy_port,
+				(void *)&cmd_setbonding_balance_xmit_policy_policy,
+				NULL
+		}
+};
+
+/* *** SHOW IEEE802.3 BONDING INFORMATION *** */
+struct cmd_show_bonding_lacp_info_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t lacp;
+	cmdline_fixed_string_t info;
+	portid_t port_id;
+};
+
+static void port_param_show(struct port_params *params)
+{
+	char buf[RTE_ETHER_ADDR_FMT_SIZE];
+
+	printf("\t\tsystem priority: %u\n", params->system_priority);
+	rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, &params->system);
+	printf("\t\tsystem mac address: %s\n", buf);
+	printf("\t\tport key: %u\n", params->key);
+	printf("\t\tport priority: %u\n", params->port_priority);
+	printf("\t\tport number: %u\n", params->port_number);
+}
+
+static void lacp_slave_info_show(struct rte_eth_bond_8023ad_slave_info *info)
+{
+	char a_state[256] = { 0 };
+	char p_state[256] = { 0 };
+	int a_len = 0;
+	int p_len = 0;
+	uint32_t i;
+
+	static const char * const state[] = {
+		"ACTIVE",
+		"TIMEOUT",
+		"AGGREGATION",
+		"SYNCHRONIZATION",
+		"COLLECTING",
+		"DISTRIBUTING",
+		"DEFAULTED",
+		"EXPIRED"
+	};
+	static const char * const selection[] = {
+		"UNSELECTED",
+		"STANDBY",
+		"SELECTED"
+	};
+
+	for (i = 0; i < RTE_DIM(state); i++) {
+		if ((info->actor_state >> i) & 1)
+			a_len += snprintf(&a_state[a_len],
+						RTE_DIM(a_state) - a_len, "%s ",
+						state[i]);
+
+		if ((info->partner_state >> i) & 1)
+			p_len += snprintf(&p_state[p_len],
+						RTE_DIM(p_state) - p_len, "%s ",
+						state[i]);
+	}
+	printf("\tAggregator port id: %u\n", info->agg_port_id);
+	printf("\tselection: %s\n", selection[info->selected]);
+	printf("\tActor detail info:\n");
+	port_param_show(&info->actor);
+	printf("\t\tport state: %s\n", a_state);
+	printf("\tPartner detail info:\n");
+	port_param_show(&info->partner);
+	printf("\t\tport state: %s\n", p_state);
+	printf("\n");
+}
+
+static void lacp_conf_show(struct rte_eth_bond_8023ad_conf *conf)
+{
+	printf("\tfast period: %u ms\n", conf->fast_periodic_ms);
+	printf("\tslow period: %u ms\n", conf->slow_periodic_ms);
+	printf("\tshort timeout: %u ms\n", conf->short_timeout_ms);
+	printf("\tlong timeout: %u ms\n", conf->long_timeout_ms);
+	printf("\taggregate wait timeout: %u ms\n",
+			conf->aggregate_wait_timeout_ms);
+	printf("\ttx period: %u ms\n", conf->tx_period_ms);
+	printf("\trx marker period: %u ms\n", conf->rx_marker_period_ms);
+	printf("\tupdate timeout: %u ms\n", conf->update_timeout_ms);
+	switch (conf->agg_selection) {
+	case AGG_BANDWIDTH:
+		printf("\taggregation mode: bandwidth\n");
+		break;
+	case AGG_STABLE:
+		printf("\taggregation mode: stable\n");
+		break;
+	case AGG_COUNT:
+		printf("\taggregation mode: count\n");
+		break;
+	default:
+		printf("\taggregation mode: invalid\n");
+		break;
+	}
+
+	printf("\n");
+}
+
+static void cmd_show_bonding_lacp_info_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_show_bonding_lacp_info_result *res = parsed_result;
+	struct rte_eth_bond_8023ad_slave_info slave_info;
+	struct rte_eth_bond_8023ad_conf port_conf;
+	portid_t slaves[RTE_MAX_ETHPORTS];
+	portid_t port_id = res->port_id;
+	int num_active_slaves;
+	int bonding_mode;
+	int i;
+	int ret;
+
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode != BONDING_MODE_8023AD) {
+		fprintf(stderr, "\tBonding mode is not mode 4\n");
+		return;
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+			RTE_MAX_ETHPORTS);
+	if (num_active_slaves < 0) {
+		fprintf(stderr, "\tFailed to get active slave list for port = %u\n",
+				port_id);
+		return;
+	}
+	if (num_active_slaves == 0)
+		fprintf(stderr, "\tIEEE802.3 port %u has no active slave\n",
+			port_id);
+
+	printf("\tIEEE802.3 port: %u\n", port_id);
+	ret = rte_eth_bond_8023ad_conf_get(port_id, &port_conf);
+	if (ret) {
+		fprintf(stderr, "\tGet bonded device %u info failed\n",
+			port_id);
+		return;
+	}
+	lacp_conf_show(&port_conf);
+
+	for (i = 0; i < num_active_slaves; i++) {
+		ret = rte_eth_bond_8023ad_slave_info(port_id, slaves[i],
+				&slave_info);
+		if (ret) {
+			fprintf(stderr, "\tGet slave device %u info failed\n",
+				slaves[i]);
+			return;
+		}
+		printf("\tSlave Port: %u\n", slaves[i]);
+		lacp_slave_info_show(&slave_info);
+	}
+}
+
+cmdline_parse_token_string_t cmd_show_bonding_lacp_info_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_show_bonding_lacp_info_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_show_bonding_lacp_info_lacp =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
+		bonding, "lacp");
+cmdline_parse_token_string_t cmd_show_bonding_lacp_info_info =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
+		info, "info");
+cmdline_parse_token_num_t cmd_show_bonding_lacp_info_port_id =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_lacp_info_result,
+		port_id, RTE_UINT16);
+
+cmdline_parse_inst_t cmd_show_bonding_lacp_info = {
+		.f = cmd_show_bonding_lacp_info_parsed,
+		.help_str = "show bonding lacp info <port_id> : "
+			"Show bonding IEEE802.3 information for port_id",
+		.data = NULL,
+		.tokens = {
+			(void *)&cmd_show_bonding_lacp_info_show,
+			(void *)&cmd_show_bonding_lacp_info_bonding,
+			(void *)&cmd_show_bonding_lacp_info_lacp,
+			(void *)&cmd_show_bonding_lacp_info_info,
+			(void *)&cmd_show_bonding_lacp_info_port_id,
+			NULL
+		}
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	portid_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode, agg_mode;
+	portid_t slaves[RTE_MAX_ETHPORTS];
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		fprintf(stderr, "\tFailed to get bonding mode for port = %d\n",
+			port_id);
+		return;
+	}
+	printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE ||
+		bonding_mode == BONDING_MODE_8023AD) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			fprintf(stderr,
+				"\tFailed to get balance xmit policy for port = %d\n",
+				port_id);
+			return;
+		}
+		printf("\tBalance Xmit Policy: ");
+
+		switch (balance_xmit_policy) {
+		case BALANCE_XMIT_POLICY_LAYER2:
+			printf("BALANCE_XMIT_POLICY_LAYER2");
+			break;
+		case BALANCE_XMIT_POLICY_LAYER23:
+			printf("BALANCE_XMIT_POLICY_LAYER23");
+			break;
+		case BALANCE_XMIT_POLICY_LAYER34:
+			printf("BALANCE_XMIT_POLICY_LAYER34");
+			break;
+		}
+		printf("\n");
+	}
+
+	if (bonding_mode == BONDING_MODE_8023AD) {
+		agg_mode = rte_eth_bond_8023ad_agg_selection_get(port_id);
+		printf("\tIEEE802.3AD Aggregator Mode: ");
+		switch (agg_mode) {
+		case AGG_BANDWIDTH:
+			printf("bandwidth");
+			break;
+		case AGG_STABLE:
+			printf("stable");
+			break;
+		case AGG_COUNT:
+			printf("count");
+			break;
+		}
+		printf("\n");
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
+
+	if (num_slaves < 0) {
+		fprintf(stderr, "\tFailed to get slave list for port = %d\n",
+			port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+			RTE_MAX_ETHPORTS);
+
+	if (num_active_slaves < 0) {
+		fprintf(stderr,
+			"\tFailed to get active slave list for port = %d\n",
+			port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		fprintf(stderr, "\tFailed to get primary slave for port = %d\n",
+			port_id);
+		return;
+	}
+	printf("\tPrimary: [%d]\n", primary_id);
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, RTE_UINT16);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+		.f = cmd_show_bonding_config_parsed,
+		.help_str = "show bonding config <port_id>: "
+			"Show the bonding config for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_showbonding_config_show,
+				(void *)&cmd_showbonding_config_bonding,
+				(void *)&cmd_showbonding_config_config,
+				(void *)&cmd_showbonding_config_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	portid_t slave_id;
+	portid_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (rte_eth_bond_primary_set(master_port_id, slave_port_id) != 0) {
+		fprintf(stderr, "\t Failed to set primary slave for port = %d.\n",
+			master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, RTE_UINT16);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, RTE_UINT16);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+		.f = cmd_set_bonding_primary_parsed,
+		.help_str = "set bonding primary <slave_id> <port_id>: "
+			"Set the primary slave for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_primary_set,
+				(void *)&cmd_setbonding_primary_bonding,
+				(void *)&cmd_setbonding_primary_primary,
+				(void *)&cmd_setbonding_primary_slave,
+				(void *)&cmd_setbonding_primary_port,
+				NULL
+		}
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	portid_t slave_id;
+	portid_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* add the slave for a bonded device. */
+	if (rte_eth_bond_slave_add(master_port_id, slave_port_id) != 0) {
+		fprintf(stderr,
+			"\t Failed to add slave %d to master port = %d.\n",
+			slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+	set_port_slave_flag(slave_port_id);
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, RTE_UINT16);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, RTE_UINT16);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed,
+		.help_str = "add bonding slave <slave_id> <port_id>: "
+			"Add a slave device to a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_addbonding_slave_add,
+				(void *)&cmd_addbonding_slave_bonding,
+				(void *)&cmd_addbonding_slave_slave,
+				(void *)&cmd_addbonding_slave_slaveid,
+				(void *)&cmd_addbonding_slave_port,
+				NULL
+		}
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	portid_t slave_id;
+	portid_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* remove the slave from a bonded device. */
+	if (rte_eth_bond_slave_remove(master_port_id, slave_port_id) != 0) {
+		fprintf(stderr,
+			"\t Failed to remove slave %d from master port = %d.\n",
+			slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+	clear_port_slave_flag(slave_port_id);
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave_id, RTE_UINT16);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				port_id, RTE_UINT16);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+		.f = cmd_remove_bonding_slave_parsed,
+		.help_str = "remove bonding slave <slave_id> <port_id>: "
+			"Remove a slave device from a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_removebonding_slave_remove,
+				(void *)&cmd_removebonding_slave_bonding,
+				(void *)&cmd_removebonding_slave_slave,
+				(void *)&cmd_removebonding_slave_slaveid,
+				(void *)&cmd_removebonding_slave_port,
+				NULL
+		}
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static int bond_dev_num;
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int port_id;
+	int ret;
+
+	if (test_done == 0) {
+		fprintf(stderr, "Please stop forwarding first\n");
+		return;
+	}
+
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d",
+			bond_dev_num++);
+
+	/* Create a new bonded device. */
+	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
+	if (port_id < 0) {
+		fprintf(stderr, "\t Failed to create bonded device.\n");
+		return;
+	}
+	printf("Created new bonded device %s on (port %d).\n", ethdev_name,
+		port_id);
+
+	/* Update number of ports */
+	nb_ports = rte_eth_dev_count_avail();
+	reconfig(port_id, res->socket);
+	ret = rte_eth_promiscuous_enable(port_id);
+	if (ret != 0)
+		fprintf(stderr, "Failed to enable promiscuous mode for port %u: %s - ignore\n",
+			port_id, rte_strerror(-ret));
+
+	ports[port_id].need_setup = 0;
+	ports[port_id].port_status = RTE_PORT_STOPPED;
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				mode, RTE_UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				socket, RTE_UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+		.f = cmd_create_bonded_device_parsed,
+		.help_str = "create bonded device <mode> <socket>: "
+			"Create a new bonded device with specific bonding mode and socket",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_createbonded_device_create,
+				(void *)&cmd_createbonded_device_bonded,
+				(void *)&cmd_createbonded_device_device,
+				(void *)&cmd_createbonded_device_mode,
+				(void *)&cmd_createbonded_device_socket,
+				NULL
+		}
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint16_t port_num;
+	struct rte_ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
+			strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+				"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+				"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result,
+				port_num, RTE_UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed,
+		.data = NULL,
+		.help_str = "set bonding mac_addr <port_id> <mac_addr>",
+		.tokens = {
+				(void *)&cmd_set_bond_mac_addr_set,
+				(void *)&cmd_set_bond_mac_addr_bonding,
+				(void *)&cmd_set_bond_mac_addr_mac,
+				(void *)&cmd_set_bond_mac_addr_portnum,
+				(void *)&cmd_set_bond_mac_addr_addr,
+				NULL
+		}
+};
+
+/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
+struct cmd_set_bond_mon_period_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mon_period;
+	uint16_t port_num;
+	uint32_t period_ms;
+};
+
+static void cmd_set_bond_mon_period_parsed(void *parsed_result,
+		__rte_unused  struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bond_mon_period_result *res = parsed_result;
+	int ret;
+
+	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
+			strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
+				set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
+				mon_period,	"mon_period");
+cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
+				port_num, RTE_UINT16);
+cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
+				period_ms, RTE_UINT32);
+
+cmdline_parse_inst_t cmd_set_bond_mon_period = {
+		.f = cmd_set_bond_mon_period_parsed,
+		.data = NULL,
+		.help_str = "set bonding mon_period <port_id> <period_ms>",
+		.tokens = {
+				(void *)&cmd_set_bond_mon_period_set,
+				(void *)&cmd_set_bond_mon_period_bonding,
+				(void *)&cmd_set_bond_mon_period_mon_period,
+				(void *)&cmd_set_bond_mon_period_portnum,
+				(void *)&cmd_set_bond_mon_period_period_ms,
+				NULL
+		}
+};
+
+struct cmd_set_bonding_agg_mode_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t agg_mode;
+	uint16_t port_num;
+	cmdline_fixed_string_t policy;
+};
+
+static void
+cmd_set_bonding_agg_mode(void *parsed_result,
+		__rte_unused struct cmdline *cl,
+		__rte_unused void *data)
+{
+	struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result;
+	uint8_t policy = AGG_BANDWIDTH;
+
+	if (!strcmp(res->policy, "bandwidth"))
+		policy = AGG_BANDWIDTH;
+	else if (!strcmp(res->policy, "stable"))
+		policy = AGG_STABLE;
+	else if (!strcmp(res->policy, "count"))
+		policy = AGG_COUNT;
+
+	rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy);
+}
+
+cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
+				set, "set");
+cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
+				bonding, "bonding");
+
+cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
+				agg_mode, "agg_mode");
+
+cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
+				port_num, RTE_UINT16);
+
+cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "stable#bandwidth#count");
+
+cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = {
+	.f = cmd_set_bonding_agg_mode,
+	.data = NULL,
+	.help_str = "set bonding mode IEEE802.3AD aggregator policy <port_id> <agg_name>",
+	.tokens = {
+			(void *)&cmd_set_bonding_agg_mode_set,
+			(void *)&cmd_set_bonding_agg_mode_bonding,
+			(void *)&cmd_set_bonding_agg_mode_agg_mode,
+			(void *)&cmd_set_bonding_agg_mode_portnum,
+			(void *)&cmd_set_bonding_agg_mode_policy_string,
+			NULL
+		}
+};
+
+static struct testpmd_cmdline_parser driver_parser = {
+	.ctx = (cmdline_parse_ctx_t[]) {
+		(cmdline_parse_inst_t *)&cmd_set_bonding_mode,
+		(cmdline_parse_inst_t *)&cmd_show_bonding_config,
+		(cmdline_parse_inst_t *)&cmd_show_bonding_lacp_info,
+		(cmdline_parse_inst_t *)&cmd_set_bonding_primary,
+		(cmdline_parse_inst_t *)&cmd_add_bonding_slave,
+		(cmdline_parse_inst_t *)&cmd_remove_bonding_slave,
+		(cmdline_parse_inst_t *)&cmd_create_bonded_device,
+		(cmdline_parse_inst_t *)&cmd_set_bond_mac_addr,
+		(cmdline_parse_inst_t *)&cmd_set_balance_xmit_policy,
+		(cmdline_parse_inst_t *)&cmd_set_bond_mon_period,
+		(cmdline_parse_inst_t *)&cmd_set_lacp_dedicated_queues,
+		(cmdline_parse_inst_t *)&cmd_set_bonding_agg_mode_policy,
+		NULL
+	},
+	.help = {
+		"set bonding mode (value) (port_id)\n"
+		"	Set the bonding mode on a bonded device.\n",
+
+		"show bonding config (port_id)\n"
+		"	Show the bonding config for port_id.\n",
+
+		"show bonding lacp info (port_id)\n"
+		"	Show the bonding lacp information for port_id.\n",
+
+		"set bonding primary (slave_id) (port_id)\n"
+		"	Set the primary slave for a bonded device.\n",
+
+		"add bonding slave (slave_id) (port_id)\n"
+		"	Add a slave device to a bonded device.\n",
+
+		"remove bonding slave (slave_id) (port_id)\n"
+		"	Remove a slave device from a bonded device.\n",
+
+		"create bonded device (mode) (socket)\n"
+		"	Create a new bonded device with specific bonding mode and socket.\n",
+
+		"set bonding mac_addr (port_id) (address)\n"
+		"	Set the MAC address of a bonded device.\n",
+
+		"set bonding balance_xmit_policy (port_id) (l2|l23|l34)\n"
+		"	Set the transmit balance policy for bonded device running in balance mode.\n",
+
+		"set bonding mon_period (port_id) (value)\n"
+		"	Set the bonding link status monitoring polling period in ms.\n",
+
+		"set bonding lacp dedicated_queues <port_id> (enable|disable)\n"
+		"	Enable/disable dedicated queues for LACP control traffic.\n",
+
+		"set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)\n"
+		"	Set Aggregation mode for IEEE802.3AD (mode 4)\n",
+
+		NULL
+	},
+};
+
+RTE_INIT(bonding_testpmd)
+{
+	testpmd_add_commands(&driver_parser);
+}