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