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