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