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