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