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