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