1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
13 #include <sys/queue.h>
15 #include <rte_cycles.h>
16 #include <rte_byteorder.h>
17 #include <rte_common.h>
18 #include <rte_debug.h>
19 #include <rte_ethdev.h>
20 #include <rte_ethdev_driver.h>
22 #include <rte_lcore.h>
23 #include <rte_memory.h>
24 #include <rte_string_fns.h>
25 #include <rte_eth_bond.h>
27 #include "virtual_pmd.h"
28 #include "packet_burst_generator.h"
32 #define TEST_MAX_NUMBER_OF_PORTS (6)
34 #define RX_RING_SIZE 128
35 #define RX_FREE_THRESH 32
40 #define TX_RING_SIZE 512
41 #define TX_FREE_THRESH 32
45 #define TX_RSBIT_THRESH 32
46 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
47 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
48 ETH_TXQ_FLAGS_NOXSUMTCP)
50 #define MBUF_CACHE_SIZE (250)
51 #define BURST_SIZE (32)
53 #define RTE_TEST_RX_DESC_MAX (2048)
54 #define RTE_TEST_TX_DESC_MAX (2048)
55 #define MAX_PKT_BURST (512)
56 #define DEF_PKT_BURST (16)
58 #define BONDED_DEV_NAME ("net_bonding_ut")
60 #define INVALID_SOCKET_ID (-1)
61 #define INVALID_PORT_ID (-1)
62 #define INVALID_BONDING_MODE (-1)
65 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
66 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
68 struct link_bonding_unittest_params {
69 int16_t bonded_port_id;
70 int16_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
71 uint16_t bonded_slave_count;
77 struct rte_mempool *mbuf_pool;
79 struct ether_addr *default_slave_mac;
80 struct ether_addr *default_bonded_mac;
83 struct ether_hdr *pkt_eth_hdr;
84 struct ipv4_hdr *pkt_ipv4_hdr;
85 struct ipv6_hdr *pkt_ipv6_hdr;
86 struct udp_hdr *pkt_udp_hdr;
90 static struct ipv4_hdr pkt_ipv4_hdr;
91 static struct ipv6_hdr pkt_ipv6_hdr;
92 static struct udp_hdr pkt_udp_hdr;
94 static struct link_bonding_unittest_params default_params = {
96 .slave_port_ids = { -1 },
97 .bonded_slave_count = 0,
98 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
105 .default_slave_mac = (struct ether_addr *)slave_mac,
106 .default_bonded_mac = (struct ether_addr *)bonded_mac,
109 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
110 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
111 .pkt_udp_hdr = &pkt_udp_hdr
115 static struct link_bonding_unittest_params *test_params = &default_params;
117 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
118 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
119 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
121 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
122 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
123 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
125 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
126 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
127 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
128 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
129 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
130 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
132 static uint16_t src_port = 1024;
133 static uint16_t dst_port_0 = 1024;
134 static uint16_t dst_port_1 = 2024;
136 static uint16_t vlan_id = 0x100;
138 struct rte_eth_rxmode rx_mode = {
139 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
141 .header_split = 0, /**< Header Split disabled. */
142 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
143 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
144 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
145 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
146 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
147 .hw_strip_crc = 1, /**< CRC stripping by hardware enabled. */
150 struct rte_fdir_conf fdir_conf = {
151 .mode = RTE_FDIR_MODE_NONE,
152 .pballoc = RTE_FDIR_PBALLOC_64K,
153 .status = RTE_FDIR_REPORT_STATUS,
157 static struct rte_eth_conf default_pmd_conf = {
159 .mq_mode = ETH_MQ_RX_NONE,
160 .max_rx_pkt_len = ETHER_MAX_LEN,
162 .header_split = 0, /**< Header Split disabled */
163 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
164 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
165 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
166 .hw_strip_crc = 1, /**< CRC stripped by hardware */
169 .mq_mode = ETH_MQ_TX_NONE,
174 static const struct rte_eth_rxconf rx_conf_default = {
176 .pthresh = RX_PTHRESH,
177 .hthresh = RX_HTHRESH,
178 .wthresh = RX_WTHRESH,
180 .rx_free_thresh = RX_FREE_THRESH,
184 static struct rte_eth_txconf tx_conf_default = {
186 .pthresh = TX_PTHRESH,
187 .hthresh = TX_HTHRESH,
188 .wthresh = TX_WTHRESH,
190 .tx_free_thresh = TX_FREE_THRESH,
191 .tx_rs_thresh = TX_RSBIT_THRESH,
192 .txq_flags = TX_Q_FLAGS
196 static void free_virtualpmd_tx_queue(void);
201 configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
206 default_pmd_conf.intr_conf.lsc = 1;
208 default_pmd_conf.intr_conf.lsc = 0;
210 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
211 test_params->nb_tx_q, &default_pmd_conf),
212 "rte_eth_dev_configure for port %d failed", port_id);
214 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
215 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
216 rte_eth_dev_socket_id(port_id), &rx_conf_default,
217 test_params->mbuf_pool) ,
218 "rte_eth_rx_queue_setup for port %d failed", port_id);
220 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
221 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
222 rte_eth_dev_socket_id(port_id), &tx_conf_default),
223 "rte_eth_tx_queue_setup for port %d failed", port_id);
226 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
227 "rte_eth_dev_start for port %d failed", port_id);
232 static int slaves_initialized;
234 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
235 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
241 int i, nb_mbuf_per_pool;
242 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
244 /* Allocate ethernet packet header with space for VLAN header */
245 if (test_params->pkt_eth_hdr == NULL) {
246 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
247 sizeof(struct vlan_hdr));
249 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
250 "Ethernet header struct allocation failed!");
253 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
254 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
255 if (test_params->mbuf_pool == NULL) {
256 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
257 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
258 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
259 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
260 "rte_mempool_create failed");
263 /* Create / Initialize virtual eth devs */
264 if (!slaves_initialized) {
265 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
266 char pmd_name[RTE_ETH_NAME_MAX_LEN];
268 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
270 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
272 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
273 mac_addr, rte_socket_id(), 1);
274 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
275 "Failed to create virtual virtual ethdev %s", pmd_name);
277 TEST_ASSERT_SUCCESS(configure_ethdev(
278 test_params->slave_port_ids[i], 1, 0),
279 "Failed to configure virtual ethdev %s", pmd_name);
281 slaves_initialized = 1;
288 test_create_bonded_device(void)
290 int current_slave_count;
292 uint16_t slaves[RTE_MAX_ETHPORTS];
294 /* Don't try to recreate bonded device if re-running test suite*/
295 if (test_params->bonded_port_id == -1) {
296 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
297 test_params->bonding_mode, rte_socket_id());
299 TEST_ASSERT(test_params->bonded_port_id >= 0,
300 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
302 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
303 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
306 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
307 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
308 test_params->bonded_port_id, test_params->bonding_mode);
310 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
311 slaves, RTE_MAX_ETHPORTS);
313 TEST_ASSERT_EQUAL(current_slave_count, 0,
314 "Number of slaves %d is great than expected %d.",
315 current_slave_count, 0);
317 current_slave_count = rte_eth_bond_active_slaves_get(
318 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
320 TEST_ASSERT_EQUAL(current_slave_count, 0,
321 "Number of active slaves %d is great than expected %d.",
322 current_slave_count, 0);
329 test_create_bonded_device_with_invalid_params(void)
333 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
336 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
338 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
340 test_params->bonding_mode = INVALID_BONDING_MODE;
342 /* Invalid bonding mode */
343 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
345 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
347 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
349 /* Invalid socket id */
350 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
352 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
358 test_add_slave_to_bonded_device(void)
360 int current_slave_count;
362 uint16_t slaves[RTE_MAX_ETHPORTS];
364 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
365 test_params->slave_port_ids[test_params->bonded_slave_count]),
366 "Failed to add slave (%d) to bonded port (%d).",
367 test_params->slave_port_ids[test_params->bonded_slave_count],
368 test_params->bonded_port_id);
370 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
371 slaves, RTE_MAX_ETHPORTS);
372 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
373 "Number of slaves (%d) is greater than expected (%d).",
374 current_slave_count, test_params->bonded_slave_count + 1);
376 current_slave_count = rte_eth_bond_active_slaves_get(
377 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
378 TEST_ASSERT_EQUAL(current_slave_count, 0,
379 "Number of active slaves (%d) is not as expected (%d).\n",
380 current_slave_count, 0);
382 test_params->bonded_slave_count++;
388 test_add_slave_to_invalid_bonded_device(void)
390 /* Invalid port ID */
391 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
392 test_params->slave_port_ids[test_params->bonded_slave_count]),
393 "Expected call to failed as invalid port specified.");
395 /* Non bonded device */
396 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
397 test_params->slave_port_ids[test_params->bonded_slave_count]),
398 "Expected call to failed as invalid port specified.");
405 test_remove_slave_from_bonded_device(void)
407 int current_slave_count;
408 struct ether_addr read_mac_addr, *mac_addr;
409 uint16_t slaves[RTE_MAX_ETHPORTS];
411 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
412 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
413 "Failed to remove slave %d from bonded port (%d).",
414 test_params->slave_port_ids[test_params->bonded_slave_count-1],
415 test_params->bonded_port_id);
418 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
419 slaves, RTE_MAX_ETHPORTS);
421 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
422 "Number of slaves (%d) is great than expected (%d).\n",
423 current_slave_count, test_params->bonded_slave_count - 1);
426 mac_addr = (struct ether_addr *)slave_mac;
427 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
428 test_params->bonded_slave_count-1;
431 test_params->slave_port_ids[test_params->bonded_slave_count-1],
433 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
434 "bonded port mac address not set to that of primary port\n");
437 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
439 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
442 test_params->bonded_slave_count--;
448 test_remove_slave_from_invalid_bonded_device(void)
450 /* Invalid port ID */
451 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
452 test_params->bonded_port_id + 5,
453 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
454 "Expected call to failed as invalid port specified.");
456 /* Non bonded device */
457 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
458 test_params->slave_port_ids[0],
459 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
460 "Expected call to failed as invalid port specified.");
465 static int bonded_id = 2;
468 test_add_already_bonded_slave_to_bonded_device(void)
470 int port_id, current_slave_count;
471 uint16_t slaves[RTE_MAX_ETHPORTS];
472 char pmd_name[RTE_ETH_NAME_MAX_LEN];
474 test_add_slave_to_bonded_device();
476 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
477 slaves, RTE_MAX_ETHPORTS);
478 TEST_ASSERT_EQUAL(current_slave_count, 1,
479 "Number of slaves (%d) is not that expected (%d).",
480 current_slave_count, 1);
482 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
484 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
486 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
488 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
489 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
491 "Added slave (%d) to bonded port (%d) unexpectedly.",
492 test_params->slave_port_ids[test_params->bonded_slave_count-1],
495 return test_remove_slave_from_bonded_device();
500 test_get_slaves_from_bonded_device(void)
502 int current_slave_count;
503 uint16_t slaves[RTE_MAX_ETHPORTS];
505 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
506 "Failed to add slave to bonded device");
508 /* Invalid port id */
509 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
511 TEST_ASSERT(current_slave_count < 0,
512 "Invalid port id unexpectedly succeeded");
514 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
515 slaves, RTE_MAX_ETHPORTS);
516 TEST_ASSERT(current_slave_count < 0,
517 "Invalid port id unexpectedly succeeded");
519 /* Invalid slaves pointer */
520 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
521 NULL, RTE_MAX_ETHPORTS);
522 TEST_ASSERT(current_slave_count < 0,
523 "Invalid slave array unexpectedly succeeded");
525 current_slave_count = rte_eth_bond_active_slaves_get(
526 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
527 TEST_ASSERT(current_slave_count < 0,
528 "Invalid slave array unexpectedly succeeded");
530 /* non bonded device*/
531 current_slave_count = rte_eth_bond_slaves_get(
532 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
533 TEST_ASSERT(current_slave_count < 0,
534 "Invalid port id unexpectedly succeeded");
536 current_slave_count = rte_eth_bond_active_slaves_get(
537 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
538 TEST_ASSERT(current_slave_count < 0,
539 "Invalid port id unexpectedly succeeded");
541 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
542 "Failed to remove slaves from bonded device");
549 test_add_remove_multiple_slaves_to_from_bonded_device(void)
553 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
554 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
555 "Failed to add slave to bonded device");
557 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
558 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
559 "Failed to remove slaves from bonded device");
565 enable_bonded_slaves(void)
569 for (i = 0; i < test_params->bonded_slave_count; i++) {
570 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
573 virtual_ethdev_simulate_link_status_interrupt(
574 test_params->slave_port_ids[i], 1);
579 test_start_bonded_device(void)
581 struct rte_eth_link link_status;
583 int current_slave_count, current_bonding_mode, primary_port;
584 uint16_t slaves[RTE_MAX_ETHPORTS];
586 /* Add slave to bonded device*/
587 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
588 "Failed to add slave to bonded device");
590 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
591 "Failed to start bonded pmd eth device %d.",
592 test_params->bonded_port_id);
594 /* Change link status of virtual pmd so it will be added to the active
595 * slave list of the bonded device*/
596 virtual_ethdev_simulate_link_status_interrupt(
597 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
599 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
600 slaves, RTE_MAX_ETHPORTS);
601 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
602 "Number of slaves (%d) is not expected value (%d).",
603 current_slave_count, test_params->bonded_slave_count);
605 current_slave_count = rte_eth_bond_active_slaves_get(
606 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
607 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
608 "Number of active slaves (%d) is not expected value (%d).",
609 current_slave_count, test_params->bonded_slave_count);
611 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
612 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
613 "Bonded device mode (%d) is not expected value (%d).\n",
614 current_bonding_mode, test_params->bonding_mode);
616 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
617 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
618 "Primary port (%d) is not expected value (%d).",
619 primary_port, test_params->slave_port_ids[0]);
621 rte_eth_link_get(test_params->bonded_port_id, &link_status);
622 TEST_ASSERT_EQUAL(link_status.link_status, 1,
623 "Bonded port (%d) status (%d) is not expected value (%d).\n",
624 test_params->bonded_port_id, link_status.link_status, 1);
630 test_stop_bonded_device(void)
632 int current_slave_count;
633 uint16_t slaves[RTE_MAX_ETHPORTS];
635 struct rte_eth_link link_status;
637 rte_eth_dev_stop(test_params->bonded_port_id);
639 rte_eth_link_get(test_params->bonded_port_id, &link_status);
640 TEST_ASSERT_EQUAL(link_status.link_status, 0,
641 "Bonded port (%d) status (%d) is not expected value (%d).",
642 test_params->bonded_port_id, link_status.link_status, 0);
644 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
645 slaves, RTE_MAX_ETHPORTS);
646 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
647 "Number of slaves (%d) is not expected value (%d).",
648 current_slave_count, test_params->bonded_slave_count);
650 current_slave_count = rte_eth_bond_active_slaves_get(
651 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
652 TEST_ASSERT_EQUAL(current_slave_count, 0,
653 "Number of active slaves (%d) is not expected value (%d).",
654 current_slave_count, 0);
660 remove_slaves_and_stop_bonded_device(void)
662 /* Clean up and remove slaves from bonded device */
663 free_virtualpmd_tx_queue();
664 while (test_params->bonded_slave_count > 0)
665 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
666 "test_remove_slave_from_bonded_device failed");
668 rte_eth_dev_stop(test_params->bonded_port_id);
669 rte_eth_stats_reset(test_params->bonded_port_id);
670 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
676 test_set_bonding_mode(void)
680 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
681 BONDING_MODE_ACTIVE_BACKUP,
682 BONDING_MODE_BALANCE,
683 BONDING_MODE_BROADCAST
686 /* Test supported link bonding modes */
687 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
688 /* Invalid port ID */
689 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
691 "Expected call to failed as invalid port (%d) specified.",
694 /* Non bonded device */
695 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
697 "Expected call to failed as invalid port (%d) specified.",
698 test_params->slave_port_ids[0]);
700 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
702 "Failed to set link bonding mode on port (%d) to (%d).",
703 test_params->bonded_port_id, bonding_modes[i]);
705 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
706 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
707 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
708 bonding_mode, test_params->bonded_port_id,
711 /* Invalid port ID */
712 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
713 TEST_ASSERT(bonding_mode < 0,
714 "Expected call to failed as invalid port (%d) specified.",
717 /* Non bonded device */
718 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
719 TEST_ASSERT(bonding_mode < 0,
720 "Expected call to failed as invalid port (%d) specified.",
721 test_params->slave_port_ids[0]);
724 return remove_slaves_and_stop_bonded_device();
728 test_set_primary_slave(void)
731 struct ether_addr read_mac_addr;
732 struct ether_addr *expected_mac_addr;
734 /* Add 4 slaves to bonded device */
735 for (i = test_params->bonded_slave_count; i < 4; i++)
736 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
737 "Failed to add slave to bonded device.");
739 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
740 BONDING_MODE_ROUND_ROBIN),
741 "Failed to set link bonding mode on port (%d) to (%d).",
742 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
744 /* Invalid port ID */
745 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
746 test_params->slave_port_ids[i]),
747 "Expected call to failed as invalid port specified.");
749 /* Non bonded device */
750 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
751 test_params->slave_port_ids[i]),
752 "Expected call to failed as invalid port specified.");
754 /* Set slave as primary
755 * Verify slave it is now primary slave
756 * Verify that MAC address of bonded device is that of primary slave
757 * Verify that MAC address of all bonded slaves are that of primary slave
759 for (i = 0; i < 4; i++) {
760 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
761 test_params->slave_port_ids[i]),
762 "Failed to set bonded port (%d) primary port to (%d)",
763 test_params->bonded_port_id, test_params->slave_port_ids[i]);
765 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
766 TEST_ASSERT(retval >= 0,
767 "Failed to read primary port from bonded port (%d)\n",
768 test_params->bonded_port_id);
770 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
771 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
772 test_params->bonded_port_id, retval,
773 test_params->slave_port_ids[i]);
775 /* stop/start bonded eth dev to apply new MAC */
776 rte_eth_dev_stop(test_params->bonded_port_id);
778 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
779 "Failed to start bonded port %d",
780 test_params->bonded_port_id);
782 expected_mac_addr = (struct ether_addr *)&slave_mac;
783 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
785 /* Check primary slave MAC */
786 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
787 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
788 sizeof(read_mac_addr)),
789 "bonded port mac address not set to that of primary port\n");
791 /* Check bonded MAC */
792 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
793 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
794 sizeof(read_mac_addr)),
795 "bonded port mac address not set to that of primary port\n");
797 /* Check other slaves MACs */
798 for (j = 0; j < 4; j++) {
800 rte_eth_macaddr_get(test_params->slave_port_ids[j],
802 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
803 sizeof(read_mac_addr)),
804 "slave port mac address not set to that of primary "
811 /* Test with none existent port */
812 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
813 "read primary port from expectedly");
815 /* Test with slave port */
816 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
817 "read primary port from expectedly\n");
819 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
820 "Failed to stop and remove slaves from bonded device");
823 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
824 "read primary port from expectedly\n");
830 test_set_explicit_bonded_mac(void)
833 struct ether_addr read_mac_addr;
834 struct ether_addr *mac_addr;
836 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
838 mac_addr = (struct ether_addr *)explicit_bonded_mac;
840 /* Invalid port ID */
841 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
842 "Expected call to failed as invalid port specified.");
844 /* Non bonded device */
845 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
846 test_params->slave_port_ids[0], mac_addr),
847 "Expected call to failed as invalid port specified.");
849 /* NULL MAC address */
850 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
851 test_params->bonded_port_id, NULL),
852 "Expected call to failed as NULL MAC specified");
854 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
855 test_params->bonded_port_id, mac_addr),
856 "Failed to set MAC address on bonded port (%d)",
857 test_params->bonded_port_id);
859 /* Add 4 slaves to bonded device */
860 for (i = test_params->bonded_slave_count; i < 4; i++) {
861 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
862 "Failed to add slave to bonded device.\n");
865 /* Check bonded MAC */
866 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
867 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
868 "bonded port mac address not set to that of primary port");
870 /* Check other slaves MACs */
871 for (i = 0; i < 4; i++) {
872 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
873 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
874 sizeof(read_mac_addr)),
875 "slave port mac address not set to that of primary port");
878 /* test resetting mac address on bonded device */
880 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
881 "Failed to reset MAC address on bonded port (%d)",
882 test_params->bonded_port_id);
885 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
886 "Reset MAC address on bonded port (%d) unexpectedly",
887 test_params->slave_port_ids[1]);
889 /* test resetting mac address on bonded device with no slaves */
890 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
891 "Failed to remove slaves and stop bonded device");
893 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
894 "Failed to reset MAC address on bonded port (%d)",
895 test_params->bonded_port_id);
900 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
903 test_set_bonded_port_initialization_mac_assignment(void)
905 int i, slave_count, bonded_port_id;
907 uint16_t slaves[RTE_MAX_ETHPORTS];
908 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
910 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
912 /* Initialize default values for MAC addresses */
913 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
914 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
917 * 1. a - Create / configure bonded / slave ethdevs
919 bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
920 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
921 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
923 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
924 "Failed to configure bonded ethdev");
926 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
927 char pmd_name[RTE_ETH_NAME_MAX_LEN];
929 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
931 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
933 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
934 &slave_mac_addr, rte_socket_id(), 1);
936 TEST_ASSERT(slave_port_ids[i] >= 0,
937 "Failed to create slave ethdev %s", pmd_name);
939 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
940 "Failed to configure virtual ethdev %s",
946 * 2. Add slave ethdevs to bonded device
948 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
949 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
951 "Failed to add slave (%d) to bonded port (%d).",
952 slave_port_ids[i], bonded_port_id);
955 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
957 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
958 "Number of slaves (%d) is not as expected (%d)",
959 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
963 * 3. Set explicit MAC address on bonded ethdev
965 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
966 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
968 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
969 bonded_port_id, &bonded_mac_addr),
970 "Failed to set MAC address on bonded port (%d)",
974 /* 4. a - Start bonded ethdev
975 * b - Enable slave devices
976 * c - Verify bonded/slaves ethdev MAC addresses
978 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
979 "Failed to start bonded pmd eth device %d.",
982 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
983 virtual_ethdev_simulate_link_status_interrupt(
984 slave_port_ids[i], 1);
987 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
988 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
989 sizeof(read_mac_addr)),
990 "bonded port mac address not as expected");
992 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
993 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
994 sizeof(read_mac_addr)),
995 "slave port 0 mac address not as expected");
997 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
998 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
999 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1000 sizeof(read_mac_addr)),
1001 "slave port 1 mac address not as expected");
1003 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1004 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1005 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1006 sizeof(read_mac_addr)),
1007 "slave port 2 mac address not as expected");
1010 /* 7. a - Change primary port
1011 * b - Stop / Start bonded port
1012 * d - Verify slave ethdev MAC addresses
1014 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1016 "failed to set primary port on bonded device.");
1018 rte_eth_dev_stop(bonded_port_id);
1019 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1020 "Failed to start bonded pmd eth device %d.",
1023 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1024 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1025 sizeof(read_mac_addr)),
1026 "bonded port mac address not as expected");
1028 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1029 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1030 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1031 sizeof(read_mac_addr)),
1032 "slave port 0 mac address not as expected");
1034 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1035 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1036 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1037 sizeof(read_mac_addr)),
1038 "slave port 1 mac address not as expected");
1040 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1041 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1042 sizeof(read_mac_addr)),
1043 "slave port 2 mac address not as expected");
1045 /* 6. a - Stop bonded ethdev
1046 * b - remove slave ethdevs
1047 * c - Verify slave ethdevs MACs are restored
1049 rte_eth_dev_stop(bonded_port_id);
1051 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1052 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1054 "Failed to remove slave %d from bonded port (%d).",
1055 slave_port_ids[i], bonded_port_id);
1058 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1061 TEST_ASSERT_EQUAL(slave_count, 0,
1062 "Number of slaves (%d) is great than expected (%d).",
1065 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1066 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1067 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1068 sizeof(read_mac_addr)),
1069 "slave port 0 mac address not as expected");
1071 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1072 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1073 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1074 sizeof(read_mac_addr)),
1075 "slave port 1 mac address not as expected");
1077 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1078 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1079 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1080 sizeof(read_mac_addr)),
1081 "slave port 2 mac address not as expected");
1088 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1089 uint16_t number_of_slaves, uint8_t enable_slave)
1091 /* Configure bonded device */
1092 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1093 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1094 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1097 /* Add slaves to bonded device */
1098 while (number_of_slaves > test_params->bonded_slave_count)
1099 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1100 "Failed to add slave (%d to bonding port (%d).",
1101 test_params->bonded_slave_count - 1,
1102 test_params->bonded_port_id);
1104 /* Set link bonding mode */
1105 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1107 "Failed to set link bonding mode on port (%d) to (%d).",
1108 test_params->bonded_port_id, bonding_mode);
1110 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1111 "Failed to start bonded pmd eth device %d.",
1112 test_params->bonded_port_id);
1115 enable_bonded_slaves();
1121 test_adding_slave_after_bonded_device_started(void)
1125 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1126 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1127 "Failed to add slaves to bonded device");
1129 /* Enabled slave devices */
1130 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1131 virtual_ethdev_simulate_link_status_interrupt(
1132 test_params->slave_port_ids[i], 1);
1135 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1136 test_params->slave_port_ids[test_params->bonded_slave_count]),
1137 "Failed to add slave to bonded port.\n");
1139 rte_eth_stats_reset(
1140 test_params->slave_port_ids[test_params->bonded_slave_count]);
1142 test_params->bonded_slave_count++;
1144 return remove_slaves_and_stop_bonded_device();
1147 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1148 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1150 int test_lsc_interrupt_count;
1154 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1155 enum rte_eth_event_type type __rte_unused,
1156 void *param __rte_unused,
1157 void *ret_param __rte_unused)
1159 pthread_mutex_lock(&mutex);
1160 test_lsc_interrupt_count++;
1162 pthread_cond_signal(&cvar);
1163 pthread_mutex_unlock(&mutex);
1169 lsc_timeout(int wait_us)
1176 gettimeofday(&tp, NULL);
1178 /* Convert from timeval to timespec */
1179 ts.tv_sec = tp.tv_sec;
1180 ts.tv_nsec = tp.tv_usec * 1000;
1181 ts.tv_nsec += wait_us * 1000;
1183 pthread_mutex_lock(&mutex);
1184 if (test_lsc_interrupt_count < 1)
1185 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1187 pthread_mutex_unlock(&mutex);
1189 if (retval == 0 && test_lsc_interrupt_count < 1)
1196 test_status_interrupt(void)
1199 uint16_t slaves[RTE_MAX_ETHPORTS];
1201 /* initialized bonding device with T slaves */
1202 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1203 BONDING_MODE_ROUND_ROBIN, 1,
1204 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1205 "Failed to initialise bonded device");
1207 test_lsc_interrupt_count = 0;
1209 /* register link status change interrupt callback */
1210 rte_eth_dev_callback_register(test_params->bonded_port_id,
1211 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1212 &test_params->bonded_port_id);
1214 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1215 slaves, RTE_MAX_ETHPORTS);
1217 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1218 "Number of active slaves (%d) is not as expected (%d)",
1219 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1221 /* Bring all 4 slaves link status to down and test that we have received a
1223 virtual_ethdev_simulate_link_status_interrupt(
1224 test_params->slave_port_ids[0], 0);
1225 virtual_ethdev_simulate_link_status_interrupt(
1226 test_params->slave_port_ids[1], 0);
1227 virtual_ethdev_simulate_link_status_interrupt(
1228 test_params->slave_port_ids[2], 0);
1230 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1231 "Received a link status change interrupt unexpectedly");
1233 virtual_ethdev_simulate_link_status_interrupt(
1234 test_params->slave_port_ids[3], 0);
1236 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1237 "timed out waiting for interrupt");
1239 TEST_ASSERT(test_lsc_interrupt_count > 0,
1240 "Did not receive link status change interrupt");
1242 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1243 slaves, RTE_MAX_ETHPORTS);
1245 TEST_ASSERT_EQUAL(slave_count, 0,
1246 "Number of active slaves (%d) is not as expected (%d)",
1249 /* bring one slave port up so link status will change */
1250 test_lsc_interrupt_count = 0;
1252 virtual_ethdev_simulate_link_status_interrupt(
1253 test_params->slave_port_ids[0], 1);
1255 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1256 "timed out waiting for interrupt");
1258 /* test that we have received another lsc interrupt */
1259 TEST_ASSERT(test_lsc_interrupt_count > 0,
1260 "Did not receive link status change interrupt");
1262 /* Verify that calling the same slave lsc interrupt doesn't cause another
1263 * lsc interrupt from bonded device */
1264 test_lsc_interrupt_count = 0;
1266 virtual_ethdev_simulate_link_status_interrupt(
1267 test_params->slave_port_ids[0], 1);
1269 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1270 "received unexpected interrupt");
1272 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1273 "Did not receive link status change interrupt");
1276 /* unregister lsc callback before exiting */
1277 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1278 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1279 &test_params->bonded_port_id);
1281 /* Clean up and remove slaves from bonded device */
1282 return remove_slaves_and_stop_bonded_device();
1286 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1287 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1288 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1290 uint16_t pktlen, generated_burst_size, ether_type;
1294 ether_type = ETHER_TYPE_IPv4;
1296 ether_type = ETHER_TYPE_IPv6;
1299 initialize_eth_header(test_params->pkt_eth_hdr,
1300 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1301 ether_type, vlan, vlan_id);
1303 initialize_eth_header(test_params->pkt_eth_hdr,
1304 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1305 ether_type, vlan, vlan_id);
1308 if (toggle_udp_port)
1309 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1312 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1317 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1318 dst_addr_1, pktlen);
1320 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1321 dst_addr_0, pktlen);
1323 ip_hdr = test_params->pkt_ipv4_hdr;
1326 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1327 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1330 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1331 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1334 ip_hdr = test_params->pkt_ipv6_hdr;
1337 /* Generate burst of packets to transmit */
1338 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1339 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1340 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1342 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1343 "Failed to generate packet burst");
1345 return generated_burst_size;
1348 /** Round Robin Mode Tests */
1351 test_roundrobin_tx_burst(void)
1354 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1355 struct rte_eth_stats port_stats;
1357 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1358 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1359 "Failed to initialise bonded device");
1361 burst_size = 20 * test_params->bonded_slave_count;
1363 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1364 "Burst size specified is greater than supported.");
1366 /* Generate test bursts of packets to transmit */
1367 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1368 burst_size, "failed to generate test burst");
1370 /* Send burst on bonded port */
1371 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1372 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1375 /* Verify bonded port tx stats */
1376 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1377 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1378 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1379 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1382 /* Verify slave ports tx stats */
1383 for (i = 0; i < test_params->bonded_slave_count; i++) {
1384 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1385 TEST_ASSERT_EQUAL(port_stats.opackets,
1386 (uint64_t)burst_size / test_params->bonded_slave_count,
1387 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1388 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1389 burst_size / test_params->bonded_slave_count);
1392 /* Put all slaves down and try and transmit */
1393 for (i = 0; i < test_params->bonded_slave_count; i++) {
1394 virtual_ethdev_simulate_link_status_interrupt(
1395 test_params->slave_port_ids[i], 0);
1398 /* Send burst on bonded port */
1399 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1400 pkt_burst, burst_size), 0,
1401 "tx burst return unexpected value");
1403 /* Clean up and remove slaves from bonded device */
1404 return remove_slaves_and_stop_bonded_device();
1408 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1412 for (i = 0; i < nb_mbufs; i++) {
1413 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1414 TEST_ASSERT_EQUAL(refcnt, val,
1415 "mbuf ref count (%d)is not the expected value (%d)",
1422 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1426 for (i = 0; i < nb_mbufs; i++)
1427 rte_pktmbuf_free(mbufs[i]);
1430 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1431 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1432 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1433 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1436 test_roundrobin_tx_burst_slave_tx_fail(void)
1438 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1439 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1441 struct rte_eth_stats port_stats;
1443 int i, first_fail_idx, tx_count;
1445 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1446 BONDING_MODE_ROUND_ROBIN, 0,
1447 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1448 "Failed to initialise bonded device");
1450 /* Generate test bursts of packets to transmit */
1451 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1452 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1453 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1454 "Failed to generate test packet burst");
1456 /* Copy references to packets which we expect not to be transmitted */
1457 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1458 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1459 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1460 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1462 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1463 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1464 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1467 /* Set virtual slave to only fail transmission of
1468 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1469 virtual_ethdev_tx_burst_fn_set_success(
1470 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1473 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1474 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1475 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1477 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1478 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1480 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1481 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1482 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1483 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1484 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1486 /* Verify that failed packet are expected failed packets */
1487 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1488 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1489 "expected mbuf (%d) pointer %p not expected pointer %p",
1490 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1493 /* Verify bonded port tx stats */
1494 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1496 TEST_ASSERT_EQUAL(port_stats.opackets,
1497 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1498 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1499 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1500 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1501 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1502 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1504 /* Verify slave ports tx stats */
1505 for (i = 0; i < test_params->bonded_slave_count; i++) {
1506 int slave_expected_tx_count;
1508 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1510 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1511 test_params->bonded_slave_count;
1513 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1514 slave_expected_tx_count = slave_expected_tx_count -
1515 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1517 TEST_ASSERT_EQUAL(port_stats.opackets,
1518 (uint64_t)slave_expected_tx_count,
1519 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1520 test_params->slave_port_ids[i],
1521 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1524 /* Verify that all mbufs have a ref value of zero */
1525 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1526 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1527 "mbufs refcnts not as expected");
1528 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1530 /* Clean up and remove slaves from bonded device */
1531 return remove_slaves_and_stop_bonded_device();
1535 test_roundrobin_rx_burst_on_single_slave(void)
1537 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1538 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1540 struct rte_eth_stats port_stats;
1542 int i, j, burst_size = 25;
1544 /* Initialize bonded device with 4 slaves in round robin mode */
1545 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1546 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1547 "Failed to initialize bonded device with slaves");
1549 /* Generate test bursts of packets to transmit */
1550 TEST_ASSERT_EQUAL(generate_test_burst(
1551 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1552 "burst generation failed");
1554 for (i = 0; i < test_params->bonded_slave_count; i++) {
1555 /* Add rx data to slave */
1556 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1557 &gen_pkt_burst[0], burst_size);
1559 /* Call rx burst on bonded device */
1560 /* Send burst on bonded port */
1561 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1562 test_params->bonded_port_id, 0, rx_pkt_burst,
1563 MAX_PKT_BURST), burst_size,
1564 "round-robin rx burst failed");
1566 /* Verify bonded device rx count */
1567 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1568 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1569 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1570 test_params->bonded_port_id,
1571 (unsigned int)port_stats.ipackets, burst_size);
1575 /* Verify bonded slave devices rx count */
1576 /* Verify slave ports tx stats */
1577 for (j = 0; j < test_params->bonded_slave_count; j++) {
1578 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1581 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1582 "Slave Port (%d) ipackets value (%u) not as expected"
1583 " (%d)", test_params->slave_port_ids[i],
1584 (unsigned int)port_stats.ipackets, burst_size);
1586 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1587 "Slave Port (%d) ipackets value (%u) not as expected"
1588 " (%d)", test_params->slave_port_ids[i],
1589 (unsigned int)port_stats.ipackets, 0);
1592 /* Reset bonded slaves stats */
1593 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1595 /* reset bonded device stats */
1596 rte_eth_stats_reset(test_params->bonded_port_id);
1600 for (i = 0; i < MAX_PKT_BURST; i++) {
1601 if (rx_pkt_burst[i] != NULL)
1602 rte_pktmbuf_free(rx_pkt_burst[i]);
1606 /* Clean up and remove slaves from bonded device */
1607 return remove_slaves_and_stop_bonded_device();
1610 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1613 test_roundrobin_rx_burst_on_multiple_slaves(void)
1615 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1617 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1618 struct rte_eth_stats port_stats;
1620 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1623 /* Initialize bonded device with 4 slaves in round robin mode */
1624 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1625 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1626 "Failed to initialize bonded device with slaves");
1628 /* Generate test bursts of packets to transmit */
1629 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1630 TEST_ASSERT_EQUAL(generate_test_burst(
1631 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1632 burst_size[i], "burst generation failed");
1635 /* Add rx data to slaves */
1636 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1637 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1638 &gen_pkt_burst[i][0], burst_size[i]);
1641 /* Call rx burst on bonded device */
1642 /* Send burst on bonded port */
1643 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1645 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1646 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1647 burst_size[0] + burst_size[1] + burst_size[2]);
1649 /* Verify bonded device rx count */
1650 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1651 TEST_ASSERT_EQUAL(port_stats.ipackets,
1652 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1653 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1654 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1655 burst_size[0] + burst_size[1] + burst_size[2]);
1657 /* Verify bonded slave devices rx counts */
1658 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1659 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1660 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1661 test_params->slave_port_ids[0],
1662 (unsigned int)port_stats.ipackets, burst_size[0]);
1664 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1665 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1666 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1667 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1670 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1671 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1672 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1673 test_params->slave_port_ids[2],
1674 (unsigned int)port_stats.ipackets, burst_size[2]);
1676 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1677 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1678 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1679 test_params->slave_port_ids[3],
1680 (unsigned int)port_stats.ipackets, 0);
1683 for (i = 0; i < MAX_PKT_BURST; i++) {
1684 if (rx_pkt_burst[i] != NULL)
1685 rte_pktmbuf_free(rx_pkt_burst[i]);
1688 /* Clean up and remove slaves from bonded device */
1689 return remove_slaves_and_stop_bonded_device();
1693 test_roundrobin_verify_mac_assignment(void)
1695 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1699 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1700 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1702 /* Initialize bonded device with 4 slaves in round robin mode */
1703 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1704 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1705 "Failed to initialize bonded device with slaves");
1707 /* Verify that all MACs are the same as first slave added to bonded dev */
1708 for (i = 0; i < test_params->bonded_slave_count; i++) {
1709 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1710 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1711 sizeof(read_mac_addr)),
1712 "slave port (%d) mac address not set to that of primary port",
1713 test_params->slave_port_ids[i]);
1716 /* change primary and verify that MAC addresses haven't changed */
1717 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1718 test_params->slave_port_ids[2]),
1719 "Failed to set bonded port (%d) primary port to (%d)",
1720 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1722 for (i = 0; i < test_params->bonded_slave_count; i++) {
1723 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1724 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1725 sizeof(read_mac_addr)),
1726 "slave port (%d) mac address has changed to that of primary"
1727 " port without stop/start toggle of bonded device",
1728 test_params->slave_port_ids[i]);
1731 /* stop / start bonded device and verify that primary MAC address is
1732 * propagate to bonded device and slaves */
1733 rte_eth_dev_stop(test_params->bonded_port_id);
1735 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1736 "Failed to start bonded device");
1738 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1739 TEST_ASSERT_SUCCESS(
1740 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1741 "bonded port (%d) mac address not set to that of new primary port",
1742 test_params->slave_port_ids[i]);
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_2, &read_mac_addr,
1747 sizeof(read_mac_addr)),
1748 "slave port (%d) mac address not set to that of new primary"
1749 " port", test_params->slave_port_ids[i]);
1752 /* Set explicit MAC address */
1753 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1754 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1755 "Failed to set MAC");
1757 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1758 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1759 sizeof(read_mac_addr)),
1760 "bonded port (%d) mac address not set to that of new primary port",
1761 test_params->slave_port_ids[i]);
1763 for (i = 0; i < test_params->bonded_slave_count; i++) {
1764 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1765 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1766 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1767 " that of new primary port\n", test_params->slave_port_ids[i]);
1770 /* Clean up and remove slaves from bonded device */
1771 return remove_slaves_and_stop_bonded_device();
1775 test_roundrobin_verify_promiscuous_enable_disable(void)
1777 int i, promiscuous_en;
1779 /* Initialize bonded device with 4 slaves in round robin mode */
1780 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1781 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1782 "Failed to initialize bonded device with slaves");
1784 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1786 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1787 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1788 "Port (%d) promiscuous mode not enabled",
1789 test_params->bonded_port_id);
1791 for (i = 0; i < test_params->bonded_slave_count; i++) {
1792 promiscuous_en = rte_eth_promiscuous_get(
1793 test_params->slave_port_ids[i]);
1794 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1795 "slave port (%d) promiscuous mode not enabled",
1796 test_params->slave_port_ids[i]);
1799 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1801 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1802 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1803 "Port (%d) promiscuous mode not disabled\n",
1804 test_params->bonded_port_id);
1806 for (i = 0; i < test_params->bonded_slave_count; i++) {
1807 promiscuous_en = rte_eth_promiscuous_get(
1808 test_params->slave_port_ids[i]);
1809 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1810 "Port (%d) promiscuous mode not disabled\n",
1811 test_params->slave_port_ids[i]);
1814 /* Clean up and remove slaves from bonded device */
1815 return remove_slaves_and_stop_bonded_device();
1818 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1819 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1822 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1824 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1825 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1826 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1828 struct rte_eth_stats port_stats;
1829 uint16_t slaves[RTE_MAX_ETHPORTS];
1831 int i, burst_size, slave_count;
1833 /* NULL all pointers in array to simplify cleanup */
1834 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1836 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1837 * in round robin mode */
1838 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1839 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1840 "Failed to initialize bonded device with slaves");
1842 /* Verify Current Slaves Count /Active Slave Count is */
1843 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1845 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1846 "Number of slaves (%d) is not as expected (%d).",
1847 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1849 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1850 slaves, RTE_MAX_ETHPORTS);
1851 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1852 "Number of active slaves (%d) is not as expected (%d).",
1853 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1855 /* Set 2 slaves eth_devs link status to down */
1856 virtual_ethdev_simulate_link_status_interrupt(
1857 test_params->slave_port_ids[1], 0);
1858 virtual_ethdev_simulate_link_status_interrupt(
1859 test_params->slave_port_ids[3], 0);
1861 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1862 slaves, RTE_MAX_ETHPORTS);
1863 TEST_ASSERT_EQUAL(slave_count,
1864 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1865 "Number of active slaves (%d) is not as expected (%d).\n",
1866 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1870 /* Verify that pkts are not sent on slaves with link status down:
1872 * 1. Generate test burst of traffic
1873 * 2. Transmit burst on bonded eth_dev
1874 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1875 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1878 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1879 burst_size, "generate_test_burst failed");
1881 rte_eth_stats_reset(test_params->bonded_port_id);
1885 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1886 burst_size), burst_size, "rte_eth_tx_burst failed");
1888 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1889 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1890 "Port (%d) opackets stats (%d) not expected (%d) value",
1891 test_params->bonded_port_id, (int)port_stats.opackets,
1894 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1895 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1896 "Port (%d) opackets stats (%d) not expected (%d) value",
1897 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1899 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1900 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1901 "Port (%d) opackets stats (%d) not expected (%d) value",
1902 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1904 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1905 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1906 "Port (%d) opackets stats (%d) not expected (%d) value",
1907 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1909 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1910 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1911 "Port (%d) opackets stats (%d) not expected (%d) value",
1912 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1914 /* Verify that pkts are not sent on slaves with link status down:
1916 * 1. Generate test bursts of traffic
1917 * 2. Add bursts on to virtual eth_devs
1918 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1919 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1920 * 4. Verify stats for bonded eth_dev
1921 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1923 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1924 TEST_ASSERT_EQUAL(generate_test_burst(
1925 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1926 burst_size, "failed to generate packet burst");
1928 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1929 &gen_pkt_burst[i][0], burst_size);
1932 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1933 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1934 burst_size + burst_size,
1935 "rte_eth_rx_burst failed");
1937 /* Verify bonded device rx count */
1938 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1939 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1940 "(%d) port_stats.ipackets not as expected\n",
1941 test_params->bonded_port_id);
1944 for (i = 0; i < MAX_PKT_BURST; i++) {
1945 if (rx_pkt_burst[i] != NULL)
1946 rte_pktmbuf_free(rx_pkt_burst[i]);
1949 /* Clean up and remove slaves from bonded device */
1950 return remove_slaves_and_stop_bonded_device();
1953 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1955 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1958 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1961 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1963 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1964 char slave_name[RTE_ETH_NAME_MAX_LEN];
1968 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1969 /* Generate slave name / MAC address */
1970 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1971 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
1973 /* Create slave devices with no ISR Support */
1974 if (polling_test_slaves[i] == -1) {
1975 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
1976 rte_socket_id(), 0);
1977 TEST_ASSERT(polling_test_slaves[i] >= 0,
1978 "Failed to create virtual virtual ethdev %s\n", slave_name);
1980 /* Configure slave */
1981 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
1982 "Failed to configure virtual ethdev %s(%d)", slave_name,
1983 polling_test_slaves[i]);
1986 /* Add slave to bonded device */
1987 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1988 polling_test_slaves[i]),
1989 "Failed to add slave %s(%d) to bonded device %d",
1990 slave_name, polling_test_slaves[i],
1991 test_params->bonded_port_id);
1994 /* Initialize bonded device */
1995 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
1996 "Failed to configure bonded device %d",
1997 test_params->bonded_port_id);
2000 /* Register link status change interrupt callback */
2001 rte_eth_dev_callback_register(test_params->bonded_port_id,
2002 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2003 &test_params->bonded_port_id);
2005 /* link status change callback for first slave link up */
2006 test_lsc_interrupt_count = 0;
2008 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2010 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2013 /* no link status change callback for second slave link up */
2014 test_lsc_interrupt_count = 0;
2016 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2018 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2020 /* link status change callback for both slave links down */
2021 test_lsc_interrupt_count = 0;
2023 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2024 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2026 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2028 /* Un-Register link status change interrupt callback */
2029 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2030 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2031 &test_params->bonded_port_id);
2034 /* Clean up and remove slaves from bonded device */
2035 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2037 TEST_ASSERT_SUCCESS(
2038 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2039 polling_test_slaves[i]),
2040 "Failed to remove slave %d from bonded port (%d)",
2041 polling_test_slaves[i], test_params->bonded_port_id);
2044 return remove_slaves_and_stop_bonded_device();
2048 /** Active Backup Mode Tests */
2051 test_activebackup_tx_burst(void)
2053 int i, pktlen, primary_port, burst_size;
2054 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2055 struct rte_eth_stats port_stats;
2057 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2058 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2059 "Failed to initialize bonded device with slaves");
2061 initialize_eth_header(test_params->pkt_eth_hdr,
2062 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2063 ETHER_TYPE_IPv4, 0, 0);
2064 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2066 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2067 dst_addr_0, pktlen);
2069 burst_size = 20 * test_params->bonded_slave_count;
2071 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2072 "Burst size specified is greater than supported.");
2074 /* Generate a burst of packets to transmit */
2075 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2076 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2077 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2078 burst_size, "failed to generate burst correctly");
2080 /* Send burst on bonded port */
2081 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2082 burst_size), burst_size, "tx burst failed");
2084 /* Verify bonded port tx stats */
2085 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2086 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2087 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2088 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2091 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2093 /* Verify slave ports tx stats */
2094 for (i = 0; i < test_params->bonded_slave_count; i++) {
2095 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2096 if (test_params->slave_port_ids[i] == primary_port) {
2097 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2098 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2099 test_params->bonded_port_id,
2100 (unsigned int)port_stats.opackets,
2101 burst_size / test_params->bonded_slave_count);
2103 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2104 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2105 test_params->bonded_port_id,
2106 (unsigned int)port_stats.opackets, 0);
2110 /* Put all slaves down and try and transmit */
2111 for (i = 0; i < test_params->bonded_slave_count; i++) {
2112 virtual_ethdev_simulate_link_status_interrupt(
2113 test_params->slave_port_ids[i], 0);
2116 /* Send burst on bonded port */
2117 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2118 pkts_burst, burst_size), 0, "Sending empty burst failed");
2120 /* Clean up and remove slaves from bonded device */
2121 return remove_slaves_and_stop_bonded_device();
2124 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2127 test_activebackup_rx_burst(void)
2129 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2130 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2132 struct rte_eth_stats port_stats;
2136 int i, j, burst_size = 17;
2138 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2139 BONDING_MODE_ACTIVE_BACKUP, 0,
2140 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2141 "Failed to initialize bonded device with slaves");
2143 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2144 TEST_ASSERT(primary_port >= 0,
2145 "failed to get primary slave for bonded port (%d)",
2146 test_params->bonded_port_id);
2148 for (i = 0; i < test_params->bonded_slave_count; i++) {
2149 /* Generate test bursts of packets to transmit */
2150 TEST_ASSERT_EQUAL(generate_test_burst(
2151 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2152 burst_size, "burst generation failed");
2154 /* Add rx data to slave */
2155 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2156 &gen_pkt_burst[0], burst_size);
2158 /* Call rx burst on bonded device */
2159 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2160 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2161 "rte_eth_rx_burst failed");
2163 if (test_params->slave_port_ids[i] == primary_port) {
2164 /* Verify bonded device rx count */
2165 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2166 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2167 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2168 test_params->bonded_port_id,
2169 (unsigned int)port_stats.ipackets, burst_size);
2171 /* Verify bonded slave devices rx count */
2172 for (j = 0; j < test_params->bonded_slave_count; j++) {
2173 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2175 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2176 "Slave Port (%d) ipackets value (%u) not as "
2177 "expected (%d)", test_params->slave_port_ids[i],
2178 (unsigned int)port_stats.ipackets, burst_size);
2180 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2181 "Slave Port (%d) ipackets value (%u) not as "
2182 "expected (%d)\n", test_params->slave_port_ids[i],
2183 (unsigned int)port_stats.ipackets, 0);
2187 for (j = 0; j < test_params->bonded_slave_count; j++) {
2188 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2189 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2190 "Slave Port (%d) ipackets value (%u) not as expected "
2191 "(%d)", test_params->slave_port_ids[i],
2192 (unsigned int)port_stats.ipackets, 0);
2197 for (i = 0; i < MAX_PKT_BURST; i++) {
2198 if (rx_pkt_burst[i] != NULL) {
2199 rte_pktmbuf_free(rx_pkt_burst[i]);
2200 rx_pkt_burst[i] = NULL;
2204 /* reset bonded device stats */
2205 rte_eth_stats_reset(test_params->bonded_port_id);
2208 /* Clean up and remove slaves from bonded device */
2209 return remove_slaves_and_stop_bonded_device();
2213 test_activebackup_verify_promiscuous_enable_disable(void)
2215 int i, primary_port, promiscuous_en;
2217 /* Initialize bonded device with 4 slaves in round robin mode */
2218 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2219 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2220 "Failed to initialize bonded device with slaves");
2222 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2223 TEST_ASSERT(primary_port >= 0,
2224 "failed to get primary slave for bonded port (%d)",
2225 test_params->bonded_port_id);
2227 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2229 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2230 "Port (%d) promiscuous mode not enabled",
2231 test_params->bonded_port_id);
2233 for (i = 0; i < test_params->bonded_slave_count; i++) {
2234 promiscuous_en = rte_eth_promiscuous_get(
2235 test_params->slave_port_ids[i]);
2236 if (primary_port == test_params->slave_port_ids[i]) {
2237 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2238 "slave port (%d) promiscuous mode not enabled",
2239 test_params->slave_port_ids[i]);
2241 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2242 "slave port (%d) promiscuous mode enabled",
2243 test_params->slave_port_ids[i]);
2248 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2250 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2251 "Port (%d) promiscuous mode not disabled\n",
2252 test_params->bonded_port_id);
2254 for (i = 0; i < test_params->bonded_slave_count; i++) {
2255 promiscuous_en = rte_eth_promiscuous_get(
2256 test_params->slave_port_ids[i]);
2257 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2258 "slave port (%d) promiscuous mode not disabled\n",
2259 test_params->slave_port_ids[i]);
2262 /* Clean up and remove slaves from bonded device */
2263 return remove_slaves_and_stop_bonded_device();
2267 test_activebackup_verify_mac_assignment(void)
2269 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2271 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2272 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2274 /* Initialize bonded device with 2 slaves in active backup mode */
2275 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2276 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2277 "Failed to initialize bonded device with slaves");
2279 /* Verify that bonded MACs is that of first slave and that the other slave
2280 * MAC hasn't been changed */
2281 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2282 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2283 sizeof(read_mac_addr)),
2284 "bonded port (%d) mac address not set to that of primary port",
2285 test_params->bonded_port_id);
2287 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2288 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2289 sizeof(read_mac_addr)),
2290 "slave port (%d) mac address not set to that of primary port",
2291 test_params->slave_port_ids[0]);
2293 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2294 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2295 sizeof(read_mac_addr)),
2296 "slave port (%d) mac address not as expected",
2297 test_params->slave_port_ids[1]);
2299 /* change primary and verify that MAC addresses haven't changed */
2300 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2301 test_params->slave_port_ids[1]), 0,
2302 "Failed to set bonded port (%d) primary port to (%d)",
2303 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2305 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2306 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2307 sizeof(read_mac_addr)),
2308 "bonded port (%d) mac address not set to that of primary port",
2309 test_params->bonded_port_id);
2311 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2312 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2313 sizeof(read_mac_addr)),
2314 "slave port (%d) mac address not set to that of primary port",
2315 test_params->slave_port_ids[0]);
2317 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2318 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2319 sizeof(read_mac_addr)),
2320 "slave port (%d) mac address not as expected",
2321 test_params->slave_port_ids[1]);
2323 /* stop / start bonded device and verify that primary MAC address is
2324 * propagated to bonded device and slaves */
2326 rte_eth_dev_stop(test_params->bonded_port_id);
2328 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2329 "Failed to start device");
2331 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2332 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2333 sizeof(read_mac_addr)),
2334 "bonded port (%d) mac address not set to that of primary port",
2335 test_params->bonded_port_id);
2337 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2338 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2339 sizeof(read_mac_addr)),
2340 "slave port (%d) mac address not as expected",
2341 test_params->slave_port_ids[0]);
2343 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2344 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2345 sizeof(read_mac_addr)),
2346 "slave port (%d) mac address not set to that of primary port",
2347 test_params->slave_port_ids[1]);
2349 /* Set explicit MAC address */
2350 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2351 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2352 "failed to set MAC address");
2354 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2355 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2356 sizeof(read_mac_addr)),
2357 "bonded port (%d) mac address not set to that of bonded port",
2358 test_params->bonded_port_id);
2360 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2361 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2362 sizeof(read_mac_addr)),
2363 "slave port (%d) mac address not as expected",
2364 test_params->slave_port_ids[0]);
2366 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2367 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2368 sizeof(read_mac_addr)),
2369 "slave port (%d) mac address not set to that of bonded port",
2370 test_params->slave_port_ids[1]);
2372 /* Clean up and remove slaves from bonded device */
2373 return remove_slaves_and_stop_bonded_device();
2377 test_activebackup_verify_slave_link_status_change_failover(void)
2379 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2380 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2381 struct rte_eth_stats port_stats;
2383 uint16_t slaves[RTE_MAX_ETHPORTS];
2385 int i, burst_size, slave_count, primary_port;
2389 memset(pkt_burst, 0, sizeof(pkt_burst));
2391 /* Generate packet burst for testing */
2392 TEST_ASSERT_EQUAL(generate_test_burst(
2393 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2394 "generate_test_burst failed");
2396 /* Initialize bonded device with 4 slaves in round robin mode */
2397 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2398 BONDING_MODE_ACTIVE_BACKUP, 0,
2399 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2400 "Failed to initialize bonded device with slaves");
2402 /* Verify Current Slaves Count /Active Slave Count is */
2403 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2405 TEST_ASSERT_EQUAL(slave_count, 4,
2406 "Number of slaves (%d) is not as expected (%d).",
2409 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2410 slaves, RTE_MAX_ETHPORTS);
2411 TEST_ASSERT_EQUAL(slave_count, 4,
2412 "Number of active slaves (%d) is not as expected (%d).",
2415 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2416 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2417 "Primary port not as expected");
2419 /* Bring 2 slaves down and verify active slave count */
2420 virtual_ethdev_simulate_link_status_interrupt(
2421 test_params->slave_port_ids[1], 0);
2422 virtual_ethdev_simulate_link_status_interrupt(
2423 test_params->slave_port_ids[3], 0);
2425 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2426 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2427 "Number of active slaves (%d) is not as expected (%d).",
2430 virtual_ethdev_simulate_link_status_interrupt(
2431 test_params->slave_port_ids[1], 1);
2432 virtual_ethdev_simulate_link_status_interrupt(
2433 test_params->slave_port_ids[3], 1);
2436 /* Bring primary port down, verify that active slave count is 3 and primary
2438 virtual_ethdev_simulate_link_status_interrupt(
2439 test_params->slave_port_ids[0], 0);
2441 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2442 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2444 "Number of active slaves (%d) is not as expected (%d).",
2447 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2448 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2449 "Primary port not as expected");
2451 /* Verify that pkts are sent on new primary slave */
2453 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2454 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2455 burst_size), burst_size, "rte_eth_tx_burst failed");
2457 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2458 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2459 "(%d) port_stats.opackets not as expected",
2460 test_params->slave_port_ids[2]);
2462 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2463 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2464 "(%d) port_stats.opackets not as expected\n",
2465 test_params->slave_port_ids[0]);
2467 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2468 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2469 "(%d) port_stats.opackets not as expected\n",
2470 test_params->slave_port_ids[1]);
2472 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2473 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2474 "(%d) port_stats.opackets not as expected\n",
2475 test_params->slave_port_ids[3]);
2477 /* Generate packet burst for testing */
2479 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2480 TEST_ASSERT_EQUAL(generate_test_burst(
2481 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2482 "generate_test_burst failed");
2484 virtual_ethdev_add_mbufs_to_rx_queue(
2485 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2488 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2489 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2490 burst_size, "rte_eth_rx_burst\n");
2492 /* Verify bonded device rx count */
2493 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2494 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2495 "(%d) port_stats.ipackets not as expected",
2496 test_params->bonded_port_id);
2498 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2499 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2500 "(%d) port_stats.opackets not as expected",
2501 test_params->slave_port_ids[2]);
2503 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2504 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2505 "(%d) port_stats.opackets not as expected",
2506 test_params->slave_port_ids[0]);
2508 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2509 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2510 "(%d) port_stats.opackets not as expected",
2511 test_params->slave_port_ids[1]);
2513 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2514 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2515 "(%d) port_stats.opackets not as expected",
2516 test_params->slave_port_ids[3]);
2518 /* Clean up and remove slaves from bonded device */
2519 return remove_slaves_and_stop_bonded_device();
2522 /** Balance Mode Tests */
2525 test_balance_xmit_policy_configuration(void)
2527 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2528 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2529 "Failed to initialize_bonded_device_with_slaves.");
2531 /* Invalid port id */
2532 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2533 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2534 "Expected call to failed as invalid port specified.");
2536 /* Set xmit policy on non bonded device */
2537 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2538 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2539 "Expected call to failed as invalid port specified.");
2542 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2543 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2544 "Failed to set balance xmit policy.");
2546 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2547 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2550 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2551 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2552 "Failed to set balance xmit policy.");
2554 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2555 BALANCE_XMIT_POLICY_LAYER23,
2556 "balance xmit policy not as expected.");
2559 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2560 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2561 "Failed to set balance xmit policy.");
2563 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2564 BALANCE_XMIT_POLICY_LAYER34,
2565 "balance xmit policy not as expected.");
2567 /* Invalid port id */
2568 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2569 "Expected call to failed as invalid port specified.");
2571 /* Clean up and remove slaves from bonded device */
2572 return remove_slaves_and_stop_bonded_device();
2575 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2578 test_balance_l2_tx_burst(void)
2580 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2581 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2585 struct rte_eth_stats port_stats;
2587 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2588 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2589 "Failed to initialize_bonded_device_with_slaves.");
2591 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2592 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2593 "Failed to set balance xmit policy.");
2595 initialize_eth_header(test_params->pkt_eth_hdr,
2596 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2597 ETHER_TYPE_IPv4, 0, 0);
2598 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2600 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2601 dst_addr_0, pktlen);
2603 /* Generate a burst 1 of packets to transmit */
2604 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2605 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2606 test_params->pkt_udp_hdr, burst_size[0],
2607 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2608 "failed to generate packet burst");
2610 initialize_eth_header(test_params->pkt_eth_hdr,
2611 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2612 ETHER_TYPE_IPv4, 0, 0);
2614 /* Generate a burst 2 of packets to transmit */
2615 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2616 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2617 test_params->pkt_udp_hdr, burst_size[1],
2618 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2619 "failed to generate packet burst");
2621 /* Send burst 1 on bonded port */
2622 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2623 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2624 &pkts_burst[i][0], burst_size[i]),
2625 burst_size[i], "Failed to transmit packet burst");
2628 /* Verify bonded port tx stats */
2629 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2630 TEST_ASSERT_EQUAL(port_stats.opackets,
2631 (uint64_t)(burst_size[0] + burst_size[1]),
2632 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2633 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2634 burst_size[0] + burst_size[1]);
2637 /* Verify slave ports tx stats */
2638 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2639 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2640 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2641 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2644 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2645 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2646 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2647 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2650 /* Put all slaves down and try and transmit */
2651 for (i = 0; i < test_params->bonded_slave_count; i++) {
2653 virtual_ethdev_simulate_link_status_interrupt(
2654 test_params->slave_port_ids[i], 0);
2657 /* Send burst on bonded port */
2658 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2659 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2660 0, "Expected zero packet");
2662 /* Clean up and remove slaves from bonded device */
2663 return remove_slaves_and_stop_bonded_device();
2667 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2668 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2670 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2672 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2673 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2675 struct rte_eth_stats port_stats;
2677 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2678 BONDING_MODE_BALANCE, 0, 2, 1),
2679 "Failed to initialize_bonded_device_with_slaves.");
2681 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2682 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2683 "Failed to set balance xmit policy.");
2688 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2689 "Burst size specified is greater than supported.");
2691 /* Generate test bursts of packets to transmit */
2692 TEST_ASSERT_EQUAL(generate_test_burst(
2693 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2694 burst_size_1, "failed to generate packet burst");
2696 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2697 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2698 "failed to generate packet burst");
2700 /* Send burst 1 on bonded port */
2701 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2703 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2705 /* Send burst 2 on bonded port */
2706 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2708 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2710 /* Verify bonded port tx stats */
2711 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2712 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2713 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2714 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2717 /* Verify slave ports tx stats */
2718 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2719 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2720 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2721 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2724 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2725 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2726 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2727 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2730 /* Put all slaves down and try and transmit */
2731 for (i = 0; i < test_params->bonded_slave_count; i++) {
2733 virtual_ethdev_simulate_link_status_interrupt(
2734 test_params->slave_port_ids[i], 0);
2737 /* Send burst on bonded port */
2738 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2739 test_params->bonded_port_id, 0, pkts_burst_1,
2740 burst_size_1), 0, "Expected zero packet");
2743 /* Clean up and remove slaves from bonded device */
2744 return remove_slaves_and_stop_bonded_device();
2748 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2750 return balance_l23_tx_burst(0, 1, 0, 1);
2754 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2756 return balance_l23_tx_burst(1, 1, 0, 1);
2760 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2762 return balance_l23_tx_burst(0, 0, 0, 1);
2766 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2768 return balance_l23_tx_burst(1, 0, 0, 1);
2772 test_balance_l23_tx_burst_toggle_mac_addr(void)
2774 return balance_l23_tx_burst(0, 0, 1, 0);
2778 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2779 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2780 uint8_t toggle_udp_port)
2782 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2784 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2785 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2787 struct rte_eth_stats port_stats;
2789 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2790 BONDING_MODE_BALANCE, 0, 2, 1),
2791 "Failed to initialize_bonded_device_with_slaves.");
2793 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2794 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2795 "Failed to set balance xmit policy.");
2800 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2801 "Burst size specified is greater than supported.");
2803 /* Generate test bursts of packets to transmit */
2804 TEST_ASSERT_EQUAL(generate_test_burst(
2805 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2806 burst_size_1, "failed to generate burst");
2808 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2809 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2810 toggle_udp_port), burst_size_2, "failed to generate burst");
2812 /* Send burst 1 on bonded port */
2813 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2815 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2817 /* Send burst 2 on bonded port */
2818 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2820 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2823 /* Verify bonded port tx stats */
2824 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2825 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2826 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2827 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2830 /* Verify slave ports tx stats */
2831 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2832 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2833 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2834 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2837 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2838 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2839 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2840 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2843 /* Put all slaves down and try and transmit */
2844 for (i = 0; i < test_params->bonded_slave_count; i++) {
2846 virtual_ethdev_simulate_link_status_interrupt(
2847 test_params->slave_port_ids[i], 0);
2850 /* Send burst on bonded port */
2851 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2852 test_params->bonded_port_id, 0, pkts_burst_1,
2853 burst_size_1), 0, "Expected zero packet");
2855 /* Clean up and remove slaves from bonded device */
2856 return remove_slaves_and_stop_bonded_device();
2860 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2862 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2866 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2868 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2872 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2874 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2878 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2880 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2884 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2886 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2890 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2892 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2895 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2896 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2897 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2898 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2899 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2902 test_balance_tx_burst_slave_tx_fail(void)
2904 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2905 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2907 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2909 struct rte_eth_stats port_stats;
2911 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2913 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2914 BONDING_MODE_BALANCE, 0,
2915 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2916 "Failed to initialise bonded device");
2918 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2919 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2920 "Failed to set balance xmit policy.");
2923 /* Generate test bursts for transmission */
2924 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2925 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2926 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2927 "Failed to generate test packet burst 1");
2929 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2930 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2932 /* copy mbuf referneces for expected transmission failures */
2933 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2934 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2936 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2937 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2938 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2939 "Failed to generate test packet burst 2");
2942 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2943 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2944 virtual_ethdev_tx_burst_fn_set_success(
2945 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2948 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2949 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2950 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2953 /* Transmit burst 1 */
2954 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2955 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2957 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2958 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2959 "Transmitted (%d) packets, expected to transmit (%d) packets",
2960 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2961 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2963 /* Verify that failed packet are expected failed packets */
2964 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
2965 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
2966 "expected mbuf (%d) pointer %p not expected pointer %p",
2967 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
2970 /* Transmit burst 2 */
2971 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2972 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2974 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2975 "Transmitted (%d) packets, expected to transmit (%d) packets",
2976 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2979 /* Verify bonded port tx stats */
2980 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2982 TEST_ASSERT_EQUAL(port_stats.opackets,
2983 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2984 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2985 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
2986 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2987 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2988 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2989 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2990 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2992 /* Verify slave ports tx stats */
2994 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2996 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
2997 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2998 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2999 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3000 test_params->slave_port_ids[0],
3001 (unsigned int)port_stats.opackets,
3002 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3003 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3008 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3010 TEST_ASSERT_EQUAL(port_stats.opackets,
3011 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3012 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3013 test_params->slave_port_ids[1],
3014 (unsigned int)port_stats.opackets,
3015 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3017 /* Verify that all mbufs have a ref value of zero */
3018 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3019 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3020 "mbufs refcnts not as expected");
3022 free_mbufs(&pkts_burst_1[tx_count_1],
3023 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3025 /* Clean up and remove slaves from bonded device */
3026 return remove_slaves_and_stop_bonded_device();
3029 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3032 test_balance_rx_burst(void)
3034 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3036 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3037 struct rte_eth_stats port_stats;
3039 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3042 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3044 /* Initialize bonded device with 4 slaves in round robin mode */
3045 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3046 BONDING_MODE_BALANCE, 0, 3, 1),
3047 "Failed to initialise bonded device");
3049 /* Generate test bursts of packets to transmit */
3050 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3051 TEST_ASSERT_EQUAL(generate_test_burst(
3052 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3053 0, 0), burst_size[i],
3054 "failed to generate packet burst");
3057 /* Add rx data to slaves */
3058 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3059 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3060 &gen_pkt_burst[i][0], burst_size[i]);
3063 /* Call rx burst on bonded device */
3064 /* Send burst on bonded port */
3065 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3066 rx_pkt_burst, MAX_PKT_BURST),
3067 burst_size[0] + burst_size[1] + burst_size[2],
3068 "balance rx burst failed\n");
3070 /* Verify bonded device rx count */
3071 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3072 TEST_ASSERT_EQUAL(port_stats.ipackets,
3073 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3074 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3075 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3076 burst_size[0] + burst_size[1] + burst_size[2]);
3079 /* Verify bonded slave devices rx counts */
3080 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3081 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3082 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3083 test_params->slave_port_ids[0],
3084 (unsigned int)port_stats.ipackets, burst_size[0]);
3086 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3087 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3088 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3089 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3092 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3093 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3094 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3095 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3098 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3099 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3100 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3101 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3105 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3106 for (j = 0; j < MAX_PKT_BURST; j++) {
3107 if (gen_pkt_burst[i][j] != NULL) {
3108 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3109 gen_pkt_burst[i][j] = NULL;
3114 /* Clean up and remove slaves from bonded device */
3115 return remove_slaves_and_stop_bonded_device();
3119 test_balance_verify_promiscuous_enable_disable(void)
3123 /* Initialize bonded device with 4 slaves in round robin mode */
3124 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3125 BONDING_MODE_BALANCE, 0, 4, 1),
3126 "Failed to initialise bonded device");
3128 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3130 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3131 "Port (%d) promiscuous mode not enabled",
3132 test_params->bonded_port_id);
3134 for (i = 0; i < test_params->bonded_slave_count; i++) {
3135 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3136 test_params->slave_port_ids[i]), 1,
3137 "Port (%d) promiscuous mode not enabled",
3138 test_params->slave_port_ids[i]);
3141 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3143 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3144 "Port (%d) promiscuous mode not disabled",
3145 test_params->bonded_port_id);
3147 for (i = 0; i < test_params->bonded_slave_count; i++) {
3148 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3149 test_params->slave_port_ids[i]), 0,
3150 "Port (%d) promiscuous mode not disabled",
3151 test_params->slave_port_ids[i]);
3154 /* Clean up and remove slaves from bonded device */
3155 return remove_slaves_and_stop_bonded_device();
3159 test_balance_verify_mac_assignment(void)
3161 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3163 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3164 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3166 /* Initialize bonded device with 2 slaves in active backup mode */
3167 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3168 BONDING_MODE_BALANCE, 0, 2, 1),
3169 "Failed to initialise bonded device");
3171 /* Verify that bonded MACs is that of first slave and that the other slave
3172 * MAC hasn't been changed */
3173 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3174 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3175 sizeof(read_mac_addr)),
3176 "bonded port (%d) mac address not set to that of primary port",
3177 test_params->bonded_port_id);
3179 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3180 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3181 sizeof(read_mac_addr)),
3182 "slave port (%d) mac address not set to that of primary port",
3183 test_params->slave_port_ids[0]);
3185 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3186 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3187 sizeof(read_mac_addr)),
3188 "slave port (%d) mac address not set to that of primary port",
3189 test_params->slave_port_ids[1]);
3191 /* change primary and verify that MAC addresses haven't changed */
3192 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3193 test_params->slave_port_ids[1]),
3194 "Failed to set bonded port (%d) primary port to (%d)\n",
3195 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3197 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3198 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3199 sizeof(read_mac_addr)),
3200 "bonded port (%d) mac address not set to that of primary port",
3201 test_params->bonded_port_id);
3203 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3204 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3205 sizeof(read_mac_addr)),
3206 "slave port (%d) mac address not set to that of primary port",
3207 test_params->slave_port_ids[0]);
3209 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3210 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3211 sizeof(read_mac_addr)),
3212 "slave port (%d) mac address not set to that of primary port",
3213 test_params->slave_port_ids[1]);
3215 /* stop / start bonded device and verify that primary MAC address is
3216 * propagated to bonded device and slaves */
3218 rte_eth_dev_stop(test_params->bonded_port_id);
3220 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3221 "Failed to start bonded device");
3223 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3224 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3225 sizeof(read_mac_addr)),
3226 "bonded port (%d) mac address not set to that of primary port",
3227 test_params->bonded_port_id);
3229 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3230 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3231 sizeof(read_mac_addr)),
3232 "slave port (%d) mac address not set to that of primary port",
3233 test_params->slave_port_ids[0]);
3235 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3236 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3237 sizeof(read_mac_addr)),
3238 "slave port (%d) mac address not set to that of primary port",
3239 test_params->slave_port_ids[1]);
3241 /* Set explicit MAC address */
3242 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3243 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3244 "failed to set MAC");
3246 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3247 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3248 sizeof(read_mac_addr)),
3249 "bonded port (%d) mac address not set to that of bonded port",
3250 test_params->bonded_port_id);
3252 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3253 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3254 sizeof(read_mac_addr)),
3255 "slave port (%d) mac address not as expected\n",
3256 test_params->slave_port_ids[0]);
3258 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3259 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3260 sizeof(read_mac_addr)),
3261 "slave port (%d) mac address not set to that of bonded port",
3262 test_params->slave_port_ids[1]);
3264 /* Clean up and remove slaves from bonded device */
3265 return remove_slaves_and_stop_bonded_device();
3268 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3271 test_balance_verify_slave_link_status_change_behaviour(void)
3273 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3274 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3275 struct rte_eth_stats port_stats;
3277 uint16_t slaves[RTE_MAX_ETHPORTS];
3279 int i, burst_size, slave_count;
3281 memset(pkt_burst, 0, sizeof(pkt_burst));
3283 /* Initialize bonded device with 4 slaves in round robin mode */
3284 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3285 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3286 "Failed to initialise bonded device");
3288 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3289 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3290 "Failed to set balance xmit policy.");
3293 /* Verify Current Slaves Count /Active Slave Count is */
3294 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3296 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3297 "Number of slaves (%d) is not as expected (%d).",
3298 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3300 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3301 slaves, RTE_MAX_ETHPORTS);
3302 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3303 "Number of active slaves (%d) is not as expected (%d).",
3304 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3306 /* Set 2 slaves link status to down */
3307 virtual_ethdev_simulate_link_status_interrupt(
3308 test_params->slave_port_ids[1], 0);
3309 virtual_ethdev_simulate_link_status_interrupt(
3310 test_params->slave_port_ids[3], 0);
3312 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3313 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3314 "Number of active slaves (%d) is not as expected (%d).",
3317 /* Send to sets of packet burst and verify that they are balanced across
3321 TEST_ASSERT_EQUAL(generate_test_burst(
3322 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3323 "generate_test_burst failed");
3325 TEST_ASSERT_EQUAL(generate_test_burst(
3326 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3327 "generate_test_burst failed");
3329 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3330 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3331 burst_size, "rte_eth_tx_burst failed");
3333 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3334 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3335 burst_size, "rte_eth_tx_burst failed");
3338 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3339 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3340 "(%d) port_stats.opackets (%d) not as expected (%d).",
3341 test_params->bonded_port_id, (int)port_stats.opackets,
3342 burst_size + burst_size);
3344 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3345 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3346 "(%d) port_stats.opackets (%d) not as expected (%d).",
3347 test_params->slave_port_ids[0], (int)port_stats.opackets,
3350 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3351 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3352 "(%d) port_stats.opackets (%d) not as expected (%d).",
3353 test_params->slave_port_ids[2], (int)port_stats.opackets,
3356 /* verify that all packets get send on primary slave when no other slaves
3358 virtual_ethdev_simulate_link_status_interrupt(
3359 test_params->slave_port_ids[2], 0);
3361 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3362 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3363 "Number of active slaves (%d) is not as expected (%d).",
3366 TEST_ASSERT_EQUAL(generate_test_burst(
3367 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3368 "generate_test_burst failed");
3370 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3371 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3372 burst_size, "rte_eth_tx_burst failed");
3374 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3375 TEST_ASSERT_EQUAL(port_stats.opackets,
3376 (uint64_t)(burst_size + burst_size + burst_size),
3377 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3378 test_params->bonded_port_id, (int)port_stats.opackets,
3379 burst_size + burst_size + burst_size);
3381 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3382 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3383 "(%d) port_stats.opackets (%d) not as expected (%d).",
3384 test_params->slave_port_ids[0], (int)port_stats.opackets,
3385 burst_size + burst_size);
3387 virtual_ethdev_simulate_link_status_interrupt(
3388 test_params->slave_port_ids[0], 0);
3389 virtual_ethdev_simulate_link_status_interrupt(
3390 test_params->slave_port_ids[1], 1);
3391 virtual_ethdev_simulate_link_status_interrupt(
3392 test_params->slave_port_ids[2], 1);
3393 virtual_ethdev_simulate_link_status_interrupt(
3394 test_params->slave_port_ids[3], 1);
3396 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3397 TEST_ASSERT_EQUAL(generate_test_burst(
3398 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3399 "Failed to generate packet burst");
3401 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3402 &pkt_burst[i][0], burst_size);
3405 /* Verify that pkts are not received on slaves with link status down */
3407 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3410 /* Verify bonded device rx count */
3411 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3412 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3413 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3414 test_params->bonded_port_id, (int)port_stats.ipackets,
3417 /* Clean up and remove slaves from bonded device */
3418 return remove_slaves_and_stop_bonded_device();
3422 test_broadcast_tx_burst(void)
3424 int i, pktlen, burst_size;
3425 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3427 struct rte_eth_stats port_stats;
3429 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3430 BONDING_MODE_BROADCAST, 0, 2, 1),
3431 "Failed to initialise bonded device");
3433 initialize_eth_header(test_params->pkt_eth_hdr,
3434 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3435 ETHER_TYPE_IPv4, 0, 0);
3437 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3439 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3440 dst_addr_0, pktlen);
3442 burst_size = 20 * test_params->bonded_slave_count;
3444 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3445 "Burst size specified is greater than supported.");
3447 /* Generate a burst of packets to transmit */
3448 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3449 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3450 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3451 1), burst_size, "Failed to generate packet burst");
3453 /* Send burst on bonded port */
3454 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3455 pkts_burst, burst_size), burst_size,
3456 "Bonded Port (%d) rx burst failed, packets transmitted value "
3457 "not as expected (%d)",
3458 test_params->bonded_port_id, burst_size);
3460 /* Verify bonded port tx stats */
3461 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3462 TEST_ASSERT_EQUAL(port_stats.opackets,
3463 (uint64_t)burst_size * test_params->bonded_slave_count,
3464 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3465 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3468 /* Verify slave ports tx stats */
3469 for (i = 0; i < test_params->bonded_slave_count; i++) {
3470 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3471 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3472 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3473 test_params->bonded_port_id,
3474 (unsigned int)port_stats.opackets, burst_size);
3477 /* Put all slaves down and try and transmit */
3478 for (i = 0; i < test_params->bonded_slave_count; i++) {
3480 virtual_ethdev_simulate_link_status_interrupt(
3481 test_params->slave_port_ids[i], 0);
3484 /* Send burst on bonded port */
3485 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3486 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3487 "transmitted an unexpected number of packets");
3489 /* Clean up and remove slaves from bonded device */
3490 return remove_slaves_and_stop_bonded_device();
3494 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3495 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3496 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3497 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3500 test_broadcast_tx_burst_slave_tx_fail(void)
3502 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3503 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3505 struct rte_eth_stats port_stats;
3509 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3510 BONDING_MODE_BROADCAST, 0,
3511 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3512 "Failed to initialise bonded device");
3514 /* Generate test bursts for transmission */
3515 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3516 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3517 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3518 "Failed to generate test packet burst");
3520 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3521 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3522 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3525 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3526 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3527 virtual_ethdev_tx_burst_fn_set_success(
3528 test_params->slave_port_ids[0],
3530 virtual_ethdev_tx_burst_fn_set_success(
3531 test_params->slave_port_ids[1],
3533 virtual_ethdev_tx_burst_fn_set_success(
3534 test_params->slave_port_ids[2],
3537 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3538 test_params->slave_port_ids[0],
3539 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3541 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3542 test_params->slave_port_ids[1],
3543 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3545 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3546 test_params->slave_port_ids[2],
3547 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3549 /* Transmit burst */
3550 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3551 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3553 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3554 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3555 "Transmitted (%d) packets, expected to transmit (%d) packets",
3556 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3557 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3559 /* Verify that failed packet are expected failed packets */
3560 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3561 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3562 "expected mbuf (%d) pointer %p not expected pointer %p",
3563 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3566 /* Verify slave ports tx stats */
3568 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3570 TEST_ASSERT_EQUAL(port_stats.opackets,
3571 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3572 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3573 "Port (%d) opackets value (%u) not as expected (%d)",
3574 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3575 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3576 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3579 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3581 TEST_ASSERT_EQUAL(port_stats.opackets,
3582 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3583 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3584 "Port (%d) opackets value (%u) not as expected (%d)",
3585 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3586 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3587 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3589 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3591 TEST_ASSERT_EQUAL(port_stats.opackets,
3592 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3593 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3594 "Port (%d) opackets value (%u) not as expected (%d)",
3595 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3596 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3597 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3600 /* Verify that all mbufs who transmission failed have a ref value of one */
3601 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3602 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3603 "mbufs refcnts not as expected");
3605 free_mbufs(&pkts_burst[tx_count],
3606 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3608 /* Clean up and remove slaves from bonded device */
3609 return remove_slaves_and_stop_bonded_device();
3612 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3615 test_broadcast_rx_burst(void)
3617 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3619 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3620 struct rte_eth_stats port_stats;
3622 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3625 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3627 /* Initialize bonded device with 4 slaves in round robin mode */
3628 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3629 BONDING_MODE_BROADCAST, 0, 3, 1),
3630 "Failed to initialise bonded device");
3632 /* Generate test bursts of packets to transmit */
3633 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3634 TEST_ASSERT_EQUAL(generate_test_burst(
3635 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3636 burst_size[i], "failed to generate packet burst");
3639 /* Add rx data to slave 0 */
3640 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3641 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3642 &gen_pkt_burst[i][0], burst_size[i]);
3646 /* Call rx burst on bonded device */
3647 /* Send burst on bonded port */
3648 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3649 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3650 burst_size[0] + burst_size[1] + burst_size[2],
3653 /* Verify bonded device rx count */
3654 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3655 TEST_ASSERT_EQUAL(port_stats.ipackets,
3656 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3657 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3658 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3659 burst_size[0] + burst_size[1] + burst_size[2]);
3662 /* Verify bonded slave devices rx counts */
3663 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3664 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3665 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3666 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3669 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3670 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3671 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3672 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3675 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3676 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3677 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3678 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3681 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3682 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3683 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3684 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3687 /* free mbufs allocate for rx testing */
3688 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3689 for (j = 0; j < MAX_PKT_BURST; j++) {
3690 if (gen_pkt_burst[i][j] != NULL) {
3691 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3692 gen_pkt_burst[i][j] = NULL;
3697 /* Clean up and remove slaves from bonded device */
3698 return remove_slaves_and_stop_bonded_device();
3702 test_broadcast_verify_promiscuous_enable_disable(void)
3706 /* Initialize bonded device with 4 slaves in round robin mode */
3707 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3708 BONDING_MODE_BROADCAST, 0, 4, 1),
3709 "Failed to initialise bonded device");
3711 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3714 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3715 "Port (%d) promiscuous mode not enabled",
3716 test_params->bonded_port_id);
3718 for (i = 0; i < test_params->bonded_slave_count; i++) {
3719 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3720 test_params->slave_port_ids[i]), 1,
3721 "Port (%d) promiscuous mode not enabled",
3722 test_params->slave_port_ids[i]);
3725 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3727 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3728 "Port (%d) promiscuous mode not disabled",
3729 test_params->bonded_port_id);
3731 for (i = 0; i < test_params->bonded_slave_count; i++) {
3732 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3733 test_params->slave_port_ids[i]), 0,
3734 "Port (%d) promiscuous mode not disabled",
3735 test_params->slave_port_ids[i]);
3738 /* Clean up and remove slaves from bonded device */
3739 return remove_slaves_and_stop_bonded_device();
3743 test_broadcast_verify_mac_assignment(void)
3745 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3749 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3750 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3752 /* Initialize bonded device with 4 slaves in round robin mode */
3753 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3754 BONDING_MODE_BROADCAST, 0, 4, 1),
3755 "Failed to initialise bonded device");
3757 /* Verify that all MACs are the same as first slave added to bonded
3759 for (i = 0; i < test_params->bonded_slave_count; i++) {
3760 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3761 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3762 sizeof(read_mac_addr)),
3763 "slave port (%d) mac address not set to that of primary port",
3764 test_params->slave_port_ids[i]);
3767 /* change primary and verify that MAC addresses haven't changed */
3768 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3769 test_params->slave_port_ids[2]),
3770 "Failed to set bonded port (%d) primary port to (%d)",
3771 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3773 for (i = 0; i < test_params->bonded_slave_count; i++) {
3774 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3775 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3776 sizeof(read_mac_addr)),
3777 "slave port (%d) mac address has changed to that of primary "
3778 "port without stop/start toggle of bonded device",
3779 test_params->slave_port_ids[i]);
3782 /* stop / start bonded device and verify that primary MAC address is
3783 * propagated to bonded device and slaves */
3785 rte_eth_dev_stop(test_params->bonded_port_id);
3787 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3788 "Failed to start bonded device");
3790 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3791 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3792 sizeof(read_mac_addr)),
3793 "bonded port (%d) mac address not set to that of new primary port",
3794 test_params->slave_port_ids[i]);
3796 for (i = 0; i < test_params->bonded_slave_count; i++) {
3797 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3798 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3799 sizeof(read_mac_addr)),
3800 "slave port (%d) mac address not set to that of new primary "
3801 "port", test_params->slave_port_ids[i]);
3804 /* Set explicit MAC address */
3805 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3806 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3807 "Failed to set MAC address");
3809 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3810 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3811 sizeof(read_mac_addr)),
3812 "bonded port (%d) mac address not set to that of new primary port",
3813 test_params->slave_port_ids[i]);
3816 for (i = 0; i < test_params->bonded_slave_count; i++) {
3817 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3818 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3819 sizeof(read_mac_addr)),
3820 "slave port (%d) mac address not set to that of new primary "
3821 "port", test_params->slave_port_ids[i]);
3824 /* Clean up and remove slaves from bonded device */
3825 return remove_slaves_and_stop_bonded_device();
3828 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3830 test_broadcast_verify_slave_link_status_change_behaviour(void)
3832 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3833 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3834 struct rte_eth_stats port_stats;
3836 uint16_t slaves[RTE_MAX_ETHPORTS];
3838 int i, burst_size, slave_count;
3840 memset(pkt_burst, 0, sizeof(pkt_burst));
3842 /* Initialize bonded device with 4 slaves in round robin mode */
3843 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3844 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3845 1), "Failed to initialise bonded device");
3847 /* Verify Current Slaves Count /Active Slave Count is */
3848 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3850 TEST_ASSERT_EQUAL(slave_count, 4,
3851 "Number of slaves (%d) is not as expected (%d).",
3854 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3855 slaves, RTE_MAX_ETHPORTS);
3856 TEST_ASSERT_EQUAL(slave_count, 4,
3857 "Number of active slaves (%d) is not as expected (%d).",
3860 /* Set 2 slaves link status to down */
3861 virtual_ethdev_simulate_link_status_interrupt(
3862 test_params->slave_port_ids[1], 0);
3863 virtual_ethdev_simulate_link_status_interrupt(
3864 test_params->slave_port_ids[3], 0);
3866 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3867 slaves, RTE_MAX_ETHPORTS);
3868 TEST_ASSERT_EQUAL(slave_count, 2,
3869 "Number of active slaves (%d) is not as expected (%d).",
3872 for (i = 0; i < test_params->bonded_slave_count; i++)
3873 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3875 /* Verify that pkts are not sent on slaves with link status down */
3878 TEST_ASSERT_EQUAL(generate_test_burst(
3879 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3880 "generate_test_burst failed");
3882 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3883 &pkt_burst[0][0], burst_size), burst_size,
3884 "rte_eth_tx_burst failed\n");
3886 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3887 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3888 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3889 test_params->bonded_port_id, (int)port_stats.opackets,
3890 burst_size * slave_count);
3892 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3893 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3894 "(%d) port_stats.opackets not as expected",
3895 test_params->slave_port_ids[0]);
3897 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3898 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3899 "(%d) port_stats.opackets not as expected",
3900 test_params->slave_port_ids[1]);
3902 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3903 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3904 "(%d) port_stats.opackets not as expected",
3905 test_params->slave_port_ids[2]);
3908 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3909 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3910 "(%d) port_stats.opackets not as expected",
3911 test_params->slave_port_ids[3]);
3914 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3915 TEST_ASSERT_EQUAL(generate_test_burst(
3916 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3917 burst_size, "failed to generate packet burst");
3919 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3920 &pkt_burst[i][0], burst_size);
3923 /* Verify that pkts are not received on slaves with link status down */
3924 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3925 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3926 burst_size + burst_size, "rte_eth_rx_burst failed");
3929 /* Verify bonded device rx count */
3930 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3931 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3932 "(%d) port_stats.ipackets not as expected\n",
3933 test_params->bonded_port_id);
3935 /* Clean up and remove slaves from bonded device */
3936 return remove_slaves_and_stop_bonded_device();
3940 test_reconfigure_bonded_device(void)
3942 test_params->nb_rx_q = 4;
3943 test_params->nb_tx_q = 4;
3945 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3946 "failed to reconfigure bonded device");
3948 test_params->nb_rx_q = 2;
3949 test_params->nb_tx_q = 2;
3951 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3952 "failed to reconfigure bonded device with less rx/tx queues");
3959 test_close_bonded_device(void)
3961 rte_eth_dev_close(test_params->bonded_port_id);
3966 testsuite_teardown(void)
3968 free(test_params->pkt_eth_hdr);
3969 test_params->pkt_eth_hdr = NULL;
3971 /* Clean up and remove slaves from bonded device */
3972 remove_slaves_and_stop_bonded_device();
3976 free_virtualpmd_tx_queue(void)
3978 int i, slave_port, to_free_cnt;
3979 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
3981 /* Free tx queue of virtual pmd */
3982 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
3984 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
3985 test_params->slave_port_ids[slave_port],
3986 pkts_to_free, MAX_PKT_BURST);
3987 for (i = 0; i < to_free_cnt; i++)
3988 rte_pktmbuf_free(pkts_to_free[i]);
3993 test_tlb_tx_burst(void)
3995 int i, burst_size, nb_tx;
3996 uint64_t nb_tx2 = 0;
3997 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
3998 struct rte_eth_stats port_stats[32];
3999 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4002 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4003 (BONDING_MODE_TLB, 1, 3, 1),
4004 "Failed to initialise bonded device");
4006 burst_size = 20 * test_params->bonded_slave_count;
4008 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4009 "Burst size specified is greater than supported.\n");
4012 /* Generate bursts of packets */
4013 for (i = 0; i < 400000; i++) {
4014 /*test two types of mac src own(bonding) and others */
4016 initialize_eth_header(test_params->pkt_eth_hdr,
4017 (struct ether_addr *)src_mac,
4018 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4020 initialize_eth_header(test_params->pkt_eth_hdr,
4021 (struct ether_addr *)test_params->default_slave_mac,
4022 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4024 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4026 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4027 dst_addr_0, pktlen);
4028 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4029 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4030 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4031 /* Send burst on bonded port */
4032 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4036 free_virtualpmd_tx_queue();
4038 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4039 "number of packet not equal burst size");
4045 /* Verify bonded port tx stats */
4046 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4048 all_bond_opackets = port_stats[0].opackets;
4049 all_bond_obytes = port_stats[0].obytes;
4051 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4052 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4053 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4057 /* Verify slave ports tx stats */
4058 for (i = 0; i < test_params->bonded_slave_count; i++) {
4059 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4060 sum_ports_opackets += port_stats[i].opackets;
4063 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4064 "Total packets sent by slaves is not equal to packets sent by bond interface");
4066 /* checking if distribution of packets is balanced over slaves */
4067 for (i = 0; i < test_params->bonded_slave_count; i++) {
4068 TEST_ASSERT(port_stats[i].obytes > 0 &&
4069 port_stats[i].obytes < all_bond_obytes,
4070 "Packets are not balanced over slaves");
4073 /* Put all slaves down and try and transmit */
4074 for (i = 0; i < test_params->bonded_slave_count; i++) {
4075 virtual_ethdev_simulate_link_status_interrupt(
4076 test_params->slave_port_ids[i], 0);
4079 /* Send burst on bonded port */
4080 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4082 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4084 /* Clean ugit checkout masterp and remove slaves from bonded device */
4085 return remove_slaves_and_stop_bonded_device();
4088 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4091 test_tlb_rx_burst(void)
4093 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4094 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4096 struct rte_eth_stats port_stats;
4100 uint16_t i, j, nb_rx, burst_size = 17;
4102 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4103 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4105 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4106 "Failed to initialize bonded device");
4109 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4110 TEST_ASSERT(primary_port >= 0,
4111 "failed to get primary slave for bonded port (%d)",
4112 test_params->bonded_port_id);
4114 for (i = 0; i < test_params->bonded_slave_count; i++) {
4115 /* Generate test bursts of packets to transmit */
4116 TEST_ASSERT_EQUAL(generate_test_burst(
4117 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4118 "burst generation failed");
4120 /* Add rx data to slave */
4121 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4122 &gen_pkt_burst[0], burst_size);
4124 /* Call rx burst on bonded device */
4125 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4126 &rx_pkt_burst[0], MAX_PKT_BURST);
4128 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4130 if (test_params->slave_port_ids[i] == primary_port) {
4131 /* Verify bonded device rx count */
4132 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4133 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4134 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4135 test_params->bonded_port_id,
4136 (unsigned int)port_stats.ipackets, burst_size);
4138 /* Verify bonded slave devices rx count */
4139 for (j = 0; j < test_params->bonded_slave_count; j++) {
4140 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4142 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4143 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4144 test_params->slave_port_ids[i],
4145 (unsigned int)port_stats.ipackets, burst_size);
4147 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4148 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4149 test_params->slave_port_ids[i],
4150 (unsigned int)port_stats.ipackets, 0);
4154 for (j = 0; j < test_params->bonded_slave_count; j++) {
4155 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4156 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4157 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4158 test_params->slave_port_ids[i],
4159 (unsigned int)port_stats.ipackets, 0);
4164 for (i = 0; i < burst_size; i++)
4165 rte_pktmbuf_free(rx_pkt_burst[i]);
4167 /* reset bonded device stats */
4168 rte_eth_stats_reset(test_params->bonded_port_id);
4171 /* Clean up and remove slaves from bonded device */
4172 return remove_slaves_and_stop_bonded_device();
4176 test_tlb_verify_promiscuous_enable_disable(void)
4178 int i, primary_port, promiscuous_en;
4180 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4181 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4182 BONDING_MODE_TLB, 0, 4, 1),
4183 "Failed to initialize bonded device");
4185 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4186 TEST_ASSERT(primary_port >= 0,
4187 "failed to get primary slave for bonded port (%d)",
4188 test_params->bonded_port_id);
4190 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4192 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4193 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4194 "Port (%d) promiscuous mode not enabled\n",
4195 test_params->bonded_port_id);
4196 for (i = 0; i < test_params->bonded_slave_count; i++) {
4197 promiscuous_en = rte_eth_promiscuous_get(
4198 test_params->slave_port_ids[i]);
4199 if (primary_port == test_params->slave_port_ids[i]) {
4200 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4201 "Port (%d) promiscuous mode not enabled\n",
4202 test_params->bonded_port_id);
4204 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4205 "Port (%d) promiscuous mode enabled\n",
4206 test_params->bonded_port_id);
4211 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4213 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4214 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4215 "Port (%d) promiscuous mode not disabled\n",
4216 test_params->bonded_port_id);
4218 for (i = 0; i < test_params->bonded_slave_count; i++) {
4219 promiscuous_en = rte_eth_promiscuous_get(
4220 test_params->slave_port_ids[i]);
4221 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4222 "slave port (%d) promiscuous mode not disabled\n",
4223 test_params->slave_port_ids[i]);
4226 /* Clean up and remove slaves from bonded device */
4227 return remove_slaves_and_stop_bonded_device();
4231 test_tlb_verify_mac_assignment(void)
4233 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4235 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4236 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4238 /* Initialize bonded device with 2 slaves in active backup mode */
4239 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4240 BONDING_MODE_TLB, 0, 2, 1),
4241 "Failed to initialize bonded device");
4243 /* Verify that bonded MACs is that of first slave and that the other slave
4244 * MAC hasn't been changed */
4245 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4246 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4247 sizeof(read_mac_addr)),
4248 "bonded port (%d) mac address not set to that of primary port",
4249 test_params->bonded_port_id);
4251 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4252 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4253 sizeof(read_mac_addr)),
4254 "slave port (%d) mac address not set to that of primary port",
4255 test_params->slave_port_ids[0]);
4257 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4258 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4259 sizeof(read_mac_addr)),
4260 "slave port (%d) mac address not as expected",
4261 test_params->slave_port_ids[1]);
4263 /* change primary and verify that MAC addresses haven't changed */
4264 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4265 test_params->slave_port_ids[1]), 0,
4266 "Failed to set bonded port (%d) primary port to (%d)",
4267 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4269 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4270 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4271 sizeof(read_mac_addr)),
4272 "bonded port (%d) mac address not set to that of primary port",
4273 test_params->bonded_port_id);
4275 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4276 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4277 sizeof(read_mac_addr)),
4278 "slave port (%d) mac address not set to that of primary port",
4279 test_params->slave_port_ids[0]);
4281 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4282 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4283 sizeof(read_mac_addr)),
4284 "slave port (%d) mac address not as expected",
4285 test_params->slave_port_ids[1]);
4287 /* stop / start bonded device and verify that primary MAC address is
4288 * propagated to bonded device and slaves */
4290 rte_eth_dev_stop(test_params->bonded_port_id);
4292 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4293 "Failed to start device");
4295 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4296 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4297 sizeof(read_mac_addr)),
4298 "bonded port (%d) mac address not set to that of primary port",
4299 test_params->bonded_port_id);
4301 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4302 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4303 sizeof(read_mac_addr)),
4304 "slave port (%d) mac address not as expected",
4305 test_params->slave_port_ids[0]);
4307 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4308 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4309 sizeof(read_mac_addr)),
4310 "slave port (%d) mac address not set to that of primary port",
4311 test_params->slave_port_ids[1]);
4314 /* Set explicit MAC address */
4315 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4316 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4317 "failed to set MAC address");
4319 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4320 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4321 sizeof(read_mac_addr)),
4322 "bonded port (%d) mac address not set to that of bonded port",
4323 test_params->bonded_port_id);
4325 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4326 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4327 sizeof(read_mac_addr)),
4328 "slave port (%d) mac address not as expected",
4329 test_params->slave_port_ids[0]);
4331 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4332 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4333 sizeof(read_mac_addr)),
4334 "slave port (%d) mac address not set to that of bonded port",
4335 test_params->slave_port_ids[1]);
4337 /* Clean up and remove slaves from bonded device */
4338 return remove_slaves_and_stop_bonded_device();
4342 test_tlb_verify_slave_link_status_change_failover(void)
4344 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4345 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4346 struct rte_eth_stats port_stats;
4348 uint16_t slaves[RTE_MAX_ETHPORTS];
4350 int i, burst_size, slave_count, primary_port;
4354 memset(pkt_burst, 0, sizeof(pkt_burst));
4358 /* Initialize bonded device with 4 slaves in round robin mode */
4359 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4360 BONDING_MODE_TLB, 0,
4361 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4362 "Failed to initialize bonded device with slaves");
4364 /* Verify Current Slaves Count /Active Slave Count is */
4365 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4367 TEST_ASSERT_EQUAL(slave_count, 4,
4368 "Number of slaves (%d) is not as expected (%d).\n",
4371 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4372 slaves, RTE_MAX_ETHPORTS);
4373 TEST_ASSERT_EQUAL(slave_count, (int)4,
4374 "Number of slaves (%d) is not as expected (%d).\n",
4377 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4378 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4379 "Primary port not as expected");
4381 /* Bring 2 slaves down and verify active slave count */
4382 virtual_ethdev_simulate_link_status_interrupt(
4383 test_params->slave_port_ids[1], 0);
4384 virtual_ethdev_simulate_link_status_interrupt(
4385 test_params->slave_port_ids[3], 0);
4387 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4388 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4389 "Number of active slaves (%d) is not as expected (%d).",
4392 virtual_ethdev_simulate_link_status_interrupt(
4393 test_params->slave_port_ids[1], 1);
4394 virtual_ethdev_simulate_link_status_interrupt(
4395 test_params->slave_port_ids[3], 1);
4398 /* Bring primary port down, verify that active slave count is 3 and primary
4400 virtual_ethdev_simulate_link_status_interrupt(
4401 test_params->slave_port_ids[0], 0);
4403 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4404 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4405 "Number of active slaves (%d) is not as expected (%d).",
4408 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4409 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4410 "Primary port not as expected");
4411 rte_delay_us(500000);
4412 /* Verify that pkts are sent on new primary slave */
4413 for (i = 0; i < 4; i++) {
4414 TEST_ASSERT_EQUAL(generate_test_burst(
4415 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4416 "generate_test_burst failed\n");
4417 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4418 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4419 "rte_eth_tx_burst failed\n");
4420 rte_delay_us(11000);
4423 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4424 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4425 "(%d) port_stats.opackets not as expected\n",
4426 test_params->slave_port_ids[0]);
4428 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4429 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4430 "(%d) port_stats.opackets not as expected\n",
4431 test_params->slave_port_ids[1]);
4433 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4434 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4435 "(%d) port_stats.opackets not as expected\n",
4436 test_params->slave_port_ids[2]);
4438 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4439 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4440 "(%d) port_stats.opackets not as expected\n",
4441 test_params->slave_port_ids[3]);
4444 /* Generate packet burst for testing */
4446 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4447 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4451 virtual_ethdev_add_mbufs_to_rx_queue(
4452 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4455 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4456 MAX_PKT_BURST) != burst_size) {
4457 printf("rte_eth_rx_burst\n");
4462 /* Verify bonded device rx count */
4463 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4464 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4465 "(%d) port_stats.ipackets not as expected\n",
4466 test_params->bonded_port_id);
4468 /* Clean up and remove slaves from bonded device */
4469 return remove_slaves_and_stop_bonded_device();
4472 #define TEST_ALB_SLAVE_COUNT 2
4474 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4475 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4476 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4477 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4479 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4480 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4481 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4482 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4483 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4486 test_alb_change_mac_in_reply_sent(void)
4488 struct rte_mbuf *pkt;
4489 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4491 struct ether_hdr *eth_pkt;
4492 struct arp_hdr *arp_pkt;
4494 int slave_idx, nb_pkts, pkt_idx;
4497 struct ether_addr bond_mac, client_mac;
4498 struct ether_addr *slave_mac1, *slave_mac2;
4500 TEST_ASSERT_SUCCESS(
4501 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4502 0, TEST_ALB_SLAVE_COUNT, 1),
4503 "Failed to initialize_bonded_device_with_slaves.");
4505 /* Flush tx queue */
4506 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4507 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4509 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4510 test_params->slave_port_ids[slave_idx], pkts_sent,
4515 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4519 * Generating four packets with different mac and ip addresses and sending
4520 * them through the bonding port.
4522 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4523 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4524 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4525 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4527 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4528 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4530 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4532 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4533 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4534 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4535 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4537 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4538 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4540 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4542 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4543 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4544 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4545 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4547 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4548 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4550 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4552 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4553 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4554 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4555 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4557 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4558 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4560 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4563 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4565 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4568 * Checking if packets are properly distributed on bonding ports. Packets
4569 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4571 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4572 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4573 test_params->slave_port_ids[slave_idx], pkts_sent,
4576 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4577 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4578 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4580 if (slave_idx%2 == 0) {
4581 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4586 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4595 retval += remove_slaves_and_stop_bonded_device();
4600 test_alb_reply_from_client(void)
4602 struct ether_hdr *eth_pkt;
4603 struct arp_hdr *arp_pkt;
4605 struct rte_mbuf *pkt;
4606 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4608 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4611 struct ether_addr bond_mac, client_mac;
4612 struct ether_addr *slave_mac1, *slave_mac2;
4614 TEST_ASSERT_SUCCESS(
4615 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4616 0, TEST_ALB_SLAVE_COUNT, 1),
4617 "Failed to initialize_bonded_device_with_slaves.");
4619 /* Flush tx queue */
4620 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4621 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4622 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4623 test_params->slave_port_ids[slave_idx], pkts_sent,
4628 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4632 * Generating four packets with different mac and ip addresses and placing
4633 * them in the rx queue to be received by the bonding driver on rx_burst.
4635 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4636 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4637 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4638 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4640 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4641 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4643 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4646 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4647 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4648 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4649 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4651 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4652 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4654 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4657 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4658 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4659 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4660 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4662 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4663 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4665 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4668 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4669 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4670 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4671 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4673 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4674 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4676 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4680 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4681 * packets to every client in alb table.
4683 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4684 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4686 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4687 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4690 * Checking if update ARP packets were properly send on slave ports.
4692 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4693 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4694 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4695 nb_pkts_sum += nb_pkts;
4697 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4698 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4699 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4701 if (slave_idx%2 == 0) {
4702 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4707 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4715 /* Check if proper number of packets was send */
4716 if (nb_pkts_sum < 4) {
4722 retval += remove_slaves_and_stop_bonded_device();
4727 test_alb_receive_vlan_reply(void)
4729 struct ether_hdr *eth_pkt;
4730 struct vlan_hdr *vlan_pkt;
4731 struct arp_hdr *arp_pkt;
4733 struct rte_mbuf *pkt;
4734 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4736 int slave_idx, nb_pkts, pkt_idx;
4739 struct ether_addr bond_mac, client_mac;
4741 TEST_ASSERT_SUCCESS(
4742 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4743 0, TEST_ALB_SLAVE_COUNT, 1),
4744 "Failed to initialize_bonded_device_with_slaves.");
4746 /* Flush tx queue */
4747 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4748 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4749 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4750 test_params->slave_port_ids[slave_idx], pkts_sent,
4755 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4759 * Generating packet with double VLAN header and placing it in the rx queue.
4761 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4762 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4763 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4764 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4766 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4767 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4768 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4769 vlan_pkt = vlan_pkt+1;
4770 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4771 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4772 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4773 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4775 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4778 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4779 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4782 * Checking if VLAN headers in generated ARP Update packet are correct.
4784 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4785 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4786 test_params->slave_port_ids[slave_idx], pkts_sent,
4789 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4790 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4791 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4792 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4796 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4800 vlan_pkt = vlan_pkt+1;
4801 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4805 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4813 retval += remove_slaves_and_stop_bonded_device();
4818 test_alb_ipv4_tx(void)
4820 int burst_size, retval, pkts_send;
4821 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4825 TEST_ASSERT_SUCCESS(
4826 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4827 0, TEST_ALB_SLAVE_COUNT, 1),
4828 "Failed to initialize_bonded_device_with_slaves.");
4832 /* Generate test bursts of packets to transmit */
4833 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4839 * Checking if ipv4 traffic is transmitted via TLB policy.
4841 pkts_send = rte_eth_tx_burst(
4842 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4843 if (pkts_send != burst_size) {
4849 retval += remove_slaves_and_stop_bonded_device();
4853 static struct unit_test_suite link_bonding_test_suite = {
4854 .suite_name = "Link Bonding Unit Test Suite",
4855 .setup = test_setup,
4856 .teardown = testsuite_teardown,
4857 .unit_test_cases = {
4858 TEST_CASE(test_create_bonded_device),
4859 TEST_CASE(test_create_bonded_device_with_invalid_params),
4860 TEST_CASE(test_add_slave_to_bonded_device),
4861 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4862 TEST_CASE(test_remove_slave_from_bonded_device),
4863 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4864 TEST_CASE(test_get_slaves_from_bonded_device),
4865 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4866 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4867 TEST_CASE(test_start_bonded_device),
4868 TEST_CASE(test_stop_bonded_device),
4869 TEST_CASE(test_set_bonding_mode),
4870 TEST_CASE(test_set_primary_slave),
4871 TEST_CASE(test_set_explicit_bonded_mac),
4872 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4873 TEST_CASE(test_status_interrupt),
4874 TEST_CASE(test_adding_slave_after_bonded_device_started),
4875 TEST_CASE(test_roundrobin_tx_burst),
4876 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4877 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4878 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4879 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4880 TEST_CASE(test_roundrobin_verify_mac_assignment),
4881 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4882 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4883 TEST_CASE(test_activebackup_tx_burst),
4884 TEST_CASE(test_activebackup_rx_burst),
4885 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4886 TEST_CASE(test_activebackup_verify_mac_assignment),
4887 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4888 TEST_CASE(test_balance_xmit_policy_configuration),
4889 TEST_CASE(test_balance_l2_tx_burst),
4890 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4891 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4892 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4893 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4894 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4895 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4896 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4897 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4898 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4899 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4900 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4901 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4902 TEST_CASE(test_balance_rx_burst),
4903 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4904 TEST_CASE(test_balance_verify_mac_assignment),
4905 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4906 TEST_CASE(test_tlb_tx_burst),
4907 TEST_CASE(test_tlb_rx_burst),
4908 TEST_CASE(test_tlb_verify_mac_assignment),
4909 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4910 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4911 TEST_CASE(test_alb_change_mac_in_reply_sent),
4912 TEST_CASE(test_alb_reply_from_client),
4913 TEST_CASE(test_alb_receive_vlan_reply),
4914 TEST_CASE(test_alb_ipv4_tx),
4915 TEST_CASE(test_broadcast_tx_burst),
4916 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4917 TEST_CASE(test_broadcast_rx_burst),
4918 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4919 TEST_CASE(test_broadcast_verify_mac_assignment),
4920 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4921 TEST_CASE(test_reconfigure_bonded_device),
4922 TEST_CASE(test_close_bonded_device),
4924 TEST_CASES_END() /**< NULL terminate unit test array */
4930 test_link_bonding(void)
4932 return unit_test_suite_runner(&link_bonding_test_suite);
4935 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);