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