xref: /dpdk/app/test/test_link_bonding.c (revision 844949ec)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include "unistd.h"
6 #include <string.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <inttypes.h>
12 #include <errno.h>
13 #include <sys/queue.h>
14 #include <sys/time.h>
15 #include <rte_cycles.h>
16 #include <rte_byteorder.h>
17 #include <rte_common.h>
18 #include <rte_debug.h>
19 #include <rte_ethdev.h>
20 #include <rte_ethdev_driver.h>
21 #include <rte_log.h>
22 #include <rte_lcore.h>
23 #include <rte_memory.h>
24 #include <rte_string_fns.h>
25 #include <rte_eth_bond.h>
26 
27 #include "virtual_pmd.h"
28 #include "packet_burst_generator.h"
29 
30 #include "test.h"
31 
32 #define TEST_MAX_NUMBER_OF_PORTS (6)
33 
34 #define RX_RING_SIZE 1024
35 #define RX_FREE_THRESH 32
36 #define RX_PTHRESH 8
37 #define RX_HTHRESH 8
38 #define RX_WTHRESH 0
39 
40 #define TX_RING_SIZE 1024
41 #define TX_FREE_THRESH 32
42 #define TX_PTHRESH 32
43 #define TX_HTHRESH 0
44 #define TX_WTHRESH 0
45 #define TX_RSBIT_THRESH 32
46 
47 #define MBUF_CACHE_SIZE (250)
48 #define BURST_SIZE (32)
49 
50 #define RTE_TEST_RX_DESC_MAX	(2048)
51 #define RTE_TEST_TX_DESC_MAX	(2048)
52 #define MAX_PKT_BURST			(512)
53 #define DEF_PKT_BURST			(16)
54 
55 #define BONDED_DEV_NAME			("net_bonding_ut")
56 
57 #define INVALID_SOCKET_ID		(-1)
58 #define INVALID_PORT_ID			(-1)
59 #define INVALID_BONDING_MODE	(-1)
60 
61 
62 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
63 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
64 
65 struct link_bonding_unittest_params {
66 	int16_t bonded_port_id;
67 	int16_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
68 	uint16_t bonded_slave_count;
69 	uint8_t bonding_mode;
70 
71 	uint16_t nb_rx_q;
72 	uint16_t nb_tx_q;
73 
74 	struct rte_mempool *mbuf_pool;
75 
76 	struct rte_ether_addr *default_slave_mac;
77 	struct rte_ether_addr *default_bonded_mac;
78 
79 	/* Packet Headers */
80 	struct rte_ether_hdr *pkt_eth_hdr;
81 	struct rte_ipv4_hdr *pkt_ipv4_hdr;
82 	struct rte_ipv6_hdr *pkt_ipv6_hdr;
83 	struct rte_udp_hdr *pkt_udp_hdr;
84 
85 };
86 
87 static struct rte_ipv4_hdr pkt_ipv4_hdr;
88 static struct rte_ipv6_hdr pkt_ipv6_hdr;
89 static struct rte_udp_hdr pkt_udp_hdr;
90 
91 static struct link_bonding_unittest_params default_params  = {
92 	.bonded_port_id = -1,
93 	.slave_port_ids = { -1 },
94 	.bonded_slave_count = 0,
95 	.bonding_mode = BONDING_MODE_ROUND_ROBIN,
96 
97 	.nb_rx_q = 1,
98 	.nb_tx_q = 1,
99 
100 	.mbuf_pool = NULL,
101 
102 	.default_slave_mac = (struct rte_ether_addr *)slave_mac,
103 	.default_bonded_mac = (struct rte_ether_addr *)bonded_mac,
104 
105 	.pkt_eth_hdr = NULL,
106 	.pkt_ipv4_hdr = &pkt_ipv4_hdr,
107 	.pkt_ipv6_hdr = &pkt_ipv6_hdr,
108 	.pkt_udp_hdr = &pkt_udp_hdr
109 
110 };
111 
112 static struct link_bonding_unittest_params *test_params = &default_params;
113 
114 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
115 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
116 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
117 
118 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
119 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
120 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
121 
122 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
123 		0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA  };
124 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
125 		0xAA, 0xFF, 0xAA,  0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA  };
126 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
127 		0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB  };
128 
129 static uint16_t src_port = 1024;
130 static uint16_t dst_port_0 = 1024;
131 static uint16_t dst_port_1 = 2024;
132 
133 static uint16_t vlan_id = 0x100;
134 
135 static struct rte_eth_conf default_pmd_conf = {
136 	.rxmode = {
137 		.mq_mode = ETH_MQ_RX_NONE,
138 		.split_hdr_size = 0,
139 		.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
140 	},
141 	.txmode = {
142 		.mq_mode = ETH_MQ_TX_NONE,
143 	},
144 	.lpbk_mode = 0,
145 };
146 
147 static const struct rte_eth_rxconf rx_conf_default = {
148 	.rx_thresh = {
149 		.pthresh = RX_PTHRESH,
150 		.hthresh = RX_HTHRESH,
151 		.wthresh = RX_WTHRESH,
152 	},
153 	.rx_free_thresh = RX_FREE_THRESH,
154 	.rx_drop_en = 0,
155 };
156 
157 static struct rte_eth_txconf tx_conf_default = {
158 	.tx_thresh = {
159 		.pthresh = TX_PTHRESH,
160 		.hthresh = TX_HTHRESH,
161 		.wthresh = TX_WTHRESH,
162 	},
163 	.tx_free_thresh = TX_FREE_THRESH,
164 	.tx_rs_thresh = TX_RSBIT_THRESH,
165 };
166 
167 static void free_virtualpmd_tx_queue(void);
168 
169 
170 
171 static int
172 configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
173 {
174 	int q_id;
175 
176 	if (en_isr)
177 		default_pmd_conf.intr_conf.lsc = 1;
178 	else
179 		default_pmd_conf.intr_conf.lsc = 0;
180 
181 	TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
182 			test_params->nb_tx_q, &default_pmd_conf),
183 			"rte_eth_dev_configure for port %d failed", port_id);
184 
185 	for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
186 		TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
187 				rte_eth_dev_socket_id(port_id), &rx_conf_default,
188 				test_params->mbuf_pool) ,
189 				"rte_eth_rx_queue_setup for port %d failed", port_id);
190 
191 	for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
192 		TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
193 				rte_eth_dev_socket_id(port_id), &tx_conf_default),
194 				"rte_eth_tx_queue_setup for port %d failed", port_id);
195 
196 	if (start)
197 		TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
198 				"rte_eth_dev_start for port %d failed", port_id);
199 
200 	return 0;
201 }
202 
203 static int slaves_initialized;
204 static int mac_slaves_initialized;
205 
206 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
207 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
208 
209 
210 static int
211 test_setup(void)
212 {
213 	int i, nb_mbuf_per_pool;
214 	struct rte_ether_addr *mac_addr = (struct rte_ether_addr *)slave_mac;
215 
216 	/* Allocate ethernet packet header with space for VLAN header */
217 	if (test_params->pkt_eth_hdr == NULL) {
218 		test_params->pkt_eth_hdr = malloc(sizeof(struct rte_ether_hdr) +
219 				sizeof(struct rte_vlan_hdr));
220 
221 		TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
222 				"Ethernet header struct allocation failed!");
223 	}
224 
225 	nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
226 			RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
227 	if (test_params->mbuf_pool == NULL) {
228 		test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
229 			nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
230 			RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
231 		TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
232 				"rte_mempool_create failed");
233 	}
234 
235 	/* Create / Initialize virtual eth devs */
236 	if (!slaves_initialized) {
237 		for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
238 			char pmd_name[RTE_ETH_NAME_MAX_LEN];
239 
240 			mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
241 
242 			snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
243 
244 			test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
245 					mac_addr, rte_socket_id(), 1);
246 			TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
247 					"Failed to create virtual virtual ethdev %s", pmd_name);
248 
249 			TEST_ASSERT_SUCCESS(configure_ethdev(
250 					test_params->slave_port_ids[i], 1, 0),
251 					"Failed to configure virtual ethdev %s", pmd_name);
252 		}
253 		slaves_initialized = 1;
254 	}
255 
256 	return 0;
257 }
258 
259 static int
260 test_create_bonded_device(void)
261 {
262 	int current_slave_count;
263 
264 	uint16_t slaves[RTE_MAX_ETHPORTS];
265 
266 	/* Don't try to recreate bonded device if re-running test suite*/
267 	if (test_params->bonded_port_id == -1) {
268 		test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
269 				test_params->bonding_mode, rte_socket_id());
270 
271 		TEST_ASSERT(test_params->bonded_port_id >= 0,
272 				"Failed to create bonded ethdev %s", BONDED_DEV_NAME);
273 
274 		TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
275 				"Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
276 	}
277 
278 	TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
279 			test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
280 			test_params->bonded_port_id, test_params->bonding_mode);
281 
282 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
283 			slaves, RTE_MAX_ETHPORTS);
284 
285 	TEST_ASSERT_EQUAL(current_slave_count, 0,
286 			"Number of slaves %d is great than expected %d.",
287 			current_slave_count, 0);
288 
289 	current_slave_count = rte_eth_bond_active_slaves_get(
290 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
291 
292 	TEST_ASSERT_EQUAL(current_slave_count, 0,
293 			"Number of active slaves %d is great than expected %d.",
294 			current_slave_count, 0);
295 
296 	return 0;
297 }
298 
299 
300 static int
301 test_create_bonded_device_with_invalid_params(void)
302 {
303 	int port_id;
304 
305 	test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
306 
307 	/* Invalid name */
308 	port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
309 			rte_socket_id());
310 	TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
311 
312 	test_params->bonding_mode = INVALID_BONDING_MODE;
313 
314 	/* Invalid bonding mode */
315 	port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
316 			rte_socket_id());
317 	TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
318 
319 	test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
320 
321 	/* Invalid socket id */
322 	port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
323 			INVALID_SOCKET_ID);
324 	TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
325 
326 	return 0;
327 }
328 
329 static int
330 test_add_slave_to_bonded_device(void)
331 {
332 	int current_slave_count;
333 
334 	uint16_t slaves[RTE_MAX_ETHPORTS];
335 
336 	TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
337 			test_params->slave_port_ids[test_params->bonded_slave_count]),
338 			"Failed to add slave (%d) to bonded port (%d).",
339 			test_params->slave_port_ids[test_params->bonded_slave_count],
340 			test_params->bonded_port_id);
341 
342 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
343 			slaves, RTE_MAX_ETHPORTS);
344 	TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
345 			"Number of slaves (%d) is greater than expected (%d).",
346 			current_slave_count, test_params->bonded_slave_count + 1);
347 
348 	current_slave_count = rte_eth_bond_active_slaves_get(
349 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
350 	TEST_ASSERT_EQUAL(current_slave_count, 0,
351 					"Number of active slaves (%d) is not as expected (%d).\n",
352 					current_slave_count, 0);
353 
354 	test_params->bonded_slave_count++;
355 
356 	return 0;
357 }
358 
359 static int
360 test_add_slave_to_invalid_bonded_device(void)
361 {
362 	/* Invalid port ID */
363 	TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
364 			test_params->slave_port_ids[test_params->bonded_slave_count]),
365 			"Expected call to failed as invalid port specified.");
366 
367 	/* Non bonded device */
368 	TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
369 			test_params->slave_port_ids[test_params->bonded_slave_count]),
370 			"Expected call to failed as invalid port specified.");
371 
372 	return 0;
373 }
374 
375 
376 static int
377 test_remove_slave_from_bonded_device(void)
378 {
379 	int current_slave_count;
380 	struct rte_ether_addr read_mac_addr, *mac_addr;
381 	uint16_t slaves[RTE_MAX_ETHPORTS];
382 
383 	TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
384 			test_params->slave_port_ids[test_params->bonded_slave_count-1]),
385 			"Failed to remove slave %d from bonded port (%d).",
386 			test_params->slave_port_ids[test_params->bonded_slave_count-1],
387 			test_params->bonded_port_id);
388 
389 
390 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
391 			slaves, RTE_MAX_ETHPORTS);
392 
393 	TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
394 			"Number of slaves (%d) is great than expected (%d).\n",
395 			current_slave_count, test_params->bonded_slave_count - 1);
396 
397 
398 	mac_addr = (struct rte_ether_addr *)slave_mac;
399 	mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] =
400 			test_params->bonded_slave_count-1;
401 
402 	rte_eth_macaddr_get(
403 			test_params->slave_port_ids[test_params->bonded_slave_count-1],
404 			&read_mac_addr);
405 	TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
406 			"bonded port mac address not set to that of primary port\n");
407 
408 	rte_eth_stats_reset(
409 			test_params->slave_port_ids[test_params->bonded_slave_count-1]);
410 
411 	virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
412 			0);
413 
414 	test_params->bonded_slave_count--;
415 
416 	return 0;
417 }
418 
419 static int
420 test_remove_slave_from_invalid_bonded_device(void)
421 {
422 	/* Invalid port ID */
423 	TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
424 			test_params->bonded_port_id + 5,
425 			test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
426 			"Expected call to failed as invalid port specified.");
427 
428 	/* Non bonded device */
429 	TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
430 			test_params->slave_port_ids[0],
431 			test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
432 			"Expected call to failed as invalid port specified.");
433 
434 	return 0;
435 }
436 
437 static int bonded_id = 2;
438 
439 static int
440 test_add_already_bonded_slave_to_bonded_device(void)
441 {
442 	int port_id, current_slave_count;
443 	uint16_t slaves[RTE_MAX_ETHPORTS];
444 	char pmd_name[RTE_ETH_NAME_MAX_LEN];
445 
446 	test_add_slave_to_bonded_device();
447 
448 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
449 			slaves, RTE_MAX_ETHPORTS);
450 	TEST_ASSERT_EQUAL(current_slave_count, 1,
451 			"Number of slaves (%d) is not that expected (%d).",
452 			current_slave_count, 1);
453 
454 	snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
455 
456 	port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
457 			rte_socket_id());
458 	TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
459 
460 	TEST_ASSERT(rte_eth_bond_slave_add(port_id,
461 			test_params->slave_port_ids[test_params->bonded_slave_count - 1])
462 			< 0,
463 			"Added slave (%d) to bonded port (%d) unexpectedly.",
464 			test_params->slave_port_ids[test_params->bonded_slave_count-1],
465 			port_id);
466 
467 	return test_remove_slave_from_bonded_device();
468 }
469 
470 
471 static int
472 test_get_slaves_from_bonded_device(void)
473 {
474 	int current_slave_count;
475 	uint16_t slaves[RTE_MAX_ETHPORTS];
476 
477 	TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
478 			"Failed to add slave to bonded device");
479 
480 	/* Invalid port id */
481 	current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
482 			RTE_MAX_ETHPORTS);
483 	TEST_ASSERT(current_slave_count < 0,
484 			"Invalid port id unexpectedly succeeded");
485 
486 	current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
487 			slaves, RTE_MAX_ETHPORTS);
488 	TEST_ASSERT(current_slave_count < 0,
489 			"Invalid port id unexpectedly succeeded");
490 
491 	/* Invalid slaves pointer */
492 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
493 			NULL, RTE_MAX_ETHPORTS);
494 	TEST_ASSERT(current_slave_count < 0,
495 			"Invalid slave array unexpectedly succeeded");
496 
497 	current_slave_count = rte_eth_bond_active_slaves_get(
498 			test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
499 	TEST_ASSERT(current_slave_count < 0,
500 			"Invalid slave array unexpectedly succeeded");
501 
502 	/* non bonded device*/
503 	current_slave_count = rte_eth_bond_slaves_get(
504 			test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
505 	TEST_ASSERT(current_slave_count < 0,
506 			"Invalid port id unexpectedly succeeded");
507 
508 	current_slave_count = rte_eth_bond_active_slaves_get(
509 			test_params->slave_port_ids[0],	NULL, RTE_MAX_ETHPORTS);
510 	TEST_ASSERT(current_slave_count < 0,
511 			"Invalid port id unexpectedly succeeded");
512 
513 	TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
514 			"Failed to remove slaves from bonded device");
515 
516 	return 0;
517 }
518 
519 
520 static int
521 test_add_remove_multiple_slaves_to_from_bonded_device(void)
522 {
523 	int i;
524 
525 	for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
526 		TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
527 				"Failed to add slave to bonded device");
528 
529 	for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
530 		TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
531 				"Failed to remove slaves from bonded device");
532 
533 	return 0;
534 }
535 
536 static void
537 enable_bonded_slaves(void)
538 {
539 	int i;
540 
541 	for (i = 0; i < test_params->bonded_slave_count; i++) {
542 		virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
543 				1);
544 
545 		virtual_ethdev_simulate_link_status_interrupt(
546 				test_params->slave_port_ids[i], 1);
547 	}
548 }
549 
550 static int
551 test_start_bonded_device(void)
552 {
553 	struct rte_eth_link link_status;
554 
555 	int current_slave_count, current_bonding_mode, primary_port;
556 	uint16_t slaves[RTE_MAX_ETHPORTS];
557 	int retval;
558 
559 	/* Add slave to bonded device*/
560 	TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
561 			"Failed to add slave to bonded device");
562 
563 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
564 		"Failed to start bonded pmd eth device %d.",
565 		test_params->bonded_port_id);
566 
567 	/* Change link status of virtual pmd so it will be added to the active
568 	 * slave list of the bonded device*/
569 	virtual_ethdev_simulate_link_status_interrupt(
570 			test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
571 
572 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
573 			slaves, RTE_MAX_ETHPORTS);
574 	TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
575 			"Number of slaves (%d) is not expected value (%d).",
576 			current_slave_count, test_params->bonded_slave_count);
577 
578 	current_slave_count = rte_eth_bond_active_slaves_get(
579 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
580 	TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
581 			"Number of active slaves (%d) is not expected value (%d).",
582 			current_slave_count, test_params->bonded_slave_count);
583 
584 	current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
585 	TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
586 			"Bonded device mode (%d) is not expected value (%d).\n",
587 			current_bonding_mode, test_params->bonding_mode);
588 
589 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
590 	TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
591 			"Primary port (%d) is not expected value (%d).",
592 			primary_port, test_params->slave_port_ids[0]);
593 
594 	retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
595 	TEST_ASSERT(retval >= 0,
596 			"Bonded port (%d) link get failed: %s\n",
597 			test_params->bonded_port_id, rte_strerror(-retval));
598 	TEST_ASSERT_EQUAL(link_status.link_status, 1,
599 			"Bonded port (%d) status (%d) is not expected value (%d).\n",
600 			test_params->bonded_port_id, link_status.link_status, 1);
601 
602 	return 0;
603 }
604 
605 static int
606 test_stop_bonded_device(void)
607 {
608 	int current_slave_count;
609 	uint16_t slaves[RTE_MAX_ETHPORTS];
610 
611 	struct rte_eth_link link_status;
612 	int retval;
613 
614 	rte_eth_dev_stop(test_params->bonded_port_id);
615 
616 	retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
617 	TEST_ASSERT(retval >= 0,
618 			"Bonded port (%d) link get failed: %s\n",
619 			test_params->bonded_port_id, rte_strerror(-retval));
620 	TEST_ASSERT_EQUAL(link_status.link_status, 0,
621 			"Bonded port (%d) status (%d) is not expected value (%d).",
622 			test_params->bonded_port_id, link_status.link_status, 0);
623 
624 	current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
625 			slaves, RTE_MAX_ETHPORTS);
626 	TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
627 			"Number of slaves (%d) is not expected value (%d).",
628 			current_slave_count, test_params->bonded_slave_count);
629 
630 	current_slave_count = rte_eth_bond_active_slaves_get(
631 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
632 	TEST_ASSERT_EQUAL(current_slave_count, 0,
633 			"Number of active slaves (%d) is not expected value (%d).",
634 			current_slave_count, 0);
635 
636 	return 0;
637 }
638 
639 static int
640 remove_slaves_and_stop_bonded_device(void)
641 {
642 	/* Clean up and remove slaves from bonded device */
643 	free_virtualpmd_tx_queue();
644 	while (test_params->bonded_slave_count > 0)
645 		TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
646 				"test_remove_slave_from_bonded_device failed");
647 
648 	rte_eth_dev_stop(test_params->bonded_port_id);
649 	rte_eth_stats_reset(test_params->bonded_port_id);
650 	rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
651 
652 	return 0;
653 }
654 
655 static int
656 test_set_bonding_mode(void)
657 {
658 	int i, bonding_mode;
659 
660 	int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
661 							BONDING_MODE_ACTIVE_BACKUP,
662 							BONDING_MODE_BALANCE,
663 							BONDING_MODE_BROADCAST
664 							};
665 
666 	/* Test supported link bonding modes */
667 	for (i = 0; i < (int)RTE_DIM(bonding_modes);	i++) {
668 		/* Invalid port ID */
669 		TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
670 				bonding_modes[i]),
671 				"Expected call to failed as invalid port (%d) specified.",
672 				INVALID_PORT_ID);
673 
674 		/* Non bonded device */
675 		TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
676 				bonding_modes[i]),
677 				"Expected call to failed as invalid port (%d) specified.",
678 				test_params->slave_port_ids[0]);
679 
680 		TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
681 				bonding_modes[i]),
682 				"Failed to set link bonding mode on port (%d) to (%d).",
683 				test_params->bonded_port_id, bonding_modes[i]);
684 
685 		bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
686 		TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
687 				"Link bonding mode (%d) of port (%d) is not expected value (%d).",
688 				bonding_mode, test_params->bonded_port_id,
689 				bonding_modes[i]);
690 
691 		/* Invalid port ID */
692 		bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
693 		TEST_ASSERT(bonding_mode < 0,
694 				"Expected call to failed as invalid port (%d) specified.",
695 				INVALID_PORT_ID);
696 
697 		/* Non bonded device */
698 		bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
699 		TEST_ASSERT(bonding_mode < 0,
700 				"Expected call to failed as invalid port (%d) specified.",
701 				test_params->slave_port_ids[0]);
702 	}
703 
704 	return remove_slaves_and_stop_bonded_device();
705 }
706 
707 static int
708 test_set_primary_slave(void)
709 {
710 	int i, j, retval;
711 	struct rte_ether_addr read_mac_addr;
712 	struct rte_ether_addr *expected_mac_addr;
713 
714 	/* Add 4 slaves to bonded device */
715 	for (i = test_params->bonded_slave_count; i < 4; i++)
716 		TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
717 				"Failed to add slave to bonded device.");
718 
719 	TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
720 			BONDING_MODE_ROUND_ROBIN),
721 			"Failed to set link bonding mode on port (%d) to (%d).",
722 			test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
723 
724 	/* Invalid port ID */
725 	TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
726 			test_params->slave_port_ids[i]),
727 			"Expected call to failed as invalid port specified.");
728 
729 	/* Non bonded device */
730 	TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
731 			test_params->slave_port_ids[i]),
732 			"Expected call to failed as invalid port specified.");
733 
734 	/* Set slave as primary
735 	 * Verify slave it is now primary slave
736 	 * Verify that MAC address of bonded device is that of primary slave
737 	 * Verify that MAC address of all bonded slaves are that of primary slave
738 	 */
739 	for (i = 0; i < 4; i++) {
740 		TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
741 				test_params->slave_port_ids[i]),
742 				"Failed to set bonded port (%d) primary port to (%d)",
743 				test_params->bonded_port_id, test_params->slave_port_ids[i]);
744 
745 		retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
746 		TEST_ASSERT(retval >= 0,
747 				"Failed to read primary port from bonded port (%d)\n",
748 					test_params->bonded_port_id);
749 
750 		TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
751 				"Bonded port (%d) primary port (%d) not expected value (%d)\n",
752 				test_params->bonded_port_id, retval,
753 				test_params->slave_port_ids[i]);
754 
755 		/* stop/start bonded eth dev to apply new MAC */
756 		rte_eth_dev_stop(test_params->bonded_port_id);
757 
758 		TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
759 				"Failed to start bonded port %d",
760 				test_params->bonded_port_id);
761 
762 		expected_mac_addr = (struct rte_ether_addr *)&slave_mac;
763 		expected_mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
764 
765 		/* Check primary slave MAC */
766 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
767 		TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
768 				sizeof(read_mac_addr)),
769 				"bonded port mac address not set to that of primary port\n");
770 
771 		/* Check bonded MAC */
772 		rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
773 		TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
774 				sizeof(read_mac_addr)),
775 				"bonded port mac address not set to that of primary port\n");
776 
777 		/* Check other slaves MACs */
778 		for (j = 0; j < 4; j++) {
779 			if (j != i) {
780 				rte_eth_macaddr_get(test_params->slave_port_ids[j],
781 						&read_mac_addr);
782 				TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
783 						sizeof(read_mac_addr)),
784 						"slave port mac address not set to that of primary "
785 						"port");
786 			}
787 		}
788 	}
789 
790 
791 	/* Test with none existent port */
792 	TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
793 			"read primary port from expectedly");
794 
795 	/* Test with slave port */
796 	TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
797 			"read primary port from expectedly\n");
798 
799 	TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
800 			"Failed to stop and remove slaves from bonded device");
801 
802 	/* No slaves  */
803 	TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id)  < 0,
804 			"read primary port from expectedly\n");
805 
806 	return 0;
807 }
808 
809 static int
810 test_set_explicit_bonded_mac(void)
811 {
812 	int i;
813 	struct rte_ether_addr read_mac_addr;
814 	struct rte_ether_addr *mac_addr;
815 
816 	uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
817 
818 	mac_addr = (struct rte_ether_addr *)explicit_bonded_mac;
819 
820 	/* Invalid port ID */
821 	TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
822 			"Expected call to failed as invalid port specified.");
823 
824 	/* Non bonded device */
825 	TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
826 			test_params->slave_port_ids[0],	mac_addr),
827 			"Expected call to failed as invalid port specified.");
828 
829 	/* NULL MAC address */
830 	TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
831 			test_params->bonded_port_id, NULL),
832 			"Expected call to failed as NULL MAC specified");
833 
834 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
835 			test_params->bonded_port_id, mac_addr),
836 			"Failed to set MAC address on bonded port (%d)",
837 			test_params->bonded_port_id);
838 
839 	/* Add 4 slaves to bonded device */
840 	for (i = test_params->bonded_slave_count; i < 4; i++) {
841 		TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
842 				"Failed to add slave to bonded device.\n");
843 	}
844 
845 	/* Check bonded MAC */
846 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
847 	TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
848 			"bonded port mac address not set to that of primary port");
849 
850 	/* Check other slaves MACs */
851 	for (i = 0; i < 4; i++) {
852 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
853 		TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
854 				sizeof(read_mac_addr)),
855 				"slave port mac address not set to that of primary port");
856 	}
857 
858 	/* test resetting mac address on bonded device */
859 	TEST_ASSERT_SUCCESS(
860 			rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
861 			"Failed to reset MAC address on bonded port (%d)",
862 			test_params->bonded_port_id);
863 
864 	TEST_ASSERT_FAIL(
865 			rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
866 			"Reset MAC address on bonded port (%d) unexpectedly",
867 			test_params->slave_port_ids[1]);
868 
869 	/* test resetting mac address on bonded device with no slaves */
870 	TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
871 			"Failed to remove slaves and stop bonded device");
872 
873 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
874 			"Failed to reset MAC address on bonded port (%d)",
875 				test_params->bonded_port_id);
876 
877 	return 0;
878 }
879 
880 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
881 
882 static int
883 test_set_bonded_port_initialization_mac_assignment(void)
884 {
885 	int i, slave_count;
886 
887 	uint16_t slaves[RTE_MAX_ETHPORTS];
888 	static int bonded_port_id = -1;
889 	static int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
890 
891 	struct rte_ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
892 
893 	/* Initialize default values for MAC addresses */
894 	memcpy(&slave_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
895 	memcpy(&bonded_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
896 
897 	/*
898 	 * 1. a - Create / configure  bonded / slave ethdevs
899 	 */
900 	if (bonded_port_id == -1) {
901 		bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
902 				BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
903 		TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
904 
905 		TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
906 					"Failed to configure bonded ethdev");
907 	}
908 
909 	if (!mac_slaves_initialized) {
910 		for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
911 			char pmd_name[RTE_ETH_NAME_MAX_LEN];
912 
913 			slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] =
914 				i + 100;
915 
916 			snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN,
917 				"eth_slave_%d", i);
918 
919 			slave_port_ids[i] = virtual_ethdev_create(pmd_name,
920 					&slave_mac_addr, rte_socket_id(), 1);
921 
922 			TEST_ASSERT(slave_port_ids[i] >= 0,
923 					"Failed to create slave ethdev %s",
924 					pmd_name);
925 
926 			TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
927 					"Failed to configure virtual ethdev %s",
928 					pmd_name);
929 		}
930 		mac_slaves_initialized = 1;
931 	}
932 
933 
934 	/*
935 	 * 2. Add slave ethdevs to bonded device
936 	 */
937 	for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
938 		TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
939 				slave_port_ids[i]),
940 				"Failed to add slave (%d) to bonded port (%d).",
941 				slave_port_ids[i], bonded_port_id);
942 	}
943 
944 	slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
945 			RTE_MAX_ETHPORTS);
946 	TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
947 			"Number of slaves (%d) is not as expected (%d)",
948 			slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
949 
950 
951 	/*
952 	 * 3. Set explicit MAC address on bonded ethdev
953 	 */
954 	bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-2] = 0xFF;
955 	bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0xAA;
956 
957 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
958 			bonded_port_id, &bonded_mac_addr),
959 			"Failed to set MAC address on bonded port (%d)",
960 			bonded_port_id);
961 
962 
963 	/* 4. a - Start bonded ethdev
964 	 *    b - Enable slave devices
965 	 *    c - Verify bonded/slaves ethdev MAC addresses
966 	 */
967 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
968 			"Failed to start bonded pmd eth device %d.",
969 			bonded_port_id);
970 
971 	for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
972 		virtual_ethdev_simulate_link_status_interrupt(
973 				slave_port_ids[i], 1);
974 	}
975 
976 	rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
977 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
978 			sizeof(read_mac_addr)),
979 			"bonded port mac address not as expected");
980 
981 	rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
982 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
983 			sizeof(read_mac_addr)),
984 			"slave port 0 mac address not as expected");
985 
986 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
987 	rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
988 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
989 			sizeof(read_mac_addr)),
990 			"slave port 1 mac address not as expected");
991 
992 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
993 	rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
994 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
995 			sizeof(read_mac_addr)),
996 			"slave port 2 mac address not as expected");
997 
998 
999 	/* 7. a - Change primary port
1000 	 *    b - Stop / Start bonded port
1001 	 *    d - Verify slave ethdev MAC addresses
1002 	 */
1003 	TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1004 			slave_port_ids[2]),
1005 			"failed to set primary port on bonded device.");
1006 
1007 	rte_eth_dev_stop(bonded_port_id);
1008 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1009 				"Failed to start bonded pmd eth device %d.",
1010 				bonded_port_id);
1011 
1012 	rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1013 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1014 			sizeof(read_mac_addr)),
1015 			"bonded port mac address not as expected");
1016 
1017 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1018 	rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1019 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1020 			sizeof(read_mac_addr)),
1021 			"slave port 0 mac address not as expected");
1022 
1023 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1024 	rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1025 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1026 			sizeof(read_mac_addr)),
1027 			"slave port 1 mac address not as expected");
1028 
1029 	rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1030 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1031 			sizeof(read_mac_addr)),
1032 			"slave port 2 mac address not as expected");
1033 
1034 	/* 6. a - Stop bonded ethdev
1035 	 *    b - remove slave ethdevs
1036 	 *    c - Verify slave ethdevs MACs are restored
1037 	 */
1038 	rte_eth_dev_stop(bonded_port_id);
1039 
1040 	for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1041 		TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1042 				slave_port_ids[i]),
1043 				"Failed to remove slave %d from bonded port (%d).",
1044 				slave_port_ids[i], bonded_port_id);
1045 	}
1046 
1047 	slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1048 			RTE_MAX_ETHPORTS);
1049 
1050 	TEST_ASSERT_EQUAL(slave_count, 0,
1051 			"Number of slaves (%d) is great than expected (%d).",
1052 			slave_count, 0);
1053 
1054 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1055 	rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1056 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1057 			sizeof(read_mac_addr)),
1058 			"slave port 0 mac address not as expected");
1059 
1060 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1061 	rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1062 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1063 			sizeof(read_mac_addr)),
1064 			"slave port 1 mac address not as expected");
1065 
1066 	slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1067 	rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1068 	TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1069 			sizeof(read_mac_addr)),
1070 			"slave port 2 mac address not as expected");
1071 
1072 	return 0;
1073 }
1074 
1075 
1076 static int
1077 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1078 		uint16_t number_of_slaves, uint8_t enable_slave)
1079 {
1080 	/* Configure bonded device */
1081 	TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1082 			bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1083 			"with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1084 			number_of_slaves);
1085 
1086 	/* Add slaves to bonded device */
1087 	while (number_of_slaves > test_params->bonded_slave_count)
1088 		TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1089 				"Failed to add slave (%d to  bonding port (%d).",
1090 				test_params->bonded_slave_count - 1,
1091 				test_params->bonded_port_id);
1092 
1093 	/* Set link bonding mode  */
1094 	TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1095 			bonding_mode),
1096 			"Failed to set link bonding mode on port (%d) to (%d).",
1097 			test_params->bonded_port_id, bonding_mode);
1098 
1099 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1100 		"Failed to start bonded pmd eth device %d.",
1101 		test_params->bonded_port_id);
1102 
1103 	if (enable_slave)
1104 		enable_bonded_slaves();
1105 
1106 	return 0;
1107 }
1108 
1109 static int
1110 test_adding_slave_after_bonded_device_started(void)
1111 {
1112 	int i;
1113 
1114 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1115 			BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1116 			"Failed to add slaves to bonded device");
1117 
1118 	/* Enabled slave devices */
1119 	for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1120 		virtual_ethdev_simulate_link_status_interrupt(
1121 				test_params->slave_port_ids[i], 1);
1122 	}
1123 
1124 	TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1125 			test_params->slave_port_ids[test_params->bonded_slave_count]),
1126 			"Failed to add slave to bonded port.\n");
1127 
1128 	rte_eth_stats_reset(
1129 			test_params->slave_port_ids[test_params->bonded_slave_count]);
1130 
1131 	test_params->bonded_slave_count++;
1132 
1133 	return remove_slaves_and_stop_bonded_device();
1134 }
1135 
1136 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT	4
1137 #define TEST_LSC_WAIT_TIMEOUT_MS	500
1138 
1139 int test_lsc_interrupt_count;
1140 
1141 
1142 static int
1143 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1144 		enum rte_eth_event_type type  __rte_unused,
1145 		void *param __rte_unused,
1146 		void *ret_param __rte_unused)
1147 {
1148 	pthread_mutex_lock(&mutex);
1149 	test_lsc_interrupt_count++;
1150 
1151 	pthread_cond_signal(&cvar);
1152 	pthread_mutex_unlock(&mutex);
1153 
1154 	return 0;
1155 }
1156 
1157 static inline int
1158 lsc_timeout(int wait_us)
1159 {
1160 	int retval = 0;
1161 
1162 	struct timespec ts;
1163 	struct timeval tp;
1164 
1165 	gettimeofday(&tp, NULL);
1166 
1167 	/* Convert from timeval to timespec */
1168 	ts.tv_sec = tp.tv_sec;
1169 	ts.tv_nsec = tp.tv_usec * 1000;
1170 	ts.tv_nsec += wait_us * 1000;
1171 
1172 	pthread_mutex_lock(&mutex);
1173 	if (test_lsc_interrupt_count < 1)
1174 		retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1175 
1176 	pthread_mutex_unlock(&mutex);
1177 
1178 	if (retval == 0 && test_lsc_interrupt_count < 1)
1179 		return -1;
1180 
1181 	return retval;
1182 }
1183 
1184 static int
1185 test_status_interrupt(void)
1186 {
1187 	int slave_count;
1188 	uint16_t slaves[RTE_MAX_ETHPORTS];
1189 
1190 	/* initialized bonding device with T slaves */
1191 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1192 			BONDING_MODE_ROUND_ROBIN, 1,
1193 			TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1194 			"Failed to initialise bonded device");
1195 
1196 	test_lsc_interrupt_count = 0;
1197 
1198 	/* register link status change interrupt callback */
1199 	rte_eth_dev_callback_register(test_params->bonded_port_id,
1200 			RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1201 			&test_params->bonded_port_id);
1202 
1203 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1204 			slaves, RTE_MAX_ETHPORTS);
1205 
1206 	TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1207 			"Number of active slaves (%d) is not as expected (%d)",
1208 			slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1209 
1210 	/* Bring all 4 slaves link status to down and test that we have received a
1211 	 * lsc interrupts */
1212 	virtual_ethdev_simulate_link_status_interrupt(
1213 			test_params->slave_port_ids[0], 0);
1214 	virtual_ethdev_simulate_link_status_interrupt(
1215 			test_params->slave_port_ids[1], 0);
1216 	virtual_ethdev_simulate_link_status_interrupt(
1217 			test_params->slave_port_ids[2], 0);
1218 
1219 	TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1220 			"Received a link status change interrupt unexpectedly");
1221 
1222 	virtual_ethdev_simulate_link_status_interrupt(
1223 			test_params->slave_port_ids[3], 0);
1224 
1225 	TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1226 			"timed out waiting for interrupt");
1227 
1228 	TEST_ASSERT(test_lsc_interrupt_count > 0,
1229 			"Did not receive link status change interrupt");
1230 
1231 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1232 			slaves, RTE_MAX_ETHPORTS);
1233 
1234 	TEST_ASSERT_EQUAL(slave_count, 0,
1235 			"Number of active slaves (%d) is not as expected (%d)",
1236 			slave_count, 0);
1237 
1238 	/* bring one slave port up so link status will change */
1239 	test_lsc_interrupt_count = 0;
1240 
1241 	virtual_ethdev_simulate_link_status_interrupt(
1242 			test_params->slave_port_ids[0], 1);
1243 
1244 	TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1245 			"timed out waiting for interrupt");
1246 
1247 	/* test that we have received another lsc interrupt */
1248 	TEST_ASSERT(test_lsc_interrupt_count > 0,
1249 			"Did not receive link status change interrupt");
1250 
1251 	/* Verify that calling the same slave lsc interrupt doesn't cause another
1252 	 * lsc interrupt from bonded device */
1253 	test_lsc_interrupt_count = 0;
1254 
1255 	virtual_ethdev_simulate_link_status_interrupt(
1256 			test_params->slave_port_ids[0], 1);
1257 
1258 	TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1259 			"received unexpected interrupt");
1260 
1261 	TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1262 			"Did not receive link status change interrupt");
1263 
1264 
1265 	/* unregister lsc callback before exiting */
1266 	rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1267 				RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1268 				&test_params->bonded_port_id);
1269 
1270 	/* Clean up and remove slaves from bonded device */
1271 	return remove_slaves_and_stop_bonded_device();
1272 }
1273 
1274 static int
1275 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1276 		uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1277 		uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1278 {
1279 	uint16_t pktlen, generated_burst_size, ether_type;
1280 	void *ip_hdr;
1281 
1282 	if (ipv4)
1283 		ether_type = RTE_ETHER_TYPE_IPV4;
1284 	else
1285 		ether_type = RTE_ETHER_TYPE_IPV6;
1286 
1287 	if (toggle_dst_mac)
1288 		initialize_eth_header(test_params->pkt_eth_hdr,
1289 				(struct rte_ether_addr *)src_mac,
1290 				(struct rte_ether_addr *)dst_mac_1,
1291 				ether_type, vlan, vlan_id);
1292 	else
1293 		initialize_eth_header(test_params->pkt_eth_hdr,
1294 				(struct rte_ether_addr *)src_mac,
1295 				(struct rte_ether_addr *)dst_mac_0,
1296 				ether_type, vlan, vlan_id);
1297 
1298 
1299 	if (toggle_udp_port)
1300 		pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1301 				dst_port_1, 64);
1302 	else
1303 		pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1304 				dst_port_0, 64);
1305 
1306 	if (ipv4) {
1307 		if (toggle_ip_addr)
1308 			pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1309 					dst_addr_1, pktlen);
1310 		else
1311 			pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1312 					dst_addr_0, pktlen);
1313 
1314 		ip_hdr = test_params->pkt_ipv4_hdr;
1315 	} else {
1316 		if (toggle_ip_addr)
1317 			pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1318 					(uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1319 					pktlen);
1320 		else
1321 			pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1322 					(uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1323 					pktlen);
1324 
1325 		ip_hdr = test_params->pkt_ipv6_hdr;
1326 	}
1327 
1328 	/* Generate burst of packets to transmit */
1329 	generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1330 			pkts_burst,	test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1331 			test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1332 			1);
1333 	TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1334 			"Failed to generate packet burst");
1335 
1336 	return generated_burst_size;
1337 }
1338 
1339 /** Round Robin Mode Tests */
1340 
1341 static int
1342 test_roundrobin_tx_burst(void)
1343 {
1344 	int i, burst_size;
1345 	struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1346 	struct rte_eth_stats port_stats;
1347 
1348 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1349 			BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1350 			"Failed to initialise bonded device");
1351 
1352 	burst_size = 20 * test_params->bonded_slave_count;
1353 
1354 	TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1355 			"Burst size specified is greater than supported.");
1356 
1357 	/* Generate test bursts of packets to transmit */
1358 	TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1359 			burst_size, "failed to generate test burst");
1360 
1361 	/* Send burst on bonded port */
1362 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1363 			test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1364 			"tx burst failed");
1365 
1366 	/* Verify bonded port tx stats */
1367 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1368 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1369 			"Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1370 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1371 			burst_size);
1372 
1373 	/* Verify slave ports tx stats */
1374 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1375 		rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1376 		TEST_ASSERT_EQUAL(port_stats.opackets,
1377 				(uint64_t)burst_size / test_params->bonded_slave_count,
1378 				"Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1379 				test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1380 				burst_size / test_params->bonded_slave_count);
1381 	}
1382 
1383 	/* Put all slaves down and try and transmit */
1384 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1385 		virtual_ethdev_simulate_link_status_interrupt(
1386 				test_params->slave_port_ids[i], 0);
1387 	}
1388 
1389 	/* Send burst on bonded port */
1390 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1391 			pkt_burst, burst_size), 0,
1392 			"tx burst return unexpected value");
1393 
1394 	/* Clean up and remove slaves from bonded device */
1395 	return remove_slaves_and_stop_bonded_device();
1396 }
1397 
1398 static int
1399 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1400 {
1401 	int i, refcnt;
1402 
1403 	for (i = 0; i < nb_mbufs; i++) {
1404 		refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1405 		TEST_ASSERT_EQUAL(refcnt, val,
1406 			"mbuf ref count (%d)is not the expected value (%d)",
1407 			refcnt, val);
1408 	}
1409 	return 0;
1410 }
1411 
1412 static void
1413 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1414 {
1415 	int i;
1416 
1417 	for (i = 0; i < nb_mbufs; i++)
1418 		rte_pktmbuf_free(mbufs[i]);
1419 }
1420 
1421 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT		(2)
1422 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE		(64)
1423 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT		(22)
1424 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX	(1)
1425 
1426 static int
1427 test_roundrobin_tx_burst_slave_tx_fail(void)
1428 {
1429 	struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1430 	struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1431 
1432 	struct rte_eth_stats port_stats;
1433 
1434 	int i, first_fail_idx, tx_count;
1435 
1436 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1437 			BONDING_MODE_ROUND_ROBIN, 0,
1438 			TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1439 			"Failed to initialise bonded device");
1440 
1441 	/* Generate test bursts of packets to transmit */
1442 	TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1443 			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1444 			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1445 			"Failed to generate test packet burst");
1446 
1447 	/* Copy references to packets which we expect not to be transmitted */
1448 	first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1449 			(TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1450 			TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1451 			TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1452 
1453 	for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1454 		expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1455 				(i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1456 	}
1457 
1458 	/* Set virtual slave to only fail transmission of
1459 	 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1460 	virtual_ethdev_tx_burst_fn_set_success(
1461 			test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1462 			0);
1463 
1464 	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1465 			test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1466 			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1467 
1468 	tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1469 			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1470 
1471 	TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1472 			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1473 			"Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1474 			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1475 			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1476 
1477 	/* Verify that failed packet are expected failed packets */
1478 	for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1479 		TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1480 				"expected mbuf (%d) pointer %p not expected pointer %p",
1481 				i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1482 	}
1483 
1484 	/* Verify bonded port tx stats */
1485 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1486 
1487 	TEST_ASSERT_EQUAL(port_stats.opackets,
1488 			(uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1489 			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1490 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
1491 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1492 			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1493 			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1494 
1495 	/* Verify slave ports tx stats */
1496 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1497 		int slave_expected_tx_count;
1498 
1499 		rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1500 
1501 		slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1502 				test_params->bonded_slave_count;
1503 
1504 		if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1505 			slave_expected_tx_count = slave_expected_tx_count -
1506 					TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1507 
1508 		TEST_ASSERT_EQUAL(port_stats.opackets,
1509 				(uint64_t)slave_expected_tx_count,
1510 				"Slave Port (%d) opackets value (%u) not as expected (%d)",
1511 				test_params->slave_port_ids[i],
1512 				(unsigned int)port_stats.opackets, slave_expected_tx_count);
1513 	}
1514 
1515 	/* Verify that all mbufs have a ref value of zero */
1516 	TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1517 			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1518 			"mbufs refcnts not as expected");
1519 	free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1520 
1521 	/* Clean up and remove slaves from bonded device */
1522 	return remove_slaves_and_stop_bonded_device();
1523 }
1524 
1525 static int
1526 test_roundrobin_rx_burst_on_single_slave(void)
1527 {
1528 	struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1529 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1530 
1531 	struct rte_eth_stats port_stats;
1532 
1533 	int i, j, burst_size = 25;
1534 
1535 	/* Initialize bonded device with 4 slaves in round robin mode */
1536 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1537 			BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1538 			"Failed to initialize bonded device with slaves");
1539 
1540 	/* Generate test bursts of packets to transmit */
1541 	TEST_ASSERT_EQUAL(generate_test_burst(
1542 			gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1543 			"burst generation failed");
1544 
1545 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1546 		/* Add rx data to slave */
1547 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1548 				&gen_pkt_burst[0], burst_size);
1549 
1550 		/* Call rx burst on bonded device */
1551 		/* Send burst on bonded port */
1552 		TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1553 				test_params->bonded_port_id, 0, rx_pkt_burst,
1554 				MAX_PKT_BURST), burst_size,
1555 				"round-robin rx burst failed");
1556 
1557 		/* Verify bonded device rx count */
1558 		rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1559 		TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1560 				"Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1561 				test_params->bonded_port_id,
1562 				(unsigned int)port_stats.ipackets, burst_size);
1563 
1564 
1565 
1566 		/* Verify bonded slave devices rx count */
1567 		/* Verify slave ports tx stats */
1568 		for (j = 0; j < test_params->bonded_slave_count; j++) {
1569 			rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1570 
1571 			if (i == j) {
1572 				TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1573 						"Slave Port (%d) ipackets value (%u) not as expected"
1574 						" (%d)", test_params->slave_port_ids[i],
1575 						(unsigned int)port_stats.ipackets, burst_size);
1576 			} else {
1577 				TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1578 						"Slave Port (%d) ipackets value (%u) not as expected"
1579 						" (%d)", test_params->slave_port_ids[i],
1580 						(unsigned int)port_stats.ipackets, 0);
1581 			}
1582 
1583 			/* Reset bonded slaves stats */
1584 			rte_eth_stats_reset(test_params->slave_port_ids[j]);
1585 		}
1586 		/* reset bonded device stats */
1587 		rte_eth_stats_reset(test_params->bonded_port_id);
1588 	}
1589 
1590 	/* free mbufs */
1591 	for (i = 0; i < MAX_PKT_BURST; i++) {
1592 		if (rx_pkt_burst[i] != NULL)
1593 			rte_pktmbuf_free(rx_pkt_burst[i]);
1594 	}
1595 
1596 
1597 	/* Clean up and remove slaves from bonded device */
1598 	return remove_slaves_and_stop_bonded_device();
1599 }
1600 
1601 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1602 
1603 static int
1604 test_roundrobin_rx_burst_on_multiple_slaves(void)
1605 {
1606 	struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1607 
1608 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1609 	struct rte_eth_stats port_stats;
1610 
1611 	int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1612 	int i, nb_rx;
1613 
1614 	/* Initialize bonded device with 4 slaves in round robin mode */
1615 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1616 			BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1617 			"Failed to initialize bonded device with slaves");
1618 
1619 	/* Generate test bursts of packets to transmit */
1620 	for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1621 		TEST_ASSERT_EQUAL(generate_test_burst(
1622 				&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1623 				burst_size[i], "burst generation failed");
1624 	}
1625 
1626 	/* Add rx data to slaves */
1627 	for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1628 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1629 				&gen_pkt_burst[i][0], burst_size[i]);
1630 	}
1631 
1632 	/* Call rx burst on bonded device */
1633 	/* Send burst on bonded port */
1634 	nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1635 			MAX_PKT_BURST);
1636 	TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1637 			"round-robin rx burst failed (%d != %d)\n", nb_rx,
1638 			burst_size[0] + burst_size[1] + burst_size[2]);
1639 
1640 	/* Verify bonded device rx count */
1641 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1642 	TEST_ASSERT_EQUAL(port_stats.ipackets,
1643 			(uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1644 			"Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1645 			test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1646 			burst_size[0] + burst_size[1] + burst_size[2]);
1647 
1648 	/* Verify bonded slave devices rx counts */
1649 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1650 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1651 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
1652 			test_params->slave_port_ids[0],
1653 			(unsigned int)port_stats.ipackets, burst_size[0]);
1654 
1655 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1656 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1657 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
1658 			test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1659 			burst_size[1]);
1660 
1661 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1662 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1663 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
1664 				test_params->slave_port_ids[2],
1665 				(unsigned int)port_stats.ipackets, burst_size[2]);
1666 
1667 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1668 	TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1669 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
1670 			test_params->slave_port_ids[3],
1671 			(unsigned int)port_stats.ipackets, 0);
1672 
1673 	/* free mbufs */
1674 	for (i = 0; i < MAX_PKT_BURST; i++) {
1675 		if (rx_pkt_burst[i] != NULL)
1676 			rte_pktmbuf_free(rx_pkt_burst[i]);
1677 	}
1678 
1679 	/* Clean up and remove slaves from bonded device */
1680 	return remove_slaves_and_stop_bonded_device();
1681 }
1682 
1683 static int
1684 test_roundrobin_verify_mac_assignment(void)
1685 {
1686 	struct rte_ether_addr read_mac_addr;
1687 	struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_2;
1688 
1689 	int i;
1690 
1691 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1692 	rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1693 
1694 	/* Initialize bonded device with 4 slaves in round robin mode */
1695 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1696 				BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1697 				"Failed to initialize bonded device with slaves");
1698 
1699 	/* Verify that all MACs are the same as first slave added to bonded dev */
1700 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1701 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1702 		TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1703 				sizeof(read_mac_addr)),
1704 				"slave port (%d) mac address not set to that of primary port",
1705 				test_params->slave_port_ids[i]);
1706 	}
1707 
1708 	/* change primary and verify that MAC addresses haven't changed */
1709 	TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1710 			test_params->slave_port_ids[2]),
1711 			"Failed to set bonded port (%d) primary port to (%d)",
1712 			test_params->bonded_port_id, test_params->slave_port_ids[i]);
1713 
1714 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1715 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1716 		TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1717 				sizeof(read_mac_addr)),
1718 				"slave port (%d) mac address has changed to that of primary"
1719 				" port without stop/start toggle of bonded device",
1720 				test_params->slave_port_ids[i]);
1721 	}
1722 
1723 	/* stop / start bonded device and verify that primary MAC address is
1724 	 * propagate to bonded device and slaves */
1725 	rte_eth_dev_stop(test_params->bonded_port_id);
1726 
1727 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1728 			"Failed to start bonded device");
1729 
1730 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1731 	TEST_ASSERT_SUCCESS(
1732 			memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1733 			"bonded port (%d) mac address not set to that of new primary port",
1734 			test_params->slave_port_ids[i]);
1735 
1736 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1737 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1738 		TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1739 				sizeof(read_mac_addr)),
1740 				"slave port (%d) mac address not set to that of new primary"
1741 				" port", test_params->slave_port_ids[i]);
1742 	}
1743 
1744 	/* Set explicit MAC address */
1745 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1746 			test_params->bonded_port_id,
1747 			(struct rte_ether_addr *)bonded_mac),
1748 			"Failed to set MAC");
1749 
1750 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1751 	TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1752 			sizeof(read_mac_addr)),
1753 			"bonded port (%d) mac address not set to that of new primary port",
1754 				test_params->slave_port_ids[i]);
1755 
1756 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1757 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1758 		TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1759 				sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1760 				" that of new primary port\n", test_params->slave_port_ids[i]);
1761 	}
1762 
1763 	/* Clean up and remove slaves from bonded device */
1764 	return remove_slaves_and_stop_bonded_device();
1765 }
1766 
1767 static int
1768 test_roundrobin_verify_promiscuous_enable_disable(void)
1769 {
1770 	int i, promiscuous_en;
1771 	int ret;
1772 
1773 	/* Initialize bonded device with 4 slaves in round robin mode */
1774 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1775 			BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1776 			"Failed to initialize bonded device with slaves");
1777 
1778 	ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
1779 	TEST_ASSERT_SUCCESS(ret,
1780 		"Failed to enable promiscuous mode for port %d: %s",
1781 		test_params->bonded_port_id, rte_strerror(-ret));
1782 
1783 	promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1784 	TEST_ASSERT_EQUAL(promiscuous_en, 1,
1785 			"Port (%d) promiscuous mode not enabled",
1786 			test_params->bonded_port_id);
1787 
1788 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1789 		promiscuous_en = rte_eth_promiscuous_get(
1790 				test_params->slave_port_ids[i]);
1791 		TEST_ASSERT_EQUAL(promiscuous_en, 1,
1792 				"slave port (%d) promiscuous mode not enabled",
1793 				test_params->slave_port_ids[i]);
1794 	}
1795 
1796 	ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
1797 	TEST_ASSERT_SUCCESS(ret,
1798 		"Failed to disable promiscuous mode for port %d: %s",
1799 		test_params->bonded_port_id, rte_strerror(-ret));
1800 
1801 	promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1802 	TEST_ASSERT_EQUAL(promiscuous_en, 0,
1803 			"Port (%d) promiscuous mode not disabled\n",
1804 			test_params->bonded_port_id);
1805 
1806 	for (i = 0; i < test_params->bonded_slave_count; i++) {
1807 		promiscuous_en = rte_eth_promiscuous_get(
1808 				test_params->slave_port_ids[i]);
1809 		TEST_ASSERT_EQUAL(promiscuous_en, 0,
1810 				"Port (%d) promiscuous mode not disabled\n",
1811 				test_params->slave_port_ids[i]);
1812 	}
1813 
1814 	/* Clean up and remove slaves from bonded device */
1815 	return remove_slaves_and_stop_bonded_device();
1816 }
1817 
1818 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1819 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1820 
1821 static int
1822 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1823 {
1824 	struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1825 	struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1826 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1827 
1828 	struct rte_eth_stats port_stats;
1829 	uint16_t slaves[RTE_MAX_ETHPORTS];
1830 
1831 	int i, burst_size, slave_count;
1832 
1833 	/* NULL all pointers in array to simplify cleanup */
1834 	memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1835 
1836 	/* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1837 	 * in round robin mode */
1838 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1839 			BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1840 			"Failed to initialize bonded device with slaves");
1841 
1842 	/* Verify Current Slaves Count /Active Slave Count is */
1843 	slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1844 			RTE_MAX_ETHPORTS);
1845 	TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1846 			"Number of slaves (%d) is not as expected (%d).",
1847 			slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1848 
1849 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1850 			slaves, RTE_MAX_ETHPORTS);
1851 	TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1852 			"Number of active slaves (%d) is not as expected (%d).",
1853 			slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1854 
1855 	/* Set 2 slaves eth_devs link status to down */
1856 	virtual_ethdev_simulate_link_status_interrupt(
1857 			test_params->slave_port_ids[1], 0);
1858 	virtual_ethdev_simulate_link_status_interrupt(
1859 			test_params->slave_port_ids[3], 0);
1860 
1861 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1862 			slaves, RTE_MAX_ETHPORTS);
1863 	TEST_ASSERT_EQUAL(slave_count,
1864 			TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1865 			"Number of active slaves (%d) is not as expected (%d).\n",
1866 			slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1867 
1868 	burst_size = 20;
1869 
1870 	/* Verify that pkts are not sent on slaves with link status down:
1871 	 *
1872 	 * 1. Generate test burst of traffic
1873 	 * 2. Transmit burst on bonded eth_dev
1874 	 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1875 	 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1876 	 */
1877 	TEST_ASSERT_EQUAL(
1878 			generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1879 			burst_size, "generate_test_burst failed");
1880 
1881 	rte_eth_stats_reset(test_params->bonded_port_id);
1882 
1883 
1884 	TEST_ASSERT_EQUAL(
1885 			rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1886 			burst_size), burst_size, "rte_eth_tx_burst failed");
1887 
1888 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1889 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1890 			"Port (%d) opackets stats (%d) not expected (%d) value",
1891 			test_params->bonded_port_id, (int)port_stats.opackets,
1892 			burst_size);
1893 
1894 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1895 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1896 			"Port (%d) opackets stats (%d) not expected (%d) value",
1897 			test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1898 
1899 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1900 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1901 			"Port (%d) opackets stats (%d) not expected (%d) value",
1902 			test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1903 
1904 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1905 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1906 			"Port (%d) opackets stats (%d) not expected (%d) value",
1907 			test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1908 
1909 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1910 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1911 			"Port (%d) opackets stats (%d) not expected (%d) value",
1912 			test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1913 
1914 	/* Verify that pkts are not sent on slaves with link status down:
1915 	 *
1916 	 * 1. Generate test bursts of traffic
1917 	 * 2. Add bursts on to virtual eth_devs
1918 	 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1919 	 *    TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1920 	 * 4. Verify stats for bonded eth_dev
1921 	 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1922 	 */
1923 	for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1924 		TEST_ASSERT_EQUAL(generate_test_burst(
1925 				&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1926 				burst_size, "failed to generate packet burst");
1927 
1928 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1929 				&gen_pkt_burst[i][0], burst_size);
1930 	}
1931 
1932 	TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1933 			test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1934 			burst_size + burst_size,
1935 			"rte_eth_rx_burst failed");
1936 
1937 	/* Verify bonded device rx count */
1938 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1939 	TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1940 			"(%d) port_stats.ipackets not as expected\n",
1941 			test_params->bonded_port_id);
1942 
1943 	/* free mbufs */
1944 	for (i = 0; i < MAX_PKT_BURST; i++) {
1945 		if (rx_pkt_burst[i] != NULL)
1946 			rte_pktmbuf_free(rx_pkt_burst[i]);
1947 	}
1948 
1949 	/* Clean up and remove slaves from bonded device */
1950 	return remove_slaves_and_stop_bonded_device();
1951 }
1952 
1953 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1954 
1955 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1956 
1957 
1958 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1959 
1960 static int
1961 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1962 {
1963 	struct rte_ether_addr *mac_addr =
1964 		(struct rte_ether_addr *)polling_slave_mac;
1965 	char slave_name[RTE_ETH_NAME_MAX_LEN];
1966 
1967 	int i;
1968 
1969 	for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1970 		/* Generate slave name / MAC address */
1971 		snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1972 		mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
1973 
1974 		/* Create slave devices with no ISR Support */
1975 		if (polling_test_slaves[i] == -1) {
1976 			polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
1977 					rte_socket_id(), 0);
1978 			TEST_ASSERT(polling_test_slaves[i] >= 0,
1979 					"Failed to create virtual virtual ethdev %s\n", slave_name);
1980 
1981 			/* Configure slave */
1982 			TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
1983 					"Failed to configure virtual ethdev %s(%d)", slave_name,
1984 					polling_test_slaves[i]);
1985 		}
1986 
1987 		/* Add slave to bonded device */
1988 		TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1989 				polling_test_slaves[i]),
1990 				"Failed to add slave %s(%d) to bonded device %d",
1991 				slave_name, polling_test_slaves[i],
1992 				test_params->bonded_port_id);
1993 	}
1994 
1995 	/* Initialize bonded device */
1996 	TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
1997 			"Failed to configure bonded device %d",
1998 			test_params->bonded_port_id);
1999 
2000 
2001 	/* Register link status change interrupt callback */
2002 	rte_eth_dev_callback_register(test_params->bonded_port_id,
2003 			RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2004 			&test_params->bonded_port_id);
2005 
2006 	/* link status change callback for first slave link up */
2007 	test_lsc_interrupt_count = 0;
2008 
2009 	virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2010 
2011 	TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2012 
2013 
2014 	/* no link status change callback for second slave link up */
2015 	test_lsc_interrupt_count = 0;
2016 
2017 	virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2018 
2019 	TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2020 
2021 	/* link status change callback for both slave links down */
2022 	test_lsc_interrupt_count = 0;
2023 
2024 	virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2025 	virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2026 
2027 	TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2028 
2029 	/* Un-Register link status change interrupt callback */
2030 	rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2031 			RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2032 			&test_params->bonded_port_id);
2033 
2034 
2035 	/* Clean up and remove slaves from bonded device */
2036 	for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2037 
2038 		TEST_ASSERT_SUCCESS(
2039 				rte_eth_bond_slave_remove(test_params->bonded_port_id,
2040 						polling_test_slaves[i]),
2041 				"Failed to remove slave %d from bonded port (%d)",
2042 				polling_test_slaves[i], test_params->bonded_port_id);
2043 	}
2044 
2045 	return remove_slaves_and_stop_bonded_device();
2046 }
2047 
2048 
2049 /** Active Backup Mode Tests */
2050 
2051 static int
2052 test_activebackup_tx_burst(void)
2053 {
2054 	int i, pktlen, primary_port, burst_size;
2055 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2056 	struct rte_eth_stats port_stats;
2057 
2058 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2059 			BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2060 			"Failed to initialize bonded device with slaves");
2061 
2062 	initialize_eth_header(test_params->pkt_eth_hdr,
2063 			(struct rte_ether_addr *)src_mac,
2064 			(struct rte_ether_addr *)dst_mac_0,
2065 			RTE_ETHER_TYPE_IPV4,  0, 0);
2066 	pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2067 			dst_port_0, 16);
2068 	pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2069 			dst_addr_0, pktlen);
2070 
2071 	burst_size = 20 * test_params->bonded_slave_count;
2072 
2073 	TEST_ASSERT(burst_size < MAX_PKT_BURST,
2074 			"Burst size specified is greater than supported.");
2075 
2076 	/* Generate a burst of packets to transmit */
2077 	TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2078 			test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2079 			test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2080 			burst_size,	"failed to generate burst correctly");
2081 
2082 	/* Send burst on bonded port */
2083 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2084 			burst_size),  burst_size, "tx burst failed");
2085 
2086 	/* Verify bonded port tx stats */
2087 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2088 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2089 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
2090 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2091 			burst_size);
2092 
2093 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2094 
2095 	/* Verify slave ports tx stats */
2096 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2097 		rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2098 		if (test_params->slave_port_ids[i] == primary_port) {
2099 			TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2100 					"Slave Port (%d) opackets value (%u) not as expected (%d)",
2101 					test_params->bonded_port_id,
2102 					(unsigned int)port_stats.opackets,
2103 					burst_size / test_params->bonded_slave_count);
2104 		} else {
2105 			TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2106 					"Slave Port (%d) opackets value (%u) not as expected (%d)",
2107 					test_params->bonded_port_id,
2108 					(unsigned int)port_stats.opackets, 0);
2109 		}
2110 	}
2111 
2112 	/* Put all slaves down and try and transmit */
2113 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2114 		virtual_ethdev_simulate_link_status_interrupt(
2115 				test_params->slave_port_ids[i], 0);
2116 	}
2117 
2118 	/* Send burst on bonded port */
2119 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2120 			pkts_burst, burst_size), 0, "Sending empty burst failed");
2121 
2122 	/* Clean up and remove slaves from bonded device */
2123 	return remove_slaves_and_stop_bonded_device();
2124 }
2125 
2126 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2127 
2128 static int
2129 test_activebackup_rx_burst(void)
2130 {
2131 	struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2132 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2133 
2134 	struct rte_eth_stats port_stats;
2135 
2136 	int primary_port;
2137 
2138 	int i, j, burst_size = 17;
2139 
2140 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2141 			BONDING_MODE_ACTIVE_BACKUP, 0,
2142 			TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2143 			"Failed to initialize bonded device with slaves");
2144 
2145 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2146 	TEST_ASSERT(primary_port >= 0,
2147 			"failed to get primary slave for bonded port (%d)",
2148 			test_params->bonded_port_id);
2149 
2150 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2151 		/* Generate test bursts of packets to transmit */
2152 		TEST_ASSERT_EQUAL(generate_test_burst(
2153 				&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2154 				burst_size, "burst generation failed");
2155 
2156 		/* Add rx data to slave */
2157 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2158 				&gen_pkt_burst[0], burst_size);
2159 
2160 		/* Call rx burst on bonded device */
2161 		TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2162 				&rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2163 				"rte_eth_rx_burst failed");
2164 
2165 		if (test_params->slave_port_ids[i] == primary_port) {
2166 			/* Verify bonded device rx count */
2167 			rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2168 			TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2169 					"Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2170 					test_params->bonded_port_id,
2171 					(unsigned int)port_stats.ipackets, burst_size);
2172 
2173 			/* Verify bonded slave devices rx count */
2174 			for (j = 0; j < test_params->bonded_slave_count; j++) {
2175 				rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2176 				if (i == j) {
2177 					TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2178 							"Slave Port (%d) ipackets value (%u) not as "
2179 							"expected (%d)", test_params->slave_port_ids[i],
2180 							(unsigned int)port_stats.ipackets, burst_size);
2181 				} else {
2182 					TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2183 							"Slave Port (%d) ipackets value (%u) not as "
2184 							"expected (%d)\n", test_params->slave_port_ids[i],
2185 							(unsigned int)port_stats.ipackets, 0);
2186 				}
2187 			}
2188 		} else {
2189 			for (j = 0; j < test_params->bonded_slave_count; j++) {
2190 				rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2191 				TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2192 						"Slave Port (%d) ipackets value (%u) not as expected "
2193 						"(%d)", test_params->slave_port_ids[i],
2194 						(unsigned int)port_stats.ipackets, 0);
2195 			}
2196 		}
2197 
2198 		/* free mbufs */
2199 		for (i = 0; i < MAX_PKT_BURST; i++) {
2200 			if (rx_pkt_burst[i] != NULL) {
2201 				rte_pktmbuf_free(rx_pkt_burst[i]);
2202 				rx_pkt_burst[i] = NULL;
2203 			}
2204 		}
2205 
2206 		/* reset bonded device stats */
2207 		rte_eth_stats_reset(test_params->bonded_port_id);
2208 	}
2209 
2210 	/* Clean up and remove slaves from bonded device */
2211 	return remove_slaves_and_stop_bonded_device();
2212 }
2213 
2214 static int
2215 test_activebackup_verify_promiscuous_enable_disable(void)
2216 {
2217 	int i, primary_port, promiscuous_en;
2218 	int ret;
2219 
2220 	/* Initialize bonded device with 4 slaves in round robin mode */
2221 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2222 			BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2223 			"Failed to initialize bonded device with slaves");
2224 
2225 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2226 	TEST_ASSERT(primary_port >= 0,
2227 			"failed to get primary slave for bonded port (%d)",
2228 			test_params->bonded_port_id);
2229 
2230 	ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
2231 	TEST_ASSERT_SUCCESS(ret,
2232 		"Failed to enable promiscuous mode for port %d: %s",
2233 		test_params->bonded_port_id, rte_strerror(-ret));
2234 
2235 	TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2236 			"Port (%d) promiscuous mode not enabled",
2237 			test_params->bonded_port_id);
2238 
2239 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2240 		promiscuous_en = rte_eth_promiscuous_get(
2241 				test_params->slave_port_ids[i]);
2242 		if (primary_port == test_params->slave_port_ids[i]) {
2243 			TEST_ASSERT_EQUAL(promiscuous_en, 1,
2244 					"slave port (%d) promiscuous mode not enabled",
2245 					test_params->slave_port_ids[i]);
2246 		} else {
2247 			TEST_ASSERT_EQUAL(promiscuous_en, 0,
2248 					"slave port (%d) promiscuous mode enabled",
2249 					test_params->slave_port_ids[i]);
2250 		}
2251 
2252 	}
2253 
2254 	ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
2255 	TEST_ASSERT_SUCCESS(ret,
2256 		"Failed to disable promiscuous mode for port %d: %s",
2257 		test_params->bonded_port_id, rte_strerror(-ret));
2258 
2259 	TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2260 			"Port (%d) promiscuous mode not disabled\n",
2261 			test_params->bonded_port_id);
2262 
2263 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2264 		promiscuous_en = rte_eth_promiscuous_get(
2265 				test_params->slave_port_ids[i]);
2266 		TEST_ASSERT_EQUAL(promiscuous_en, 0,
2267 				"slave port (%d) promiscuous mode not disabled\n",
2268 				test_params->slave_port_ids[i]);
2269 	}
2270 
2271 	/* Clean up and remove slaves from bonded device */
2272 	return remove_slaves_and_stop_bonded_device();
2273 }
2274 
2275 static int
2276 test_activebackup_verify_mac_assignment(void)
2277 {
2278 	struct rte_ether_addr read_mac_addr;
2279 	struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
2280 
2281 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2282 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2283 
2284 	/* Initialize bonded device with 2 slaves in active backup mode */
2285 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2286 			BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2287 			"Failed to initialize bonded device with slaves");
2288 
2289 	/* Verify that bonded MACs is that of first slave and that the other slave
2290 	 * MAC hasn't been changed */
2291 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2292 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2293 			sizeof(read_mac_addr)),
2294 			"bonded port (%d) mac address not set to that of primary port",
2295 			test_params->bonded_port_id);
2296 
2297 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2298 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2299 			sizeof(read_mac_addr)),
2300 			"slave port (%d) mac address not set to that of primary port",
2301 			test_params->slave_port_ids[0]);
2302 
2303 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2304 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2305 			sizeof(read_mac_addr)),
2306 			"slave port (%d) mac address not as expected",
2307 			test_params->slave_port_ids[1]);
2308 
2309 	/* change primary and verify that MAC addresses haven't changed */
2310 	TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2311 			test_params->slave_port_ids[1]), 0,
2312 			"Failed to set bonded port (%d) primary port to (%d)",
2313 			test_params->bonded_port_id, test_params->slave_port_ids[1]);
2314 
2315 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2316 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2317 			sizeof(read_mac_addr)),
2318 			"bonded port (%d) mac address not set to that of primary port",
2319 			test_params->bonded_port_id);
2320 
2321 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2322 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2323 			sizeof(read_mac_addr)),
2324 			"slave port (%d) mac address not set to that of primary port",
2325 			test_params->slave_port_ids[0]);
2326 
2327 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2328 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2329 			sizeof(read_mac_addr)),
2330 			"slave port (%d) mac address not as expected",
2331 			test_params->slave_port_ids[1]);
2332 
2333 	/* stop / start bonded device and verify that primary MAC address is
2334 	 * propagated to bonded device and slaves */
2335 
2336 	rte_eth_dev_stop(test_params->bonded_port_id);
2337 
2338 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2339 			"Failed to start device");
2340 
2341 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2342 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2343 			sizeof(read_mac_addr)),
2344 			"bonded port (%d) mac address not set to that of primary port",
2345 			test_params->bonded_port_id);
2346 
2347 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2348 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2349 			sizeof(read_mac_addr)),
2350 			"slave port (%d) mac address not as expected",
2351 			test_params->slave_port_ids[0]);
2352 
2353 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2354 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2355 			sizeof(read_mac_addr)),
2356 			"slave port (%d) mac address not set to that of primary port",
2357 			test_params->slave_port_ids[1]);
2358 
2359 	/* Set explicit MAC address */
2360 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2361 			test_params->bonded_port_id,
2362 			(struct rte_ether_addr *)bonded_mac),
2363 			"failed to set MAC address");
2364 
2365 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2366 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2367 			sizeof(read_mac_addr)),
2368 			"bonded port (%d) mac address not set to that of bonded port",
2369 			test_params->bonded_port_id);
2370 
2371 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2372 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2373 			sizeof(read_mac_addr)),
2374 			"slave port (%d) mac address not as expected",
2375 			test_params->slave_port_ids[0]);
2376 
2377 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2378 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2379 			sizeof(read_mac_addr)),
2380 			"slave port (%d) mac address not set to that of bonded port",
2381 			test_params->slave_port_ids[1]);
2382 
2383 	/* Clean up and remove slaves from bonded device */
2384 	return remove_slaves_and_stop_bonded_device();
2385 }
2386 
2387 static int
2388 test_activebackup_verify_slave_link_status_change_failover(void)
2389 {
2390 	struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2391 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2392 	struct rte_eth_stats port_stats;
2393 
2394 	uint16_t slaves[RTE_MAX_ETHPORTS];
2395 
2396 	int i, burst_size, slave_count, primary_port;
2397 
2398 	burst_size = 21;
2399 
2400 	memset(pkt_burst, 0, sizeof(pkt_burst));
2401 
2402 	/* Generate packet burst for testing */
2403 	TEST_ASSERT_EQUAL(generate_test_burst(
2404 			&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2405 			"generate_test_burst failed");
2406 
2407 	/* Initialize bonded device with 4 slaves in round robin mode */
2408 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2409 			BONDING_MODE_ACTIVE_BACKUP, 0,
2410 			TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2411 			"Failed to initialize bonded device with slaves");
2412 
2413 	/* Verify Current Slaves Count /Active Slave Count is */
2414 	slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2415 			RTE_MAX_ETHPORTS);
2416 	TEST_ASSERT_EQUAL(slave_count, 4,
2417 			"Number of slaves (%d) is not as expected (%d).",
2418 			slave_count, 4);
2419 
2420 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2421 			slaves, RTE_MAX_ETHPORTS);
2422 	TEST_ASSERT_EQUAL(slave_count, 4,
2423 			"Number of active slaves (%d) is not as expected (%d).",
2424 			slave_count, 4);
2425 
2426 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2427 	TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2428 			"Primary port not as expected");
2429 
2430 	/* Bring 2 slaves down and verify active slave count */
2431 	virtual_ethdev_simulate_link_status_interrupt(
2432 			test_params->slave_port_ids[1], 0);
2433 	virtual_ethdev_simulate_link_status_interrupt(
2434 			test_params->slave_port_ids[3], 0);
2435 
2436 	TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2437 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2438 			"Number of active slaves (%d) is not as expected (%d).",
2439 			slave_count, 2);
2440 
2441 	virtual_ethdev_simulate_link_status_interrupt(
2442 			test_params->slave_port_ids[1], 1);
2443 	virtual_ethdev_simulate_link_status_interrupt(
2444 			test_params->slave_port_ids[3], 1);
2445 
2446 
2447 	/* Bring primary port down, verify that active slave count is 3 and primary
2448 	 *  has changed */
2449 	virtual_ethdev_simulate_link_status_interrupt(
2450 			test_params->slave_port_ids[0], 0);
2451 
2452 	TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2453 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2454 			3,
2455 			"Number of active slaves (%d) is not as expected (%d).",
2456 			slave_count, 3);
2457 
2458 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2459 	TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2460 			"Primary port not as expected");
2461 
2462 	/* Verify that pkts are sent on new primary slave */
2463 
2464 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2465 			test_params->bonded_port_id, 0, &pkt_burst[0][0],
2466 			burst_size), burst_size, "rte_eth_tx_burst failed");
2467 
2468 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2469 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2470 			"(%d) port_stats.opackets not as expected",
2471 			test_params->slave_port_ids[2]);
2472 
2473 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2474 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2475 			"(%d) port_stats.opackets not as expected\n",
2476 			test_params->slave_port_ids[0]);
2477 
2478 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2479 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2480 			"(%d) port_stats.opackets not as expected\n",
2481 			test_params->slave_port_ids[1]);
2482 
2483 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2484 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2485 			"(%d) port_stats.opackets not as expected\n",
2486 			test_params->slave_port_ids[3]);
2487 
2488 	/* Generate packet burst for testing */
2489 
2490 	for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2491 		TEST_ASSERT_EQUAL(generate_test_burst(
2492 				&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2493 				"generate_test_burst failed");
2494 
2495 		virtual_ethdev_add_mbufs_to_rx_queue(
2496 			test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2497 	}
2498 
2499 	TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2500 			test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2501 			burst_size, "rte_eth_rx_burst\n");
2502 
2503 	/* Verify bonded device rx count */
2504 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2505 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2506 			"(%d) port_stats.ipackets not as expected",
2507 			test_params->bonded_port_id);
2508 
2509 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2510 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2511 			"(%d) port_stats.opackets not as expected",
2512 			test_params->slave_port_ids[2]);
2513 
2514 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2515 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2516 			"(%d) port_stats.opackets not as expected",
2517 			test_params->slave_port_ids[0]);
2518 
2519 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2520 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2521 			"(%d) port_stats.opackets not as expected",
2522 			test_params->slave_port_ids[1]);
2523 
2524 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2525 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2526 			"(%d) port_stats.opackets not as expected",
2527 			test_params->slave_port_ids[3]);
2528 
2529 	/* Clean up and remove slaves from bonded device */
2530 	return remove_slaves_and_stop_bonded_device();
2531 }
2532 
2533 /** Balance Mode Tests */
2534 
2535 static int
2536 test_balance_xmit_policy_configuration(void)
2537 {
2538 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2539 			BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2540 			"Failed to initialize_bonded_device_with_slaves.");
2541 
2542 	/* Invalid port id */
2543 	TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2544 			INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2545 			"Expected call to failed as invalid port specified.");
2546 
2547 	/* Set xmit policy on non bonded device */
2548 	TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2549 			test_params->slave_port_ids[0],	BALANCE_XMIT_POLICY_LAYER2),
2550 			"Expected call to failed as invalid port specified.");
2551 
2552 
2553 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2554 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2555 			"Failed to set balance xmit policy.");
2556 
2557 	TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2558 			BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2559 
2560 
2561 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2562 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2563 			"Failed to set balance xmit policy.");
2564 
2565 	TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2566 			BALANCE_XMIT_POLICY_LAYER23,
2567 			"balance xmit policy not as expected.");
2568 
2569 
2570 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2571 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2572 			"Failed to set balance xmit policy.");
2573 
2574 	TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2575 			BALANCE_XMIT_POLICY_LAYER34,
2576 			"balance xmit policy not as expected.");
2577 
2578 	/* Invalid port id */
2579 	TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2580 			"Expected call to failed as invalid port specified.");
2581 
2582 	/* Clean up and remove slaves from bonded device */
2583 	return remove_slaves_and_stop_bonded_device();
2584 }
2585 
2586 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2587 
2588 static int
2589 test_balance_l2_tx_burst(void)
2590 {
2591 	struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2592 	int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2593 
2594 	uint16_t pktlen;
2595 	int i;
2596 	struct rte_eth_stats port_stats;
2597 
2598 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2599 			BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2600 			"Failed to initialize_bonded_device_with_slaves.");
2601 
2602 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2603 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2604 			"Failed to set balance xmit policy.");
2605 
2606 	initialize_eth_header(test_params->pkt_eth_hdr,
2607 			(struct rte_ether_addr *)src_mac,
2608 			(struct rte_ether_addr *)dst_mac_0,
2609 			RTE_ETHER_TYPE_IPV4, 0, 0);
2610 	pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2611 			dst_port_0, 16);
2612 	pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2613 			dst_addr_0, pktlen);
2614 
2615 	/* Generate a burst 1 of packets to transmit */
2616 	TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2617 			test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2618 			test_params->pkt_udp_hdr, burst_size[0],
2619 			PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2620 			"failed to generate packet burst");
2621 
2622 	initialize_eth_header(test_params->pkt_eth_hdr,
2623 			(struct rte_ether_addr *)src_mac,
2624 			(struct rte_ether_addr *)dst_mac_1,
2625 			RTE_ETHER_TYPE_IPV4, 0, 0);
2626 
2627 	/* Generate a burst 2 of packets to transmit */
2628 	TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2629 			test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2630 			test_params->pkt_udp_hdr, burst_size[1],
2631 			PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2632 			"failed to generate packet burst");
2633 
2634 	/* Send burst 1 on bonded port */
2635 	for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2636 		TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2637 				&pkts_burst[i][0], burst_size[i]),
2638 				burst_size[i], "Failed to transmit packet burst");
2639 	}
2640 
2641 	/* Verify bonded port tx stats */
2642 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2643 	TEST_ASSERT_EQUAL(port_stats.opackets,
2644 			(uint64_t)(burst_size[0] + burst_size[1]),
2645 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
2646 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2647 			burst_size[0] + burst_size[1]);
2648 
2649 
2650 	/* Verify slave ports tx stats */
2651 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2652 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2653 			"Slave Port (%d) opackets value (%u) not as expected (%d)",
2654 			test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2655 			burst_size[0]);
2656 
2657 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2658 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2659 			"Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2660 			test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2661 			burst_size[1]);
2662 
2663 	/* Put all slaves down and try and transmit */
2664 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2665 
2666 		virtual_ethdev_simulate_link_status_interrupt(
2667 				test_params->slave_port_ids[i], 0);
2668 	}
2669 
2670 	/* Send burst on bonded port */
2671 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2672 			test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2673 			0, "Expected zero packet");
2674 
2675 	/* Clean up and remove slaves from bonded device */
2676 	return remove_slaves_and_stop_bonded_device();
2677 }
2678 
2679 static int
2680 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2681 		uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2682 {
2683 	int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2684 
2685 	struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2686 	struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2687 
2688 	struct rte_eth_stats port_stats;
2689 
2690 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2691 			BONDING_MODE_BALANCE, 0, 2, 1),
2692 			"Failed to initialize_bonded_device_with_slaves.");
2693 
2694 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2695 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2696 			"Failed to set balance xmit policy.");
2697 
2698 	burst_size_1 = 20;
2699 	burst_size_2 = 10;
2700 
2701 	TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2702 			"Burst size specified is greater than supported.");
2703 
2704 	/* Generate test bursts of packets to transmit */
2705 	TEST_ASSERT_EQUAL(generate_test_burst(
2706 			pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2707 			burst_size_1, "failed to generate packet burst");
2708 
2709 	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2710 			toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2711 			"failed to generate packet burst");
2712 
2713 	/* Send burst 1 on bonded port */
2714 	nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2715 			burst_size_1);
2716 	TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2717 
2718 	/* Send burst 2 on bonded port */
2719 	nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2720 			burst_size_2);
2721 	TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2722 
2723 	/* Verify bonded port tx stats */
2724 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2725 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2726 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
2727 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2728 			nb_tx_1 + nb_tx_2);
2729 
2730 	/* Verify slave ports tx stats */
2731 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2732 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2733 			"Slave Port (%d) opackets value (%u) not as expected (%d)",
2734 			test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2735 			nb_tx_1);
2736 
2737 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2738 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2739 			"Slave Port (%d) opackets value (%u) not as expected (%d)",
2740 			test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2741 			nb_tx_2);
2742 
2743 	/* Put all slaves down and try and transmit */
2744 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2745 
2746 		virtual_ethdev_simulate_link_status_interrupt(
2747 				test_params->slave_port_ids[i], 0);
2748 	}
2749 
2750 	/* Send burst on bonded port */
2751 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2752 			test_params->bonded_port_id, 0, pkts_burst_1,
2753 			burst_size_1), 0, "Expected zero packet");
2754 
2755 
2756 	/* Clean up and remove slaves from bonded device */
2757 	return remove_slaves_and_stop_bonded_device();
2758 }
2759 
2760 static int
2761 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2762 {
2763 	return balance_l23_tx_burst(0, 1, 0, 1);
2764 }
2765 
2766 static int
2767 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2768 {
2769 	return balance_l23_tx_burst(1, 1, 0, 1);
2770 }
2771 
2772 static int
2773 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2774 {
2775 	return balance_l23_tx_burst(0, 0, 0, 1);
2776 }
2777 
2778 static int
2779 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2780 {
2781 	return balance_l23_tx_burst(1, 0, 0, 1);
2782 }
2783 
2784 static int
2785 test_balance_l23_tx_burst_toggle_mac_addr(void)
2786 {
2787 	return balance_l23_tx_burst(0, 0, 1, 0);
2788 }
2789 
2790 static int
2791 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2792 		uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2793 		uint8_t toggle_udp_port)
2794 {
2795 	int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2796 
2797 	struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2798 	struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2799 
2800 	struct rte_eth_stats port_stats;
2801 
2802 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2803 			BONDING_MODE_BALANCE, 0, 2, 1),
2804 			"Failed to initialize_bonded_device_with_slaves.");
2805 
2806 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2807 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2808 			"Failed to set balance xmit policy.");
2809 
2810 	burst_size_1 = 20;
2811 	burst_size_2 = 10;
2812 
2813 	TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2814 			"Burst size specified is greater than supported.");
2815 
2816 	/* Generate test bursts of packets to transmit */
2817 	TEST_ASSERT_EQUAL(generate_test_burst(
2818 			pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2819 			burst_size_1, "failed to generate burst");
2820 
2821 	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2822 			vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2823 			toggle_udp_port), burst_size_2, "failed to generate burst");
2824 
2825 	/* Send burst 1 on bonded port */
2826 	nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2827 			burst_size_1);
2828 	TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2829 
2830 	/* Send burst 2 on bonded port */
2831 	nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2832 			burst_size_2);
2833 	TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2834 
2835 
2836 	/* Verify bonded port tx stats */
2837 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2838 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2839 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
2840 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2841 			nb_tx_1 + nb_tx_2);
2842 
2843 	/* Verify slave ports tx stats */
2844 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2845 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2846 			"Slave Port (%d) opackets value (%u) not as expected (%d)",
2847 			test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2848 			nb_tx_1);
2849 
2850 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2851 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2852 			"Slave Port (%d) opackets value (%u) not as expected (%d)",
2853 			test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2854 			nb_tx_2);
2855 
2856 	/* Put all slaves down and try and transmit */
2857 	for (i = 0; i < test_params->bonded_slave_count; i++) {
2858 
2859 		virtual_ethdev_simulate_link_status_interrupt(
2860 				test_params->slave_port_ids[i], 0);
2861 	}
2862 
2863 	/* Send burst on bonded port */
2864 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2865 			test_params->bonded_port_id, 0, pkts_burst_1,
2866 			burst_size_1), 0, "Expected zero packet");
2867 
2868 	/* Clean up and remove slaves from bonded device */
2869 	return remove_slaves_and_stop_bonded_device();
2870 }
2871 
2872 static int
2873 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2874 {
2875 	return balance_l34_tx_burst(0, 1, 0, 1, 0);
2876 }
2877 
2878 static int
2879 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2880 {
2881 	return balance_l34_tx_burst(0, 1, 0, 0, 1);
2882 }
2883 
2884 static int
2885 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2886 {
2887 	return balance_l34_tx_burst(1, 1, 0, 1, 0);
2888 }
2889 
2890 static int
2891 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2892 {
2893 	return balance_l34_tx_burst(0, 0, 0, 1, 0);
2894 }
2895 
2896 static int
2897 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2898 {
2899 	return balance_l34_tx_burst(1, 0, 0, 1, 0);
2900 }
2901 
2902 static int
2903 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2904 {
2905 	return balance_l34_tx_burst(0, 0, 0, 0, 1);
2906 }
2907 
2908 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT			(2)
2909 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1			(40)
2910 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2			(20)
2911 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT		(25)
2912 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX	(0)
2913 
2914 static int
2915 test_balance_tx_burst_slave_tx_fail(void)
2916 {
2917 	struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2918 	struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2919 
2920 	struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2921 
2922 	struct rte_eth_stats port_stats;
2923 
2924 	int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2925 
2926 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2927 			BONDING_MODE_BALANCE, 0,
2928 			TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2929 			"Failed to initialise bonded device");
2930 
2931 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2932 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2933 			"Failed to set balance xmit policy.");
2934 
2935 
2936 	/* Generate test bursts for transmission */
2937 	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2938 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2939 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2940 			"Failed to generate test packet burst 1");
2941 
2942 	first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2943 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2944 
2945 	/* copy mbuf referneces for expected transmission failures */
2946 	for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2947 		expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2948 
2949 	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2950 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2951 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2952 			"Failed to generate test packet burst 2");
2953 
2954 
2955 	/* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2956 	 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2957 	virtual_ethdev_tx_burst_fn_set_success(
2958 			test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2959 			0);
2960 
2961 	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2962 			test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2963 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2964 
2965 
2966 	/* Transmit burst 1 */
2967 	tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2968 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2969 
2970 	TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2971 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2972 			"Transmitted (%d) packets, expected to transmit (%d) packets",
2973 			tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2974 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2975 
2976 	/* Verify that failed packet are expected failed packets */
2977 	for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
2978 		TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
2979 				"expected mbuf (%d) pointer %p not expected pointer %p",
2980 				i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
2981 	}
2982 
2983 	/* Transmit burst 2 */
2984 	tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2985 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2986 
2987 	TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2988 			"Transmitted (%d) packets, expected to transmit (%d) packets",
2989 			tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2990 
2991 
2992 	/* Verify bonded port tx stats */
2993 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2994 
2995 	TEST_ASSERT_EQUAL(port_stats.opackets,
2996 			(uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2997 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2998 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
2999 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
3000 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3001 			(TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3002 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3003 			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3004 
3005 	/* Verify slave ports tx stats */
3006 
3007 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3008 
3009 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3010 				TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3011 				TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3012 				"Slave Port (%d) opackets value (%u) not as expected (%d)",
3013 				test_params->slave_port_ids[0],
3014 				(unsigned int)port_stats.opackets,
3015 				TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3016 				TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3017 
3018 
3019 
3020 
3021 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3022 
3023 	TEST_ASSERT_EQUAL(port_stats.opackets,
3024 				(uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3025 				"Slave Port (%d) opackets value (%u) not as expected (%d)",
3026 				test_params->slave_port_ids[1],
3027 				(unsigned int)port_stats.opackets,
3028 				TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3029 
3030 	/* Verify that all mbufs have a ref value of zero */
3031 	TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3032 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3033 			"mbufs refcnts not as expected");
3034 
3035 	free_mbufs(&pkts_burst_1[tx_count_1],
3036 			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3037 
3038 	/* Clean up and remove slaves from bonded device */
3039 	return remove_slaves_and_stop_bonded_device();
3040 }
3041 
3042 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3043 
3044 static int
3045 test_balance_rx_burst(void)
3046 {
3047 	struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3048 
3049 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3050 	struct rte_eth_stats port_stats;
3051 
3052 	int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3053 	int i, j;
3054 
3055 	memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3056 
3057 	/* Initialize bonded device with 4 slaves in round robin mode */
3058 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3059 			BONDING_MODE_BALANCE, 0, 3, 1),
3060 			"Failed to initialise bonded device");
3061 
3062 	/* Generate test bursts of packets to transmit */
3063 	for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3064 		TEST_ASSERT_EQUAL(generate_test_burst(
3065 				&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3066 				0, 0), burst_size[i],
3067 				"failed to generate packet burst");
3068 	}
3069 
3070 	/* Add rx data to slaves */
3071 	for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3072 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3073 				&gen_pkt_burst[i][0], burst_size[i]);
3074 	}
3075 
3076 	/* Call rx burst on bonded device */
3077 	/* Send burst on bonded port */
3078 	TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3079 			rx_pkt_burst, MAX_PKT_BURST),
3080 			burst_size[0] + burst_size[1] + burst_size[2],
3081 			"balance rx burst failed\n");
3082 
3083 	/* Verify bonded device rx count */
3084 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3085 	TEST_ASSERT_EQUAL(port_stats.ipackets,
3086 			(uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3087 			"Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3088 			test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3089 			burst_size[0] + burst_size[1] + burst_size[2]);
3090 
3091 
3092 	/* Verify bonded slave devices rx counts */
3093 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3094 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3095 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3096 				test_params->slave_port_ids[0],
3097 				(unsigned int)port_stats.ipackets, burst_size[0]);
3098 
3099 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3100 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3101 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3102 			test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3103 			burst_size[1]);
3104 
3105 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3106 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3107 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3108 			test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3109 			burst_size[2]);
3110 
3111 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3112 	TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3113 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3114 			test_params->slave_port_ids[3],	(unsigned int)port_stats.ipackets,
3115 			0);
3116 
3117 	/* free mbufs */
3118 	for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3119 		for (j = 0; j < MAX_PKT_BURST; j++) {
3120 			if (gen_pkt_burst[i][j] != NULL) {
3121 				rte_pktmbuf_free(gen_pkt_burst[i][j]);
3122 				gen_pkt_burst[i][j] = NULL;
3123 			}
3124 		}
3125 	}
3126 
3127 	/* Clean up and remove slaves from bonded device */
3128 	return remove_slaves_and_stop_bonded_device();
3129 }
3130 
3131 static int
3132 test_balance_verify_promiscuous_enable_disable(void)
3133 {
3134 	int i;
3135 	int ret;
3136 
3137 	/* Initialize bonded device with 4 slaves in round robin mode */
3138 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3139 			BONDING_MODE_BALANCE, 0, 4, 1),
3140 			"Failed to initialise bonded device");
3141 
3142 	ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3143 	TEST_ASSERT_SUCCESS(ret,
3144 		"Failed to enable promiscuous mode for port %d: %s",
3145 		test_params->bonded_port_id, rte_strerror(-ret));
3146 
3147 	TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3148 			"Port (%d) promiscuous mode not enabled",
3149 			test_params->bonded_port_id);
3150 
3151 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3152 		TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3153 				test_params->slave_port_ids[i]), 1,
3154 				"Port (%d) promiscuous mode not enabled",
3155 				test_params->slave_port_ids[i]);
3156 	}
3157 
3158 	ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3159 	TEST_ASSERT_SUCCESS(ret,
3160 		"Failed to disable promiscuous mode for port %d: %s",
3161 		test_params->bonded_port_id, rte_strerror(-ret));
3162 
3163 	TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3164 			"Port (%d) promiscuous mode not disabled",
3165 			test_params->bonded_port_id);
3166 
3167 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3168 		TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3169 				test_params->slave_port_ids[i]), 0,
3170 				"Port (%d) promiscuous mode not disabled",
3171 				test_params->slave_port_ids[i]);
3172 	}
3173 
3174 	/* Clean up and remove slaves from bonded device */
3175 	return remove_slaves_and_stop_bonded_device();
3176 }
3177 
3178 static int
3179 test_balance_verify_mac_assignment(void)
3180 {
3181 	struct rte_ether_addr read_mac_addr;
3182 	struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3183 
3184 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3185 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3186 
3187 	/* Initialize bonded device with 2 slaves in active backup mode */
3188 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3189 			BONDING_MODE_BALANCE, 0, 2, 1),
3190 			"Failed to initialise bonded device");
3191 
3192 	/* Verify that bonded MACs is that of first slave and that the other slave
3193 	 * MAC hasn't been changed */
3194 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3195 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3196 			sizeof(read_mac_addr)),
3197 			"bonded port (%d) mac address not set to that of primary port",
3198 			test_params->bonded_port_id);
3199 
3200 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3201 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3202 			sizeof(read_mac_addr)),
3203 			"slave port (%d) mac address not set to that of primary port",
3204 			test_params->slave_port_ids[0]);
3205 
3206 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3207 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3208 			sizeof(read_mac_addr)),
3209 			"slave port (%d) mac address not set to that of primary port",
3210 			test_params->slave_port_ids[1]);
3211 
3212 	/* change primary and verify that MAC addresses haven't changed */
3213 	TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3214 			test_params->slave_port_ids[1]),
3215 			"Failed to set bonded port (%d) primary port to (%d)\n",
3216 			test_params->bonded_port_id, test_params->slave_port_ids[1]);
3217 
3218 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3219 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3220 			sizeof(read_mac_addr)),
3221 			"bonded port (%d) mac address not set to that of primary port",
3222 			test_params->bonded_port_id);
3223 
3224 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3225 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3226 			sizeof(read_mac_addr)),
3227 			"slave port (%d) mac address not set to that of primary port",
3228 			test_params->slave_port_ids[0]);
3229 
3230 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3231 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3232 			sizeof(read_mac_addr)),
3233 			"slave port (%d) mac address not set to that of primary port",
3234 			test_params->slave_port_ids[1]);
3235 
3236 	/* stop / start bonded device and verify that primary MAC address is
3237 	 * propagated to bonded device and slaves */
3238 
3239 	rte_eth_dev_stop(test_params->bonded_port_id);
3240 
3241 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3242 			"Failed to start bonded device");
3243 
3244 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3245 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3246 			sizeof(read_mac_addr)),
3247 			"bonded port (%d) mac address not set to that of primary port",
3248 			test_params->bonded_port_id);
3249 
3250 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3251 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3252 			sizeof(read_mac_addr)),
3253 			"slave port (%d) mac address not set to that of primary port",
3254 			test_params->slave_port_ids[0]);
3255 
3256 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3257 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3258 			sizeof(read_mac_addr)),
3259 			"slave port (%d) mac address not set to that of primary port",
3260 			test_params->slave_port_ids[1]);
3261 
3262 	/* Set explicit MAC address */
3263 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3264 			test_params->bonded_port_id,
3265 			(struct rte_ether_addr *)bonded_mac),
3266 			"failed to set MAC");
3267 
3268 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3269 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3270 			sizeof(read_mac_addr)),
3271 			"bonded port (%d) mac address not set to that of bonded port",
3272 			test_params->bonded_port_id);
3273 
3274 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3275 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3276 			sizeof(read_mac_addr)),
3277 			"slave port (%d) mac address not as expected\n",
3278 				test_params->slave_port_ids[0]);
3279 
3280 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3281 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3282 			sizeof(read_mac_addr)),
3283 			"slave port (%d) mac address not set to that of bonded port",
3284 			test_params->slave_port_ids[1]);
3285 
3286 	/* Clean up and remove slaves from bonded device */
3287 	return remove_slaves_and_stop_bonded_device();
3288 }
3289 
3290 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3291 
3292 static int
3293 test_balance_verify_slave_link_status_change_behaviour(void)
3294 {
3295 	struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3296 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3297 	struct rte_eth_stats port_stats;
3298 
3299 	uint16_t slaves[RTE_MAX_ETHPORTS];
3300 
3301 	int i, burst_size, slave_count;
3302 
3303 	memset(pkt_burst, 0, sizeof(pkt_burst));
3304 
3305 	/* Initialize bonded device with 4 slaves in round robin mode */
3306 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3307 			BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3308 			"Failed to initialise bonded device");
3309 
3310 	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3311 			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3312 			"Failed to set balance xmit policy.");
3313 
3314 
3315 	/* Verify Current Slaves Count /Active Slave Count is */
3316 	slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3317 			RTE_MAX_ETHPORTS);
3318 	TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3319 			"Number of slaves (%d) is not as expected (%d).",
3320 			slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3321 
3322 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3323 			slaves, RTE_MAX_ETHPORTS);
3324 	TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3325 			"Number of active slaves (%d) is not as expected (%d).",
3326 			slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3327 
3328 	/* Set 2 slaves link status to down */
3329 	virtual_ethdev_simulate_link_status_interrupt(
3330 			test_params->slave_port_ids[1], 0);
3331 	virtual_ethdev_simulate_link_status_interrupt(
3332 			test_params->slave_port_ids[3], 0);
3333 
3334 	TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3335 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3336 			"Number of active slaves (%d) is not as expected (%d).",
3337 			slave_count, 2);
3338 
3339 	/* Send to sets of packet burst and verify that they are balanced across
3340 	 *  slaves */
3341 	burst_size = 21;
3342 
3343 	TEST_ASSERT_EQUAL(generate_test_burst(
3344 			&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3345 			"generate_test_burst failed");
3346 
3347 	TEST_ASSERT_EQUAL(generate_test_burst(
3348 			&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3349 			"generate_test_burst failed");
3350 
3351 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3352 			test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3353 			burst_size, "rte_eth_tx_burst failed");
3354 
3355 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3356 			test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3357 			burst_size, "rte_eth_tx_burst failed");
3358 
3359 
3360 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3361 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3362 			"(%d) port_stats.opackets (%d) not as expected (%d).",
3363 			test_params->bonded_port_id, (int)port_stats.opackets,
3364 			burst_size + burst_size);
3365 
3366 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3367 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3368 			"(%d) port_stats.opackets (%d) not as expected (%d).",
3369 			test_params->slave_port_ids[0], (int)port_stats.opackets,
3370 			burst_size);
3371 
3372 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3373 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3374 			"(%d) port_stats.opackets (%d) not as expected (%d).",
3375 			test_params->slave_port_ids[2], (int)port_stats.opackets,
3376 			burst_size);
3377 
3378 	/* verify that all packets get send on primary slave when no other slaves
3379 	 * are available */
3380 	virtual_ethdev_simulate_link_status_interrupt(
3381 			test_params->slave_port_ids[2], 0);
3382 
3383 	TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3384 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3385 			"Number of active slaves (%d) is not as expected (%d).",
3386 			slave_count, 1);
3387 
3388 	TEST_ASSERT_EQUAL(generate_test_burst(
3389 			&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3390 			"generate_test_burst failed");
3391 
3392 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3393 			test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3394 			burst_size, "rte_eth_tx_burst failed");
3395 
3396 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3397 	TEST_ASSERT_EQUAL(port_stats.opackets,
3398 			(uint64_t)(burst_size + burst_size + burst_size),
3399 			"(%d) port_stats.opackets (%d) not as expected (%d).\n",
3400 			test_params->bonded_port_id, (int)port_stats.opackets,
3401 			burst_size + burst_size + burst_size);
3402 
3403 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3404 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3405 			"(%d) port_stats.opackets (%d) not as expected (%d).",
3406 			test_params->slave_port_ids[0], (int)port_stats.opackets,
3407 			burst_size + burst_size);
3408 
3409 	virtual_ethdev_simulate_link_status_interrupt(
3410 			test_params->slave_port_ids[0], 0);
3411 	virtual_ethdev_simulate_link_status_interrupt(
3412 			test_params->slave_port_ids[1], 1);
3413 	virtual_ethdev_simulate_link_status_interrupt(
3414 			test_params->slave_port_ids[2], 1);
3415 	virtual_ethdev_simulate_link_status_interrupt(
3416 			test_params->slave_port_ids[3], 1);
3417 
3418 	for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3419 		TEST_ASSERT_EQUAL(generate_test_burst(
3420 				&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3421 				"Failed to generate packet burst");
3422 
3423 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3424 				&pkt_burst[i][0], burst_size);
3425 	}
3426 
3427 	/* Verify that pkts are not received on slaves with link status down */
3428 
3429 	rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3430 			MAX_PKT_BURST);
3431 
3432 	/* Verify bonded device rx count */
3433 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3434 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3435 			"(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3436 			test_params->bonded_port_id, (int)port_stats.ipackets,
3437 			burst_size * 3);
3438 
3439 	/* Clean up and remove slaves from bonded device */
3440 	return remove_slaves_and_stop_bonded_device();
3441 }
3442 
3443 static int
3444 test_broadcast_tx_burst(void)
3445 {
3446 	int i, pktlen, burst_size;
3447 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3448 
3449 	struct rte_eth_stats port_stats;
3450 
3451 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3452 			BONDING_MODE_BROADCAST, 0, 2, 1),
3453 			"Failed to initialise bonded device");
3454 
3455 	initialize_eth_header(test_params->pkt_eth_hdr,
3456 			(struct rte_ether_addr *)src_mac,
3457 			(struct rte_ether_addr *)dst_mac_0,
3458 			RTE_ETHER_TYPE_IPV4, 0, 0);
3459 
3460 	pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3461 			dst_port_0, 16);
3462 	pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3463 			dst_addr_0, pktlen);
3464 
3465 	burst_size = 20 * test_params->bonded_slave_count;
3466 
3467 	TEST_ASSERT(burst_size < MAX_PKT_BURST,
3468 			"Burst size specified is greater than supported.");
3469 
3470 	/* Generate a burst of packets to transmit */
3471 	TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3472 			pkts_burst,	test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3473 			1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3474 			1), burst_size, "Failed to generate packet burst");
3475 
3476 	/* Send burst on bonded port */
3477 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3478 			pkts_burst, burst_size), burst_size,
3479 			"Bonded Port (%d) rx burst failed, packets transmitted value "
3480 			"not as expected (%d)",
3481 			test_params->bonded_port_id, burst_size);
3482 
3483 	/* Verify bonded port tx stats */
3484 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3485 	TEST_ASSERT_EQUAL(port_stats.opackets,
3486 			(uint64_t)burst_size * test_params->bonded_slave_count,
3487 			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
3488 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3489 			burst_size);
3490 
3491 	/* Verify slave ports tx stats */
3492 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3493 		rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3494 		TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3495 				"Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3496 				test_params->bonded_port_id,
3497 				(unsigned int)port_stats.opackets, burst_size);
3498 	}
3499 
3500 	/* Put all slaves down and try and transmit */
3501 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3502 
3503 		virtual_ethdev_simulate_link_status_interrupt(
3504 				test_params->slave_port_ids[i], 0);
3505 	}
3506 
3507 	/* Send burst on bonded port */
3508 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3509 			test_params->bonded_port_id, 0, pkts_burst, burst_size),  0,
3510 			"transmitted an unexpected number of packets");
3511 
3512 	/* Clean up and remove slaves from bonded device */
3513 	return remove_slaves_and_stop_bonded_device();
3514 }
3515 
3516 
3517 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT		(3)
3518 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE			(40)
3519 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT	(15)
3520 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT	(10)
3521 
3522 static int
3523 test_broadcast_tx_burst_slave_tx_fail(void)
3524 {
3525 	struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3526 	struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3527 
3528 	struct rte_eth_stats port_stats;
3529 
3530 	int i, tx_count;
3531 
3532 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3533 			BONDING_MODE_BROADCAST, 0,
3534 			TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3535 			"Failed to initialise bonded device");
3536 
3537 	/* Generate test bursts for transmission */
3538 	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3539 			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3540 			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3541 			"Failed to generate test packet burst");
3542 
3543 	for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3544 		expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3545 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3546 	}
3547 
3548 	/* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3549 	 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3550 	virtual_ethdev_tx_burst_fn_set_success(
3551 			test_params->slave_port_ids[0],
3552 			0);
3553 	virtual_ethdev_tx_burst_fn_set_success(
3554 			test_params->slave_port_ids[1],
3555 			0);
3556 	virtual_ethdev_tx_burst_fn_set_success(
3557 			test_params->slave_port_ids[2],
3558 			0);
3559 
3560 	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3561 			test_params->slave_port_ids[0],
3562 			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3563 
3564 	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3565 			test_params->slave_port_ids[1],
3566 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3567 
3568 	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3569 			test_params->slave_port_ids[2],
3570 			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3571 
3572 	/* Transmit burst */
3573 	tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3574 			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3575 
3576 	TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3577 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3578 			"Transmitted (%d) packets, expected to transmit (%d) packets",
3579 			tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3580 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3581 
3582 	/* Verify that failed packet are expected failed packets */
3583 	for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3584 		TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3585 				"expected mbuf (%d) pointer %p not expected pointer %p",
3586 				i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3587 	}
3588 
3589 	/* Verify slave ports tx stats */
3590 
3591 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3592 
3593 	TEST_ASSERT_EQUAL(port_stats.opackets,
3594 			(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3595 			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3596 			"Port (%d) opackets value (%u) not as expected (%d)",
3597 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3598 			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3599 			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3600 
3601 
3602 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3603 
3604 	TEST_ASSERT_EQUAL(port_stats.opackets,
3605 			(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3606 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3607 			"Port (%d) opackets value (%u) not as expected (%d)",
3608 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3609 			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3610 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3611 
3612 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3613 
3614 	TEST_ASSERT_EQUAL(port_stats.opackets,
3615 			(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3616 			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3617 			"Port (%d) opackets value (%u) not as expected (%d)",
3618 			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3619 			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3620 			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3621 
3622 
3623 	/* Verify that all mbufs who transmission failed have a ref value of one */
3624 	TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3625 			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3626 			"mbufs refcnts not as expected");
3627 
3628 	free_mbufs(&pkts_burst[tx_count],
3629 		TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3630 
3631 	/* Clean up and remove slaves from bonded device */
3632 	return remove_slaves_and_stop_bonded_device();
3633 }
3634 
3635 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3636 
3637 static int
3638 test_broadcast_rx_burst(void)
3639 {
3640 	struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3641 
3642 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3643 	struct rte_eth_stats port_stats;
3644 
3645 	int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3646 	int i, j;
3647 
3648 	memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3649 
3650 	/* Initialize bonded device with 4 slaves in round robin mode */
3651 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3652 			BONDING_MODE_BROADCAST, 0, 3, 1),
3653 			"Failed to initialise bonded device");
3654 
3655 	/* Generate test bursts of packets to transmit */
3656 	for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3657 		TEST_ASSERT_EQUAL(generate_test_burst(
3658 				&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3659 				burst_size[i], "failed to generate packet burst");
3660 	}
3661 
3662 	/* Add rx data to slave 0 */
3663 	for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3664 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3665 				&gen_pkt_burst[i][0], burst_size[i]);
3666 	}
3667 
3668 
3669 	/* Call rx burst on bonded device */
3670 	/* Send burst on bonded port */
3671 	TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3672 			test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3673 			burst_size[0] + burst_size[1] + burst_size[2],
3674 			"rx burst failed");
3675 
3676 	/* Verify bonded device rx count */
3677 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3678 	TEST_ASSERT_EQUAL(port_stats.ipackets,
3679 			(uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3680 			"Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3681 			test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3682 			burst_size[0] + burst_size[1] + burst_size[2]);
3683 
3684 
3685 	/* Verify bonded slave devices rx counts */
3686 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3687 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3688 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3689 			test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3690 			burst_size[0]);
3691 
3692 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3693 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3694 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3695 			test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3696 			burst_size[1]);
3697 
3698 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3699 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3700 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3701 			test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3702 			burst_size[2]);
3703 
3704 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3705 	TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3706 			"Slave Port (%d) ipackets value (%u) not as expected (%d)",
3707 			test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3708 			0);
3709 
3710 	/* free mbufs allocate for rx testing */
3711 	for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3712 		for (j = 0; j < MAX_PKT_BURST; j++) {
3713 			if (gen_pkt_burst[i][j] != NULL) {
3714 				rte_pktmbuf_free(gen_pkt_burst[i][j]);
3715 				gen_pkt_burst[i][j] = NULL;
3716 			}
3717 		}
3718 	}
3719 
3720 	/* Clean up and remove slaves from bonded device */
3721 	return remove_slaves_and_stop_bonded_device();
3722 }
3723 
3724 static int
3725 test_broadcast_verify_promiscuous_enable_disable(void)
3726 {
3727 	int i;
3728 	int ret;
3729 
3730 	/* Initialize bonded device with 4 slaves in round robin mode */
3731 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3732 			BONDING_MODE_BROADCAST, 0, 4, 1),
3733 			"Failed to initialise bonded device");
3734 
3735 	ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3736 	TEST_ASSERT_SUCCESS(ret,
3737 		"Failed to enable promiscuous mode for port %d: %s",
3738 		test_params->bonded_port_id, rte_strerror(-ret));
3739 
3740 
3741 	TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3742 			"Port (%d) promiscuous mode not enabled",
3743 			test_params->bonded_port_id);
3744 
3745 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3746 		TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3747 				test_params->slave_port_ids[i]), 1,
3748 				"Port (%d) promiscuous mode not enabled",
3749 				test_params->slave_port_ids[i]);
3750 	}
3751 
3752 	ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3753 	TEST_ASSERT_SUCCESS(ret,
3754 		"Failed to disable promiscuous mode for port %d: %s",
3755 		test_params->bonded_port_id, rte_strerror(-ret));
3756 
3757 	TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3758 			"Port (%d) promiscuous mode not disabled",
3759 			test_params->bonded_port_id);
3760 
3761 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3762 		TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3763 				test_params->slave_port_ids[i]), 0,
3764 				"Port (%d) promiscuous mode not disabled",
3765 				test_params->slave_port_ids[i]);
3766 	}
3767 
3768 	/* Clean up and remove slaves from bonded device */
3769 	return remove_slaves_and_stop_bonded_device();
3770 }
3771 
3772 static int
3773 test_broadcast_verify_mac_assignment(void)
3774 {
3775 	struct rte_ether_addr read_mac_addr;
3776 	struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3777 
3778 	int i;
3779 
3780 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3781 	rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3782 
3783 	/* Initialize bonded device with 4 slaves in round robin mode */
3784 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3785 			BONDING_MODE_BROADCAST, 0, 4, 1),
3786 			"Failed to initialise bonded device");
3787 
3788 	/* Verify that all MACs are the same as first slave added to bonded
3789 	 * device */
3790 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3791 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3792 		TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3793 				sizeof(read_mac_addr)),
3794 				"slave port (%d) mac address not set to that of primary port",
3795 				test_params->slave_port_ids[i]);
3796 	}
3797 
3798 	/* change primary and verify that MAC addresses haven't changed */
3799 	TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3800 			test_params->slave_port_ids[2]),
3801 			"Failed to set bonded port (%d) primary port to (%d)",
3802 			test_params->bonded_port_id, test_params->slave_port_ids[i]);
3803 
3804 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3805 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3806 		TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3807 				sizeof(read_mac_addr)),
3808 				"slave port (%d) mac address has changed to that of primary "
3809 				"port without stop/start toggle of bonded device",
3810 				test_params->slave_port_ids[i]);
3811 	}
3812 
3813 	/* stop / start bonded device and verify that primary MAC address is
3814 	 * propagated to bonded device and slaves */
3815 
3816 	rte_eth_dev_stop(test_params->bonded_port_id);
3817 
3818 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3819 			"Failed to start bonded device");
3820 
3821 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3822 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3823 			sizeof(read_mac_addr)),
3824 			"bonded port (%d) mac address not set to that of new primary  port",
3825 			test_params->slave_port_ids[i]);
3826 
3827 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3828 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3829 		TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3830 				sizeof(read_mac_addr)),
3831 				"slave port (%d) mac address not set to that of new primary "
3832 				"port", test_params->slave_port_ids[i]);
3833 	}
3834 
3835 	/* Set explicit MAC address */
3836 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3837 			test_params->bonded_port_id,
3838 			(struct rte_ether_addr *)bonded_mac),
3839 			"Failed to set MAC address");
3840 
3841 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3842 	TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3843 			sizeof(read_mac_addr)),
3844 			"bonded port (%d) mac address not set to that of new primary port",
3845 			test_params->slave_port_ids[i]);
3846 
3847 
3848 	for (i = 0; i < test_params->bonded_slave_count; i++) {
3849 		rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3850 		TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3851 				sizeof(read_mac_addr)),
3852 				"slave port (%d) mac address not set to that of new primary "
3853 				"port", test_params->slave_port_ids[i]);
3854 	}
3855 
3856 	/* Clean up and remove slaves from bonded device */
3857 	return remove_slaves_and_stop_bonded_device();
3858 }
3859 
3860 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3861 static int
3862 test_broadcast_verify_slave_link_status_change_behaviour(void)
3863 {
3864 	struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3865 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3866 	struct rte_eth_stats port_stats;
3867 
3868 	uint16_t slaves[RTE_MAX_ETHPORTS];
3869 
3870 	int i, burst_size, slave_count;
3871 
3872 	memset(pkt_burst, 0, sizeof(pkt_burst));
3873 
3874 	/* Initialize bonded device with 4 slaves in round robin mode */
3875 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3876 				BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3877 				1), "Failed to initialise bonded device");
3878 
3879 	/* Verify Current Slaves Count /Active Slave Count is */
3880 	slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3881 			RTE_MAX_ETHPORTS);
3882 	TEST_ASSERT_EQUAL(slave_count, 4,
3883 			"Number of slaves (%d) is not as expected (%d).",
3884 			slave_count, 4);
3885 
3886 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3887 			slaves, RTE_MAX_ETHPORTS);
3888 	TEST_ASSERT_EQUAL(slave_count, 4,
3889 			"Number of active slaves (%d) is not as expected (%d).",
3890 			slave_count, 4);
3891 
3892 	/* Set 2 slaves link status to down */
3893 	virtual_ethdev_simulate_link_status_interrupt(
3894 			test_params->slave_port_ids[1], 0);
3895 	virtual_ethdev_simulate_link_status_interrupt(
3896 			test_params->slave_port_ids[3], 0);
3897 
3898 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3899 			slaves, RTE_MAX_ETHPORTS);
3900 	TEST_ASSERT_EQUAL(slave_count, 2,
3901 			"Number of active slaves (%d) is not as expected (%d).",
3902 			slave_count, 2);
3903 
3904 	for (i = 0; i < test_params->bonded_slave_count; i++)
3905 		rte_eth_stats_reset(test_params->slave_port_ids[i]);
3906 
3907 	/* Verify that pkts are not sent on slaves with link status down */
3908 	burst_size = 21;
3909 
3910 	TEST_ASSERT_EQUAL(generate_test_burst(
3911 			&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3912 			"generate_test_burst failed");
3913 
3914 	TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3915 			&pkt_burst[0][0], burst_size), burst_size,
3916 			"rte_eth_tx_burst failed\n");
3917 
3918 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3919 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3920 			"(%d) port_stats.opackets (%d) not as expected (%d)\n",
3921 			test_params->bonded_port_id, (int)port_stats.opackets,
3922 			burst_size * slave_count);
3923 
3924 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3925 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3926 			"(%d) port_stats.opackets not as expected",
3927 			test_params->slave_port_ids[0]);
3928 
3929 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3930 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3931 			"(%d) port_stats.opackets not as expected",
3932 				test_params->slave_port_ids[1]);
3933 
3934 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3935 	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3936 			"(%d) port_stats.opackets not as expected",
3937 				test_params->slave_port_ids[2]);
3938 
3939 
3940 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3941 	TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3942 			"(%d) port_stats.opackets not as expected",
3943 			test_params->slave_port_ids[3]);
3944 
3945 
3946 	for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3947 		TEST_ASSERT_EQUAL(generate_test_burst(
3948 				&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3949 				burst_size, "failed to generate packet burst");
3950 
3951 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3952 				&pkt_burst[i][0], burst_size);
3953 	}
3954 
3955 	/* Verify that pkts are not received on slaves with link status down */
3956 	TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3957 			test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3958 			burst_size + burst_size, "rte_eth_rx_burst failed");
3959 
3960 
3961 	/* Verify bonded device rx count */
3962 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3963 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3964 			"(%d) port_stats.ipackets not as expected\n",
3965 			test_params->bonded_port_id);
3966 
3967 	/* Clean up and remove slaves from bonded device */
3968 	return remove_slaves_and_stop_bonded_device();
3969 }
3970 
3971 static int
3972 test_reconfigure_bonded_device(void)
3973 {
3974 	test_params->nb_rx_q = 4;
3975 	test_params->nb_tx_q = 4;
3976 
3977 	TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3978 			"failed to reconfigure bonded device");
3979 
3980 	test_params->nb_rx_q = 2;
3981 	test_params->nb_tx_q = 2;
3982 
3983 	TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3984 			"failed to reconfigure bonded device with less rx/tx queues");
3985 
3986 	return 0;
3987 }
3988 
3989 
3990 static int
3991 test_close_bonded_device(void)
3992 {
3993 	rte_eth_dev_close(test_params->bonded_port_id);
3994 	return 0;
3995 }
3996 
3997 static void
3998 testsuite_teardown(void)
3999 {
4000 	free(test_params->pkt_eth_hdr);
4001 	test_params->pkt_eth_hdr = NULL;
4002 
4003 	/* Clean up and remove slaves from bonded device */
4004 	remove_slaves_and_stop_bonded_device();
4005 }
4006 
4007 static void
4008 free_virtualpmd_tx_queue(void)
4009 {
4010 	int i, slave_port, to_free_cnt;
4011 	struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4012 
4013 	/* Free tx queue of virtual pmd */
4014 	for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4015 			slave_port++) {
4016 		to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4017 				test_params->slave_port_ids[slave_port],
4018 				pkts_to_free, MAX_PKT_BURST);
4019 		for (i = 0; i < to_free_cnt; i++)
4020 			rte_pktmbuf_free(pkts_to_free[i]);
4021 	}
4022 }
4023 
4024 static int
4025 test_tlb_tx_burst(void)
4026 {
4027 	int i, burst_size, nb_tx;
4028 	uint64_t nb_tx2 = 0;
4029 	struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4030 	struct rte_eth_stats port_stats[32];
4031 	uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4032 	uint16_t pktlen;
4033 
4034 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4035 			(BONDING_MODE_TLB, 1, 3, 1),
4036 			"Failed to initialise bonded device");
4037 
4038 	burst_size = 20 * test_params->bonded_slave_count;
4039 
4040 	TEST_ASSERT(burst_size < MAX_PKT_BURST,
4041 			"Burst size specified is greater than supported.\n");
4042 
4043 
4044 	/* Generate bursts of packets */
4045 	for (i = 0; i < 400000; i++) {
4046 		/*test two types of mac src own(bonding) and others */
4047 		if (i % 2 == 0) {
4048 			initialize_eth_header(test_params->pkt_eth_hdr,
4049 					(struct rte_ether_addr *)src_mac,
4050 					(struct rte_ether_addr *)dst_mac_0,
4051 					RTE_ETHER_TYPE_IPV4, 0, 0);
4052 		} else {
4053 			initialize_eth_header(test_params->pkt_eth_hdr,
4054 					(struct rte_ether_addr *)test_params->default_slave_mac,
4055 					(struct rte_ether_addr *)dst_mac_0,
4056 					RTE_ETHER_TYPE_IPV4, 0, 0);
4057 		}
4058 		pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4059 				dst_port_0, 16);
4060 		pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4061 				dst_addr_0, pktlen);
4062 		generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4063 				test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4064 				1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4065 		/* Send burst on bonded port */
4066 		nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4067 				burst_size);
4068 		nb_tx2 += nb_tx;
4069 
4070 		free_virtualpmd_tx_queue();
4071 
4072 		TEST_ASSERT_EQUAL(nb_tx, burst_size,
4073 				"number of packet not equal burst size");
4074 
4075 		rte_delay_us(5);
4076 	}
4077 
4078 
4079 	/* Verify bonded port tx stats */
4080 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4081 
4082 	all_bond_opackets = port_stats[0].opackets;
4083 	all_bond_obytes = port_stats[0].obytes;
4084 
4085 	TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4086 			"Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4087 			test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4088 			burst_size);
4089 
4090 
4091 	/* Verify slave ports tx stats */
4092 	for (i = 0; i < test_params->bonded_slave_count; i++) {
4093 		rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4094 		sum_ports_opackets += port_stats[i].opackets;
4095 	}
4096 
4097 	TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4098 			"Total packets sent by slaves is not equal to packets sent by bond interface");
4099 
4100 	/* checking if distribution of packets is balanced over slaves */
4101 	for (i = 0; i < test_params->bonded_slave_count; i++) {
4102 		TEST_ASSERT(port_stats[i].obytes > 0 &&
4103 				port_stats[i].obytes < all_bond_obytes,
4104 						"Packets are not balanced over slaves");
4105 	}
4106 
4107 	/* Put all slaves down and try and transmit */
4108 	for (i = 0; i < test_params->bonded_slave_count; i++) {
4109 		virtual_ethdev_simulate_link_status_interrupt(
4110 				test_params->slave_port_ids[i], 0);
4111 	}
4112 
4113 	/* Send burst on bonded port */
4114 	nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4115 			burst_size);
4116 	TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4117 
4118 	/* Clean ugit checkout masterp and remove slaves from bonded device */
4119 	return remove_slaves_and_stop_bonded_device();
4120 }
4121 
4122 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4123 
4124 static int
4125 test_tlb_rx_burst(void)
4126 {
4127 	struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4128 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4129 
4130 	struct rte_eth_stats port_stats;
4131 
4132 	int primary_port;
4133 
4134 	uint16_t i, j, nb_rx, burst_size = 17;
4135 
4136 	/* Initialize bonded device with 4 slaves in transmit load balancing mode */
4137 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4138 			BONDING_MODE_TLB,
4139 			TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4140 			"Failed to initialize bonded device");
4141 
4142 
4143 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4144 	TEST_ASSERT(primary_port >= 0,
4145 			"failed to get primary slave for bonded port (%d)",
4146 			test_params->bonded_port_id);
4147 
4148 	for (i = 0; i < test_params->bonded_slave_count; i++) {
4149 		/* Generate test bursts of packets to transmit */
4150 		TEST_ASSERT_EQUAL(generate_test_burst(
4151 				&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4152 				"burst generation failed");
4153 
4154 		/* Add rx data to slave */
4155 		virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4156 				&gen_pkt_burst[0], burst_size);
4157 
4158 		/* Call rx burst on bonded device */
4159 		nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4160 				&rx_pkt_burst[0], MAX_PKT_BURST);
4161 
4162 		TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4163 
4164 		if (test_params->slave_port_ids[i] == primary_port) {
4165 			/* Verify bonded device rx count */
4166 			rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4167 			TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4168 					"Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4169 					test_params->bonded_port_id,
4170 					(unsigned int)port_stats.ipackets, burst_size);
4171 
4172 			/* Verify bonded slave devices rx count */
4173 			for (j = 0; j < test_params->bonded_slave_count; j++) {
4174 				rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4175 				if (i == j) {
4176 					TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4177 							"Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4178 							test_params->slave_port_ids[i],
4179 							(unsigned int)port_stats.ipackets, burst_size);
4180 				} else {
4181 					TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4182 							"Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4183 							test_params->slave_port_ids[i],
4184 							(unsigned int)port_stats.ipackets, 0);
4185 				}
4186 			}
4187 		} else {
4188 			for (j = 0; j < test_params->bonded_slave_count; j++) {
4189 				rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4190 				TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4191 						"Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4192 						test_params->slave_port_ids[i],
4193 						(unsigned int)port_stats.ipackets, 0);
4194 			}
4195 		}
4196 
4197 		/* free mbufs */
4198 		for (i = 0; i < burst_size; i++)
4199 			rte_pktmbuf_free(rx_pkt_burst[i]);
4200 
4201 		/* reset bonded device stats */
4202 		rte_eth_stats_reset(test_params->bonded_port_id);
4203 	}
4204 
4205 	/* Clean up and remove slaves from bonded device */
4206 	return remove_slaves_and_stop_bonded_device();
4207 }
4208 
4209 static int
4210 test_tlb_verify_promiscuous_enable_disable(void)
4211 {
4212 	int i, primary_port, promiscuous_en;
4213 	int ret;
4214 
4215 	/* Initialize bonded device with 4 slaves in transmit load balancing mode */
4216 	TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4217 			BONDING_MODE_TLB, 0, 4, 1),
4218 			"Failed to initialize bonded device");
4219 
4220 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4221 	TEST_ASSERT(primary_port >= 0,
4222 			"failed to get primary slave for bonded port (%d)",
4223 			test_params->bonded_port_id);
4224 
4225 	ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
4226 	TEST_ASSERT_SUCCESS(ret,
4227 		"Failed to enable promiscuous mode for port %d: %s",
4228 		test_params->bonded_port_id, rte_strerror(-ret));
4229 
4230 	promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4231 	TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4232 			"Port (%d) promiscuous mode not enabled\n",
4233 			test_params->bonded_port_id);
4234 	for (i = 0; i < test_params->bonded_slave_count; i++) {
4235 		promiscuous_en = rte_eth_promiscuous_get(
4236 				test_params->slave_port_ids[i]);
4237 		if (primary_port == test_params->slave_port_ids[i]) {
4238 			TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4239 					"Port (%d) promiscuous mode not enabled\n",
4240 					test_params->bonded_port_id);
4241 		} else {
4242 			TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4243 					"Port (%d) promiscuous mode enabled\n",
4244 					test_params->bonded_port_id);
4245 		}
4246 
4247 	}
4248 
4249 	ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
4250 	TEST_ASSERT_SUCCESS(ret,
4251 		"Failed to disable promiscuous mode for port %d: %s\n",
4252 		test_params->bonded_port_id, rte_strerror(-ret));
4253 
4254 	promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4255 	TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4256 			"Port (%d) promiscuous mode not disabled\n",
4257 			test_params->bonded_port_id);
4258 
4259 	for (i = 0; i < test_params->bonded_slave_count; i++) {
4260 		promiscuous_en = rte_eth_promiscuous_get(
4261 				test_params->slave_port_ids[i]);
4262 		TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4263 				"slave port (%d) promiscuous mode not disabled\n",
4264 				test_params->slave_port_ids[i]);
4265 	}
4266 
4267 	/* Clean up and remove slaves from bonded device */
4268 	return remove_slaves_and_stop_bonded_device();
4269 }
4270 
4271 static int
4272 test_tlb_verify_mac_assignment(void)
4273 {
4274 	struct rte_ether_addr read_mac_addr;
4275 	struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
4276 
4277 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4278 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4279 
4280 	/* Initialize bonded device with 2 slaves in active backup mode */
4281 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4282 			BONDING_MODE_TLB, 0, 2, 1),
4283 			"Failed to initialize bonded device");
4284 
4285 	/* Verify that bonded MACs is that of first slave and that the other slave
4286 	 * MAC hasn't been changed */
4287 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4288 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4289 			sizeof(read_mac_addr)),
4290 			"bonded port (%d) mac address not set to that of primary port",
4291 			test_params->bonded_port_id);
4292 
4293 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4294 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4295 			sizeof(read_mac_addr)),
4296 			"slave port (%d) mac address not set to that of primary port",
4297 			test_params->slave_port_ids[0]);
4298 
4299 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4300 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4301 			sizeof(read_mac_addr)),
4302 			"slave port (%d) mac address not as expected",
4303 			test_params->slave_port_ids[1]);
4304 
4305 	/* change primary and verify that MAC addresses haven't changed */
4306 	TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4307 			test_params->slave_port_ids[1]), 0,
4308 			"Failed to set bonded port (%d) primary port to (%d)",
4309 			test_params->bonded_port_id, test_params->slave_port_ids[1]);
4310 
4311 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4312 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4313 			sizeof(read_mac_addr)),
4314 			"bonded port (%d) mac address not set to that of primary port",
4315 			test_params->bonded_port_id);
4316 
4317 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4318 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4319 			sizeof(read_mac_addr)),
4320 			"slave port (%d) mac address not set to that of primary port",
4321 			test_params->slave_port_ids[0]);
4322 
4323 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4324 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4325 			sizeof(read_mac_addr)),
4326 			"slave port (%d) mac address not as expected",
4327 			test_params->slave_port_ids[1]);
4328 
4329 	/* stop / start bonded device and verify that primary MAC address is
4330 	 * propagated to bonded device and slaves */
4331 
4332 	rte_eth_dev_stop(test_params->bonded_port_id);
4333 
4334 	TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4335 			"Failed to start device");
4336 
4337 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4338 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4339 			sizeof(read_mac_addr)),
4340 			"bonded port (%d) mac address not set to that of primary port",
4341 			test_params->bonded_port_id);
4342 
4343 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4344 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4345 			sizeof(read_mac_addr)),
4346 			"slave port (%d) mac address not as expected",
4347 			test_params->slave_port_ids[0]);
4348 
4349 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4350 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4351 			sizeof(read_mac_addr)),
4352 			"slave port (%d) mac address not set to that of primary port",
4353 			test_params->slave_port_ids[1]);
4354 
4355 
4356 	/* Set explicit MAC address */
4357 	TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4358 			test_params->bonded_port_id,
4359 			(struct rte_ether_addr *)bonded_mac),
4360 			"failed to set MAC address");
4361 
4362 	rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4363 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4364 			sizeof(read_mac_addr)),
4365 			"bonded port (%d) mac address not set to that of bonded port",
4366 			test_params->bonded_port_id);
4367 
4368 	rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4369 	TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4370 			sizeof(read_mac_addr)),
4371 			"slave port (%d) mac address not as expected",
4372 			test_params->slave_port_ids[0]);
4373 
4374 	rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4375 	TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4376 			sizeof(read_mac_addr)),
4377 			"slave port (%d) mac address not set to that of bonded port",
4378 			test_params->slave_port_ids[1]);
4379 
4380 	/* Clean up and remove slaves from bonded device */
4381 	return remove_slaves_and_stop_bonded_device();
4382 }
4383 
4384 static int
4385 test_tlb_verify_slave_link_status_change_failover(void)
4386 {
4387 	struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4388 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4389 	struct rte_eth_stats port_stats;
4390 
4391 	uint16_t slaves[RTE_MAX_ETHPORTS];
4392 
4393 	int i, burst_size, slave_count, primary_port;
4394 
4395 	burst_size = 21;
4396 
4397 	memset(pkt_burst, 0, sizeof(pkt_burst));
4398 
4399 
4400 
4401 	/* Initialize bonded device with 4 slaves in round robin mode */
4402 	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4403 			BONDING_MODE_TLB, 0,
4404 			TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4405 			"Failed to initialize bonded device with slaves");
4406 
4407 	/* Verify Current Slaves Count /Active Slave Count is */
4408 	slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4409 			RTE_MAX_ETHPORTS);
4410 	TEST_ASSERT_EQUAL(slave_count, 4,
4411 			"Number of slaves (%d) is not as expected (%d).\n",
4412 			slave_count, 4);
4413 
4414 	slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4415 			slaves, RTE_MAX_ETHPORTS);
4416 	TEST_ASSERT_EQUAL(slave_count, (int)4,
4417 			"Number of slaves (%d) is not as expected (%d).\n",
4418 			slave_count, 4);
4419 
4420 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4421 	TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4422 			"Primary port not as expected");
4423 
4424 	/* Bring 2 slaves down and verify active slave count */
4425 	virtual_ethdev_simulate_link_status_interrupt(
4426 			test_params->slave_port_ids[1], 0);
4427 	virtual_ethdev_simulate_link_status_interrupt(
4428 			test_params->slave_port_ids[3], 0);
4429 
4430 	TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4431 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4432 			"Number of active slaves (%d) is not as expected (%d).",
4433 			slave_count, 2);
4434 
4435 	virtual_ethdev_simulate_link_status_interrupt(
4436 			test_params->slave_port_ids[1], 1);
4437 	virtual_ethdev_simulate_link_status_interrupt(
4438 			test_params->slave_port_ids[3], 1);
4439 
4440 
4441 	/* Bring primary port down, verify that active slave count is 3 and primary
4442 	 *  has changed */
4443 	virtual_ethdev_simulate_link_status_interrupt(
4444 			test_params->slave_port_ids[0], 0);
4445 
4446 	TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4447 			test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4448 			"Number of active slaves (%d) is not as expected (%d).",
4449 			slave_count, 3);
4450 
4451 	primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4452 	TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4453 			"Primary port not as expected");
4454 	rte_delay_us(500000);
4455 	/* Verify that pkts are sent on new primary slave */
4456 	for (i = 0; i < 4; i++) {
4457 		TEST_ASSERT_EQUAL(generate_test_burst(
4458 				&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4459 				"generate_test_burst failed\n");
4460 		TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4461 				test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4462 				"rte_eth_tx_burst failed\n");
4463 		rte_delay_us(11000);
4464 	}
4465 
4466 	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4467 	TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4468 			"(%d) port_stats.opackets not as expected\n",
4469 			test_params->slave_port_ids[0]);
4470 
4471 	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4472 	TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4473 			"(%d) port_stats.opackets not as expected\n",
4474 			test_params->slave_port_ids[1]);
4475 
4476 	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4477 	TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4478 			"(%d) port_stats.opackets not as expected\n",
4479 			test_params->slave_port_ids[2]);
4480 
4481 	rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4482 	TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4483 			"(%d) port_stats.opackets not as expected\n",
4484 			test_params->slave_port_ids[3]);
4485 
4486 
4487 	/* Generate packet burst for testing */
4488 
4489 	for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4490 		if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4491 				burst_size)
4492 			return -1;
4493 
4494 		virtual_ethdev_add_mbufs_to_rx_queue(
4495 				test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4496 	}
4497 
4498 	if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4499 			MAX_PKT_BURST) != burst_size) {
4500 		printf("rte_eth_rx_burst\n");
4501 		return -1;
4502 
4503 	}
4504 
4505 	/* Verify bonded device rx count */
4506 	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4507 	TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4508 			"(%d) port_stats.ipackets not as expected\n",
4509 			test_params->bonded_port_id);
4510 
4511 	/* Clean up and remove slaves from bonded device */
4512 	return remove_slaves_and_stop_bonded_device();
4513 }
4514 
4515 #define TEST_ALB_SLAVE_COUNT	2
4516 
4517 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4518 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4519 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4520 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4521 
4522 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4523 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4524 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4525 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4526 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4527 
4528 static int
4529 test_alb_change_mac_in_reply_sent(void)
4530 {
4531 	struct rte_mbuf *pkt;
4532 	struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4533 
4534 	struct rte_ether_hdr *eth_pkt;
4535 	struct rte_arp_hdr *arp_pkt;
4536 
4537 	int slave_idx, nb_pkts, pkt_idx;
4538 	int retval = 0;
4539 
4540 	struct rte_ether_addr bond_mac, client_mac;
4541 	struct rte_ether_addr *slave_mac1, *slave_mac2;
4542 
4543 	TEST_ASSERT_SUCCESS(
4544 			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4545 					0, TEST_ALB_SLAVE_COUNT, 1),
4546 			"Failed to initialize_bonded_device_with_slaves.");
4547 
4548 	/* Flush tx queue */
4549 	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4550 	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4551 			slave_idx++) {
4552 		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4553 				test_params->slave_port_ids[slave_idx], pkts_sent,
4554 				MAX_PKT_BURST);
4555 	}
4556 
4557 	rte_ether_addr_copy(
4558 			rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4559 			&bond_mac);
4560 
4561 	/*
4562 	 * Generating four packets with different mac and ip addresses and sending
4563 	 * them through the bonding port.
4564 	 */
4565 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4566 	memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4567 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4568 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4569 			RTE_ETHER_TYPE_ARP, 0, 0);
4570 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4571 					sizeof(struct rte_ether_hdr));
4572 	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4573 			RTE_ARP_OP_REPLY);
4574 	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4575 
4576 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4577 	memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4578 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4579 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4580 			RTE_ETHER_TYPE_ARP, 0, 0);
4581 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4582 					sizeof(struct rte_ether_hdr));
4583 	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4584 			RTE_ARP_OP_REPLY);
4585 	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4586 
4587 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4588 	memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4589 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4590 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4591 			RTE_ETHER_TYPE_ARP, 0, 0);
4592 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4593 					sizeof(struct rte_ether_hdr));
4594 	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4595 			RTE_ARP_OP_REPLY);
4596 	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4597 
4598 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4599 	memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4600 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4601 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4602 			RTE_ETHER_TYPE_ARP, 0, 0);
4603 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4604 					sizeof(struct rte_ether_hdr));
4605 	initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4606 			RTE_ARP_OP_REPLY);
4607 	rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4608 
4609 	slave_mac1 =
4610 			rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4611 	slave_mac2 =
4612 			rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4613 
4614 	/*
4615 	 * Checking if packets are properly distributed on bonding ports. Packets
4616 	 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4617 	 */
4618 	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4619 		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4620 				test_params->slave_port_ids[slave_idx], pkts_sent,
4621 				MAX_PKT_BURST);
4622 
4623 		for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4624 			eth_pkt = rte_pktmbuf_mtod(
4625 				pkts_sent[pkt_idx], struct rte_ether_hdr *);
4626 			arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4627 						sizeof(struct rte_ether_hdr));
4628 
4629 			if (slave_idx%2 == 0) {
4630 				if (!rte_is_same_ether_addr(slave_mac1,
4631 						&arp_pkt->arp_data.arp_sha)) {
4632 					retval = -1;
4633 					goto test_end;
4634 				}
4635 			} else {
4636 				if (!rte_is_same_ether_addr(slave_mac2,
4637 						&arp_pkt->arp_data.arp_sha)) {
4638 					retval = -1;
4639 					goto test_end;
4640 				}
4641 			}
4642 		}
4643 	}
4644 
4645 test_end:
4646 	retval += remove_slaves_and_stop_bonded_device();
4647 	return retval;
4648 }
4649 
4650 static int
4651 test_alb_reply_from_client(void)
4652 {
4653 	struct rte_ether_hdr *eth_pkt;
4654 	struct rte_arp_hdr *arp_pkt;
4655 
4656 	struct rte_mbuf *pkt;
4657 	struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4658 
4659 	int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4660 	int retval = 0;
4661 
4662 	struct rte_ether_addr bond_mac, client_mac;
4663 	struct rte_ether_addr *slave_mac1, *slave_mac2;
4664 
4665 	TEST_ASSERT_SUCCESS(
4666 			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4667 					0, TEST_ALB_SLAVE_COUNT, 1),
4668 			"Failed to initialize_bonded_device_with_slaves.");
4669 
4670 	/* Flush tx queue */
4671 	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4672 	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4673 		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4674 				test_params->slave_port_ids[slave_idx], pkts_sent,
4675 				MAX_PKT_BURST);
4676 	}
4677 
4678 	rte_ether_addr_copy(
4679 			rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4680 			&bond_mac);
4681 
4682 	/*
4683 	 * Generating four packets with different mac and ip addresses and placing
4684 	 * them in the rx queue to be received by the bonding driver on rx_burst.
4685 	 */
4686 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4687 	memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4688 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4689 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4690 			RTE_ETHER_TYPE_ARP, 0, 0);
4691 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4692 					sizeof(struct rte_ether_hdr));
4693 	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4694 			RTE_ARP_OP_REPLY);
4695 	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4696 			1);
4697 
4698 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4699 	memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4700 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4701 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4702 			RTE_ETHER_TYPE_ARP, 0, 0);
4703 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4704 					sizeof(struct rte_ether_hdr));
4705 	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4706 			RTE_ARP_OP_REPLY);
4707 	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4708 			1);
4709 
4710 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4711 	memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4712 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4713 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4714 			RTE_ETHER_TYPE_ARP, 0, 0);
4715 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4716 					sizeof(struct rte_ether_hdr));
4717 	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4718 			RTE_ARP_OP_REPLY);
4719 	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4720 			1);
4721 
4722 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4723 	memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4724 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4725 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4726 			RTE_ETHER_TYPE_ARP, 0, 0);
4727 	arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4728 					sizeof(struct rte_ether_hdr));
4729 	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4730 			RTE_ARP_OP_REPLY);
4731 	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4732 			1);
4733 
4734 	/*
4735 	 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4736 	 * packets to every client in alb table.
4737 	 */
4738 	rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4739 	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4740 
4741 	slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4742 	slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4743 
4744 	/*
4745 	 * Checking if update ARP packets were properly send on slave ports.
4746 	 */
4747 	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4748 		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4749 				test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4750 		nb_pkts_sum += nb_pkts;
4751 
4752 		for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4753 			eth_pkt = rte_pktmbuf_mtod(
4754 				pkts_sent[pkt_idx], struct rte_ether_hdr *);
4755 			arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4756 						sizeof(struct rte_ether_hdr));
4757 
4758 			if (slave_idx%2 == 0) {
4759 				if (!rte_is_same_ether_addr(slave_mac1,
4760 						&arp_pkt->arp_data.arp_sha)) {
4761 					retval = -1;
4762 					goto test_end;
4763 				}
4764 			} else {
4765 				if (!rte_is_same_ether_addr(slave_mac2,
4766 						&arp_pkt->arp_data.arp_sha)) {
4767 					retval = -1;
4768 					goto test_end;
4769 				}
4770 			}
4771 		}
4772 	}
4773 
4774 	/* Check if proper number of packets was send */
4775 	if (nb_pkts_sum < 4) {
4776 		retval = -1;
4777 		goto test_end;
4778 	}
4779 
4780 test_end:
4781 	retval += remove_slaves_and_stop_bonded_device();
4782 	return retval;
4783 }
4784 
4785 static int
4786 test_alb_receive_vlan_reply(void)
4787 {
4788 	struct rte_ether_hdr *eth_pkt;
4789 	struct rte_vlan_hdr *vlan_pkt;
4790 	struct rte_arp_hdr *arp_pkt;
4791 
4792 	struct rte_mbuf *pkt;
4793 	struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4794 
4795 	int slave_idx, nb_pkts, pkt_idx;
4796 	int retval = 0;
4797 
4798 	struct rte_ether_addr bond_mac, client_mac;
4799 
4800 	TEST_ASSERT_SUCCESS(
4801 			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4802 					0, TEST_ALB_SLAVE_COUNT, 1),
4803 			"Failed to initialize_bonded_device_with_slaves.");
4804 
4805 	/* Flush tx queue */
4806 	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4807 	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4808 		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4809 				test_params->slave_port_ids[slave_idx], pkts_sent,
4810 				MAX_PKT_BURST);
4811 	}
4812 
4813 	rte_ether_addr_copy(
4814 			rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4815 			&bond_mac);
4816 
4817 	/*
4818 	 * Generating packet with double VLAN header and placing it in the rx queue.
4819 	 */
4820 	pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4821 	memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4822 	eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4823 	initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4824 			RTE_ETHER_TYPE_VLAN, 0, 0);
4825 	vlan_pkt = (struct rte_vlan_hdr *)((char *)(eth_pkt + 1));
4826 	vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4827 	vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4828 	vlan_pkt = vlan_pkt+1;
4829 	vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4830 	vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
4831 	arp_pkt = (struct rte_arp_hdr *)((char *)(vlan_pkt + 1));
4832 	initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4833 			RTE_ARP_OP_REPLY);
4834 	virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4835 			1);
4836 
4837 	rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4838 	rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4839 
4840 	/*
4841 	 * Checking if VLAN headers in generated ARP Update packet are correct.
4842 	 */
4843 	for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4844 		nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4845 				test_params->slave_port_ids[slave_idx], pkts_sent,
4846 				MAX_PKT_BURST);
4847 
4848 		for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4849 			eth_pkt = rte_pktmbuf_mtod(
4850 				pkts_sent[pkt_idx], struct rte_ether_hdr *);
4851 			vlan_pkt = (struct rte_vlan_hdr *)(
4852 				(char *)(eth_pkt + 1));
4853 			if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4854 				retval = -1;
4855 				goto test_end;
4856 			}
4857 			if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
4858 					RTE_ETHER_TYPE_VLAN)) {
4859 				retval = -1;
4860 				goto test_end;
4861 			}
4862 			vlan_pkt = vlan_pkt+1;
4863 			if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4864 				retval = -1;
4865 				goto test_end;
4866 			}
4867 			if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
4868 					RTE_ETHER_TYPE_ARP)) {
4869 				retval = -1;
4870 				goto test_end;
4871 			}
4872 		}
4873 	}
4874 
4875 test_end:
4876 	retval += remove_slaves_and_stop_bonded_device();
4877 	return retval;
4878 }
4879 
4880 static int
4881 test_alb_ipv4_tx(void)
4882 {
4883 	int burst_size, retval, pkts_send;
4884 	struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4885 
4886 	retval = 0;
4887 
4888 	TEST_ASSERT_SUCCESS(
4889 			initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4890 					0, TEST_ALB_SLAVE_COUNT, 1),
4891 			"Failed to initialize_bonded_device_with_slaves.");
4892 
4893 	burst_size = 32;
4894 
4895 	/* Generate test bursts of packets to transmit */
4896 	if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4897 		retval = -1;
4898 		goto test_end;
4899 	}
4900 
4901 	/*
4902 	 * Checking if ipv4 traffic is transmitted via TLB policy.
4903 	 */
4904 	pkts_send = rte_eth_tx_burst(
4905 			test_params->bonded_port_id, 0, pkt_burst, burst_size);
4906 	if (pkts_send != burst_size) {
4907 		retval = -1;
4908 		goto test_end;
4909 	}
4910 
4911 test_end:
4912 	retval += remove_slaves_and_stop_bonded_device();
4913 	return retval;
4914 }
4915 
4916 static struct unit_test_suite link_bonding_test_suite  = {
4917 	.suite_name = "Link Bonding Unit Test Suite",
4918 	.setup = test_setup,
4919 	.teardown = testsuite_teardown,
4920 	.unit_test_cases = {
4921 		TEST_CASE(test_create_bonded_device),
4922 		TEST_CASE(test_create_bonded_device_with_invalid_params),
4923 		TEST_CASE(test_add_slave_to_bonded_device),
4924 		TEST_CASE(test_add_slave_to_invalid_bonded_device),
4925 		TEST_CASE(test_remove_slave_from_bonded_device),
4926 		TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4927 		TEST_CASE(test_get_slaves_from_bonded_device),
4928 		TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4929 		TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4930 		TEST_CASE(test_start_bonded_device),
4931 		TEST_CASE(test_stop_bonded_device),
4932 		TEST_CASE(test_set_bonding_mode),
4933 		TEST_CASE(test_set_primary_slave),
4934 		TEST_CASE(test_set_explicit_bonded_mac),
4935 		TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4936 		TEST_CASE(test_status_interrupt),
4937 		TEST_CASE(test_adding_slave_after_bonded_device_started),
4938 		TEST_CASE(test_roundrobin_tx_burst),
4939 		TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4940 		TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4941 		TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4942 		TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4943 		TEST_CASE(test_roundrobin_verify_mac_assignment),
4944 		TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4945 		TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4946 		TEST_CASE(test_activebackup_tx_burst),
4947 		TEST_CASE(test_activebackup_rx_burst),
4948 		TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4949 		TEST_CASE(test_activebackup_verify_mac_assignment),
4950 		TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4951 		TEST_CASE(test_balance_xmit_policy_configuration),
4952 		TEST_CASE(test_balance_l2_tx_burst),
4953 		TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4954 		TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4955 		TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4956 		TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4957 		TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4958 		TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4959 		TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4960 		TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4961 		TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4962 		TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4963 		TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4964 		TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4965 		TEST_CASE(test_balance_rx_burst),
4966 		TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4967 		TEST_CASE(test_balance_verify_mac_assignment),
4968 		TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4969 		TEST_CASE(test_tlb_tx_burst),
4970 		TEST_CASE(test_tlb_rx_burst),
4971 		TEST_CASE(test_tlb_verify_mac_assignment),
4972 		TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4973 		TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4974 		TEST_CASE(test_alb_change_mac_in_reply_sent),
4975 		TEST_CASE(test_alb_reply_from_client),
4976 		TEST_CASE(test_alb_receive_vlan_reply),
4977 		TEST_CASE(test_alb_ipv4_tx),
4978 		TEST_CASE(test_broadcast_tx_burst),
4979 		TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4980 		TEST_CASE(test_broadcast_rx_burst),
4981 		TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4982 		TEST_CASE(test_broadcast_verify_mac_assignment),
4983 		TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4984 		TEST_CASE(test_reconfigure_bonded_device),
4985 		TEST_CASE(test_close_bonded_device),
4986 
4987 		TEST_CASES_END() /**< NULL terminate unit test array */
4988 	}
4989 };
4990 
4991 
4992 static int
4993 test_link_bonding(void)
4994 {
4995 	return unit_test_suite_runner(&link_bonding_test_suite);
4996 }
4997 
4998 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);
4999