diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ee8c121..7e7dd36 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -41,6 +41,8 @@
 #include <termios.h>
 #include <unistd.h>
 #include <inttypes.h>
+
+#include "rte_eth_bond_8023ad.h"
 #ifndef __linux__
 #ifndef __FreeBSD__
 #include <net/socket.h>
@@ -86,6 +88,7 @@
 #include <rte_pci_dev_ids.h>
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
+#include <rte_eth_bond_8023ad.h>
 #endif
 
 #include "testpmd.h"
@@ -3327,13 +3330,18 @@ static void cmd_show_bonding_config_parsed(void *parsed_result,
 		__attribute__((unused)) void *data)
 {
 	struct cmd_show_bonding_config_result *res = parsed_result;
+	struct rte_eth_bond_8023ad_slave_info slave_info;
+	static const char * const state_labels[] = {
+		"ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
+	};
 	int bonding_mode;
 	uint8_t slaves[RTE_MAX_ETHPORTS];
 	int num_slaves, num_active_slaves;
 	int primary_id;
-	int i;
+	int i, j;
 	portid_t port_id = res->port_id;
 
+
 	/* Display the bonding mode.*/
 	bonding_mode = rte_eth_bond_mode_get(port_id);
 	if (bonding_mode < 0) {
@@ -3342,7 +3350,8 @@ static void cmd_show_bonding_config_parsed(void *parsed_result,
 	} else
 		printf("\tBonding mode: %d\n", bonding_mode);
 
-	if (bonding_mode == BONDING_MODE_BALANCE) {
+	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);
@@ -3399,6 +3408,19 @@ static void cmd_show_bonding_config_parsed(void *parsed_result,
 
 		printf("%d]\n", slaves[num_active_slaves - 1]);
 
+		if (bonding_mode == BONDING_MODE_8023AD) {
+			for (i = 0; i < num_active_slaves; i++) {
+				rte_eth_bond_8023ad_slave_info(port_id, slaves[i], &slave_info);
+
+				printf("\tSlave %u state: ", slaves[i]);
+				for (j = 0; j < 8; j++) {
+					if ((slave_info.actor_state >> j) & 1)
+						printf("%s ", state_labels[j]);
+				}
+				printf("\n");
+			}
+		}
+
 	} else {
 		printf("\tActive Slaves: []\n");
 
@@ -3646,6 +3668,8 @@ static void cmd_create_bonded_device_parsed(void *parsed_result,
 		/* Update number of ports */
 		nb_ports = rte_eth_dev_count();
 		reconfig(port_id, res->socket);
+		/* Save bonding mode here as it is constat. */
+		ports[port_id].bond_mode = res->mode;
 		rte_eth_promiscuous_enable(port_id);
 	}
 
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 8d10bfd..c433eea 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -254,8 +254,17 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 	 */
 	nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
 				 nb_pkt_per_burst);
+#ifndef RTE_LIBRTE_PMD_BOND
 	if (unlikely(nb_rx == 0))
 		return;
+#else
+	if (unlikely(nb_rx == 0 && (fs->forward_timeout == 0 ||
+			fs->next_forward_time > rte_rdtsc())))
+		return;
+
+	if (fs->forward_timeout != 0)
+		fs->next_forward_time = rte_rdtsc() + fs->forward_timeout;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c
index 7fd4b6d..b7bec9f 100644
--- a/app/test-pmd/icmpecho.c
+++ b/app/test-pmd/icmpecho.c
@@ -305,6 +305,9 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs)
 	uint16_t arp_pro;
 	uint8_t  i;
 	int l2_len;
+#ifdef RTE_LIBRTE_PMD_BOND
+	uint8_t force_tx_burst;
+#endif
 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
 	uint64_t start_tsc;
 	uint64_t end_tsc;
@@ -320,8 +323,20 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs)
 	 */
 	nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
 				 nb_pkt_per_burst);
+#ifndef RTE_LIBRTE_PMD_BOND
 	if (unlikely(nb_rx == 0))
 		return;
+#else
+	if (unlikely(nb_rx == 0 && (fs->forward_timeout == 0 ||
+			fs->next_forward_time > rte_rdtsc())))
+		return;
+
+	if (fs->forward_timeout != 0) {
+		force_tx_burst = fs->next_forward_time <= rte_rdtsc();
+		fs->next_forward_time = rte_rdtsc() + fs->forward_timeout;
+	} else
+		force_tx_burst = 0;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
@@ -474,7 +489,11 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs)
 	}
 
 	/* Send back ICMP echo replies, if any. */
-	if (nb_replies > 0) {
+#ifdef RTE_LIBRTE_PMD_BOND
+		if (nb_replies > 0 || force_tx_burst) {
+#else
+		if  (nb_replies > 0)	{
+#endif
 		nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst,
 					 nb_replies);
 		fs->tx_packets += nb_tx;
diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c
index 02a5977..62a325f 100644
--- a/app/test-pmd/iofwd.c
+++ b/app/test-pmd/iofwd.c
@@ -96,8 +96,17 @@ pkt_burst_io_forward(struct fwd_stream *fs)
 	 */
 	nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
 				 nb_pkt_per_burst);
+#ifndef RTE_LIBRTE_PMD_BOND
 	if (unlikely(nb_rx == 0))
 		return;
+#else
+	if (unlikely(nb_rx == 0 && (fs->forward_timeout == 0 ||
+			fs->next_forward_time > rte_rdtsc())))
+		return;
+
+	if (fs->forward_timeout != 0)
+		fs->next_forward_time = rte_rdtsc() + fs->forward_timeout;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
diff --git a/app/test-pmd/macfwd-retry.c b/app/test-pmd/macfwd-retry.c
index 83da26f..fd100c0 100644
--- a/app/test-pmd/macfwd-retry.c
+++ b/app/test-pmd/macfwd-retry.c
@@ -110,8 +110,17 @@ pkt_burst_mac_retry_forward(struct fwd_stream *fs)
 	 */
 	nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
 				 nb_pkt_per_burst);
+#ifndef RTE_LIBRTE_PMD_BOND
 	if (unlikely(nb_rx == 0))
 		return;
+#else
+	if (unlikely(nb_rx == 0 && (fs->forward_timeout == 0 ||
+			fs->next_forward_time > rte_rdtsc())))
+		return;
+
+	if (fs->forward_timeout != 0)
+		fs->next_forward_time = rte_rdtsc() + fs->forward_timeout;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c
index 38bae23..2fa7d7d 100644
--- a/app/test-pmd/macfwd.c
+++ b/app/test-pmd/macfwd.c
@@ -100,8 +100,17 @@ pkt_burst_mac_forward(struct fwd_stream *fs)
 	 */
 	nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
 				 nb_pkt_per_burst);
+#ifndef RTE_LIBRTE_PMD_BOND
 	if (unlikely(nb_rx == 0))
 		return;
+#else
+	if (unlikely(nb_rx == 0 && (fs->forward_timeout == 0 ||
+			fs->next_forward_time > rte_rdtsc())))
+		return;
+
+	if (fs->forward_timeout != 0)
+		fs->next_forward_time = rte_rdtsc() + fs->forward_timeout;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
diff --git a/app/test-pmd/macswap.c b/app/test-pmd/macswap.c
index 1786095..042670d 100644
--- a/app/test-pmd/macswap.c
+++ b/app/test-pmd/macswap.c
@@ -100,8 +100,17 @@ pkt_burst_mac_swap(struct fwd_stream *fs)
 	 */
 	nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
 				 nb_pkt_per_burst);
+#ifndef RTE_LIBRTE_PMD_BOND
 	if (unlikely(nb_rx == 0))
 		return;
+#else
+	if (unlikely(nb_rx == 0 && (fs->forward_timeout == 0 ||
+			fs->next_forward_time > rte_rdtsc())))
+		return;
+
+	if (fs->forward_timeout != 0)
+		fs->next_forward_time = rte_rdtsc() + fs->forward_timeout;
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 	fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 8a4190b..7b90081 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -72,6 +72,9 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 #include <rte_eth_xenvirt.h>
 #endif
@@ -1022,9 +1025,13 @@ start_packet_forwarding(int with_tx_first)
 	port_fwd_begin_t port_fwd_begin;
 	port_fwd_end_t  port_fwd_end;
 	struct rte_port *port;
+	struct fwd_stream *fs;
 	unsigned int i;
 	portid_t   pt_id;
 	streamid_t sm_id;
+#ifdef RTE_LIBRTE_PMD_BOND
+	uint8_t is_mode4;
+#endif
 
 	if (all_ports_started() == 0) {
 		printf("Not all ports were started\n");
@@ -1050,7 +1057,6 @@ start_packet_forwarding(int with_tx_first)
 			return;
 		}
 	}
-	test_done = 0;
 
 	if(!no_flush_rx)
 		flush_fwd_rx_queues();
@@ -1067,11 +1073,35 @@ start_packet_forwarding(int with_tx_first)
 		map_port_queue_stats_mapping_registers(pt_id, port);
 	}
 	for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
-		fwd_streams[sm_id]->rx_packets = 0;
-		fwd_streams[sm_id]->tx_packets = 0;
-		fwd_streams[sm_id]->fwd_dropped = 0;
-		fwd_streams[sm_id]->rx_bad_ip_csum = 0;
-		fwd_streams[sm_id]->rx_bad_l4_csum = 0;
+		fs = fwd_streams[sm_id];
+		fs->rx_packets = 0;
+		fs->tx_packets = 0;
+		fs->fwd_dropped = 0;
+		fs->rx_bad_ip_csum = 0;
+		fs->rx_bad_l4_csum = 0;
+
+#ifdef RTE_LIBRTE_PMD_BOND
+		is_mode4 = ports[fs->rx_port].bond_mode == BONDING_MODE_8023AD ||
+				ports[fs->tx_port].bond_mode == BONDING_MODE_8023AD;
+
+		if (is_mode4) {
+			if (cur_fwd_config.fwd_eng == &rx_only_engine ||
+				cur_fwd_config.fwd_eng == &tx_only_engine
+#ifdef RTE_LIBRTE_IEEE1588
+				|| cur_fwd_config.fwd_eng == &ieee1588_fwd_engine
+#endif
+			) {
+				printf("Selected forwarding engine '%s' is not supported in "
+					"mode 802.3ad of link bonding.\n",
+					cur_fwd_config.fwd_eng->fwd_mode_name);
+
+				return;
+			}
+			fs->forward_timeout = 100 * rte_get_tsc_hz() / 1000;
+			fs->next_forward_time = 0; /* force forward */
+		} else
+			fs->forward_timeout = 0; /* force forward is disabled */
+#endif
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
 		memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
@@ -1083,6 +1113,9 @@ start_packet_forwarding(int with_tx_first)
 		fwd_streams[sm_id]->core_cycles = 0;
 #endif
 	}
+
+	test_done = 0;
+
 	if (with_tx_first) {
 		port_fwd_begin = tx_only_engine.port_fwd_begin;
 		if (port_fwd_begin != NULL) {
@@ -1284,6 +1317,11 @@ start_port(portid_t pid)
 	struct rte_port *port;
 	struct ether_addr mac_addr;
 
+	if (pid >= nb_ports && pid != RTE_PORT_ALL) {
+		printf("Invalid port id %u\n", pid);
+		return -1;
+	}
+
 	if (test_done == 0) {
 		printf("Please stop forwarding first\n");
 		return -1;
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 5a3423c..4830775 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -40,7 +40,7 @@
 int main(int argc, char **argv);
 #endif
 
-#define RTE_PORT_ALL            (~(portid_t)0x0)
+#define RTE_PORT_ALL            ((portid_t)(~0x0))
 
 #define RTE_TEST_RX_DESC_MAX    2048
 #define RTE_TEST_TX_DESC_MAX    2048
@@ -121,6 +121,10 @@ struct fwd_stream {
 	struct pkt_burst_stats rx_burst_stats;
 	struct pkt_burst_stats tx_burst_stats;
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+	uint64_t forward_timeout; /** Timeout used to force RX/TX */
+	uint64_t next_forward_time; /**< Next time when RX/TX should be issued. */
+#endif
 };
 
 /**
@@ -152,7 +156,10 @@ struct rte_port {
 	uint8_t                 need_reconfig;  /**< need reconfiguring port or not */
 	uint8_t                 need_reconfig_queues; /**< need reconfiguring queues or not */
 	uint8_t                 rss_flag;   /**< enable rss or not */
-	uint8_t			dcb_flag;   /**< enable dcb */
+	uint8_t	                dcb_flag;   /**< enable dcb */
+#ifdef RTE_LIBRTE_PMD_BOND
+	int8_t                  bond_mode;  /**< Port bonding mode */
+#endif
 	struct rte_eth_rxconf   rx_conf;    /**< rx configuration */
 	struct rte_eth_txconf   tx_conf;    /**< tx configuration */
 };
