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>
21 #include <rte_lcore.h>
22 #include <rte_memory.h>
23 #include <rte_string_fns.h>
24 #include <rte_eth_bond.h>
26 #include "virtual_pmd.h"
27 #include "packet_burst_generator.h"
31 #define TEST_MAX_NUMBER_OF_PORTS (6)
33 #define RX_RING_SIZE 128
34 #define RX_FREE_THRESH 32
39 #define TX_RING_SIZE 512
40 #define TX_FREE_THRESH 32
44 #define TX_RSBIT_THRESH 32
45 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
46 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
47 ETH_TXQ_FLAGS_NOXSUMTCP)
49 #define MBUF_CACHE_SIZE (250)
50 #define BURST_SIZE (32)
52 #define RTE_TEST_RX_DESC_MAX (2048)
53 #define RTE_TEST_TX_DESC_MAX (2048)
54 #define MAX_PKT_BURST (512)
55 #define DEF_PKT_BURST (16)
57 #define BONDED_DEV_NAME ("net_bonding_ut")
59 #define INVALID_SOCKET_ID (-1)
60 #define INVALID_PORT_ID (-1)
61 #define INVALID_BONDING_MODE (-1)
64 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
65 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
67 struct link_bonding_unittest_params {
68 int16_t bonded_port_id;
69 int16_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
70 uint16_t bonded_slave_count;
76 struct rte_mempool *mbuf_pool;
78 struct ether_addr *default_slave_mac;
79 struct ether_addr *default_bonded_mac;
82 struct ether_hdr *pkt_eth_hdr;
83 struct ipv4_hdr *pkt_ipv4_hdr;
84 struct ipv6_hdr *pkt_ipv6_hdr;
85 struct udp_hdr *pkt_udp_hdr;
89 static struct ipv4_hdr pkt_ipv4_hdr;
90 static struct ipv6_hdr pkt_ipv6_hdr;
91 static struct udp_hdr pkt_udp_hdr;
93 static struct link_bonding_unittest_params default_params = {
95 .slave_port_ids = { -1 },
96 .bonded_slave_count = 0,
97 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
104 .default_slave_mac = (struct ether_addr *)slave_mac,
105 .default_bonded_mac = (struct ether_addr *)bonded_mac,
108 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
109 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
110 .pkt_udp_hdr = &pkt_udp_hdr
114 static struct link_bonding_unittest_params *test_params = &default_params;
116 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
117 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
118 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
120 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
121 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
122 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
124 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
125 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
126 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
127 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
128 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
129 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
131 static uint16_t src_port = 1024;
132 static uint16_t dst_port_0 = 1024;
133 static uint16_t dst_port_1 = 2024;
135 static uint16_t vlan_id = 0x100;
137 struct rte_eth_rxmode rx_mode = {
138 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
140 .header_split = 0, /**< Header Split disabled. */
141 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
142 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
143 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
144 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
145 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
146 .hw_strip_crc = 1, /**< CRC stripping by hardware enabled. */
149 struct rte_fdir_conf fdir_conf = {
150 .mode = RTE_FDIR_MODE_NONE,
151 .pballoc = RTE_FDIR_PBALLOC_64K,
152 .status = RTE_FDIR_REPORT_STATUS,
156 static struct rte_eth_conf default_pmd_conf = {
158 .mq_mode = ETH_MQ_RX_NONE,
159 .max_rx_pkt_len = ETHER_MAX_LEN,
161 .header_split = 0, /**< Header Split disabled */
162 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
163 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
164 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
165 .hw_strip_crc = 1, /**< CRC stripped by hardware */
168 .mq_mode = ETH_MQ_TX_NONE,
173 static const struct rte_eth_rxconf rx_conf_default = {
175 .pthresh = RX_PTHRESH,
176 .hthresh = RX_HTHRESH,
177 .wthresh = RX_WTHRESH,
179 .rx_free_thresh = RX_FREE_THRESH,
183 static struct rte_eth_txconf tx_conf_default = {
185 .pthresh = TX_PTHRESH,
186 .hthresh = TX_HTHRESH,
187 .wthresh = TX_WTHRESH,
189 .tx_free_thresh = TX_FREE_THRESH,
190 .tx_rs_thresh = TX_RSBIT_THRESH,
191 .txq_flags = TX_Q_FLAGS
195 static void free_virtualpmd_tx_queue(void);
200 configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
205 default_pmd_conf.intr_conf.lsc = 1;
207 default_pmd_conf.intr_conf.lsc = 0;
209 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
210 test_params->nb_tx_q, &default_pmd_conf),
211 "rte_eth_dev_configure for port %d failed", port_id);
213 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
214 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
215 rte_eth_dev_socket_id(port_id), &rx_conf_default,
216 test_params->mbuf_pool) ,
217 "rte_eth_rx_queue_setup for port %d failed", port_id);
219 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
220 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
221 rte_eth_dev_socket_id(port_id), &tx_conf_default),
222 "rte_eth_tx_queue_setup for port %d failed", port_id);
225 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
226 "rte_eth_dev_start for port %d failed", port_id);
231 static int slaves_initialized;
233 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
234 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
240 int i, nb_mbuf_per_pool;
241 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
243 /* Allocate ethernet packet header with space for VLAN header */
244 if (test_params->pkt_eth_hdr == NULL) {
245 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
246 sizeof(struct vlan_hdr));
248 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
249 "Ethernet header struct allocation failed!");
252 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
253 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
254 if (test_params->mbuf_pool == NULL) {
255 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
256 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
257 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
258 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
259 "rte_mempool_create failed");
262 /* Create / Initialize virtual eth devs */
263 if (!slaves_initialized) {
264 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
265 char pmd_name[RTE_ETH_NAME_MAX_LEN];
267 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
269 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
271 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
272 mac_addr, rte_socket_id(), 1);
273 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
274 "Failed to create virtual virtual ethdev %s", pmd_name);
276 TEST_ASSERT_SUCCESS(configure_ethdev(
277 test_params->slave_port_ids[i], 1, 0),
278 "Failed to configure virtual ethdev %s", pmd_name);
280 slaves_initialized = 1;
287 test_create_bonded_device(void)
289 int current_slave_count;
291 uint16_t slaves[RTE_MAX_ETHPORTS];
293 /* Don't try to recreate bonded device if re-running test suite*/
294 if (test_params->bonded_port_id == -1) {
295 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
296 test_params->bonding_mode, rte_socket_id());
298 TEST_ASSERT(test_params->bonded_port_id >= 0,
299 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
301 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
302 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
305 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
306 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
307 test_params->bonded_port_id, test_params->bonding_mode);
309 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
310 slaves, RTE_MAX_ETHPORTS);
312 TEST_ASSERT_EQUAL(current_slave_count, 0,
313 "Number of slaves %d is great than expected %d.",
314 current_slave_count, 0);
316 current_slave_count = rte_eth_bond_active_slaves_get(
317 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
319 TEST_ASSERT_EQUAL(current_slave_count, 0,
320 "Number of active slaves %d is great than expected %d.",
321 current_slave_count, 0);
328 test_create_bonded_device_with_invalid_params(void)
332 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
335 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
337 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
339 test_params->bonding_mode = INVALID_BONDING_MODE;
341 /* Invalid bonding mode */
342 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
344 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
346 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
348 /* Invalid socket id */
349 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
351 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
357 test_add_slave_to_bonded_device(void)
359 int current_slave_count;
361 uint16_t slaves[RTE_MAX_ETHPORTS];
363 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
364 test_params->slave_port_ids[test_params->bonded_slave_count]),
365 "Failed to add slave (%d) to bonded port (%d).",
366 test_params->slave_port_ids[test_params->bonded_slave_count],
367 test_params->bonded_port_id);
369 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
370 slaves, RTE_MAX_ETHPORTS);
371 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
372 "Number of slaves (%d) is greater than expected (%d).",
373 current_slave_count, test_params->bonded_slave_count + 1);
375 current_slave_count = rte_eth_bond_active_slaves_get(
376 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
377 TEST_ASSERT_EQUAL(current_slave_count, 0,
378 "Number of active slaves (%d) is not as expected (%d).\n",
379 current_slave_count, 0);
381 test_params->bonded_slave_count++;
387 test_add_slave_to_invalid_bonded_device(void)
389 /* Invalid port ID */
390 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
391 test_params->slave_port_ids[test_params->bonded_slave_count]),
392 "Expected call to failed as invalid port specified.");
394 /* Non bonded device */
395 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
396 test_params->slave_port_ids[test_params->bonded_slave_count]),
397 "Expected call to failed as invalid port specified.");
404 test_remove_slave_from_bonded_device(void)
406 int current_slave_count;
407 struct ether_addr read_mac_addr, *mac_addr;
408 uint16_t slaves[RTE_MAX_ETHPORTS];
410 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
411 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
412 "Failed to remove slave %d from bonded port (%d).",
413 test_params->slave_port_ids[test_params->bonded_slave_count-1],
414 test_params->bonded_port_id);
417 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
418 slaves, RTE_MAX_ETHPORTS);
420 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
421 "Number of slaves (%d) is great than expected (%d).\n",
422 current_slave_count, test_params->bonded_slave_count - 1);
425 mac_addr = (struct ether_addr *)slave_mac;
426 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
427 test_params->bonded_slave_count-1;
430 test_params->slave_port_ids[test_params->bonded_slave_count-1],
432 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
433 "bonded port mac address not set to that of primary port\n");
436 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
438 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
441 test_params->bonded_slave_count--;
447 test_remove_slave_from_invalid_bonded_device(void)
449 /* Invalid port ID */
450 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
451 test_params->bonded_port_id + 5,
452 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
453 "Expected call to failed as invalid port specified.");
455 /* Non bonded device */
456 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
457 test_params->slave_port_ids[0],
458 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
459 "Expected call to failed as invalid port specified.");
464 static int bonded_id = 2;
467 test_add_already_bonded_slave_to_bonded_device(void)
469 int port_id, current_slave_count;
470 uint16_t slaves[RTE_MAX_ETHPORTS];
471 char pmd_name[RTE_ETH_NAME_MAX_LEN];
473 test_add_slave_to_bonded_device();
475 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
476 slaves, RTE_MAX_ETHPORTS);
477 TEST_ASSERT_EQUAL(current_slave_count, 1,
478 "Number of slaves (%d) is not that expected (%d).",
479 current_slave_count, 1);
481 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
483 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
485 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
487 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
488 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
490 "Added slave (%d) to bonded port (%d) unexpectedly.",
491 test_params->slave_port_ids[test_params->bonded_slave_count-1],
494 return test_remove_slave_from_bonded_device();
499 test_get_slaves_from_bonded_device(void)
501 int current_slave_count;
502 uint16_t slaves[RTE_MAX_ETHPORTS];
504 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
505 "Failed to add slave to bonded device");
507 /* Invalid port id */
508 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
510 TEST_ASSERT(current_slave_count < 0,
511 "Invalid port id unexpectedly succeeded");
513 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
514 slaves, RTE_MAX_ETHPORTS);
515 TEST_ASSERT(current_slave_count < 0,
516 "Invalid port id unexpectedly succeeded");
518 /* Invalid slaves pointer */
519 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
520 NULL, RTE_MAX_ETHPORTS);
521 TEST_ASSERT(current_slave_count < 0,
522 "Invalid slave array unexpectedly succeeded");
524 current_slave_count = rte_eth_bond_active_slaves_get(
525 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
526 TEST_ASSERT(current_slave_count < 0,
527 "Invalid slave array unexpectedly succeeded");
529 /* non bonded device*/
530 current_slave_count = rte_eth_bond_slaves_get(
531 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
532 TEST_ASSERT(current_slave_count < 0,
533 "Invalid port id unexpectedly succeeded");
535 current_slave_count = rte_eth_bond_active_slaves_get(
536 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
537 TEST_ASSERT(current_slave_count < 0,
538 "Invalid port id unexpectedly succeeded");
540 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
541 "Failed to remove slaves from bonded device");
548 test_add_remove_multiple_slaves_to_from_bonded_device(void)
552 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
553 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
554 "Failed to add slave to bonded device");
556 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
557 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
558 "Failed to remove slaves from bonded device");
564 enable_bonded_slaves(void)
568 for (i = 0; i < test_params->bonded_slave_count; i++) {
569 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
572 virtual_ethdev_simulate_link_status_interrupt(
573 test_params->slave_port_ids[i], 1);
578 test_start_bonded_device(void)
580 struct rte_eth_link link_status;
582 int current_slave_count, current_bonding_mode, primary_port;
583 uint16_t slaves[RTE_MAX_ETHPORTS];
585 /* Add slave to bonded device*/
586 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
587 "Failed to add slave to bonded device");
589 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
590 "Failed to start bonded pmd eth device %d.",
591 test_params->bonded_port_id);
593 /* Change link status of virtual pmd so it will be added to the active
594 * slave list of the bonded device*/
595 virtual_ethdev_simulate_link_status_interrupt(
596 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
598 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
599 slaves, RTE_MAX_ETHPORTS);
600 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
601 "Number of slaves (%d) is not expected value (%d).",
602 current_slave_count, test_params->bonded_slave_count);
604 current_slave_count = rte_eth_bond_active_slaves_get(
605 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
606 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
607 "Number of active slaves (%d) is not expected value (%d).",
608 current_slave_count, test_params->bonded_slave_count);
610 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
611 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
612 "Bonded device mode (%d) is not expected value (%d).\n",
613 current_bonding_mode, test_params->bonding_mode);
615 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
616 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
617 "Primary port (%d) is not expected value (%d).",
618 primary_port, test_params->slave_port_ids[0]);
620 rte_eth_link_get(test_params->bonded_port_id, &link_status);
621 TEST_ASSERT_EQUAL(link_status.link_status, 1,
622 "Bonded port (%d) status (%d) is not expected value (%d).\n",
623 test_params->bonded_port_id, link_status.link_status, 1);
629 test_stop_bonded_device(void)
631 int current_slave_count;
632 uint16_t slaves[RTE_MAX_ETHPORTS];
634 struct rte_eth_link link_status;
636 rte_eth_dev_stop(test_params->bonded_port_id);
638 rte_eth_link_get(test_params->bonded_port_id, &link_status);
639 TEST_ASSERT_EQUAL(link_status.link_status, 0,
640 "Bonded port (%d) status (%d) is not expected value (%d).",
641 test_params->bonded_port_id, link_status.link_status, 0);
643 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
644 slaves, RTE_MAX_ETHPORTS);
645 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
646 "Number of slaves (%d) is not expected value (%d).",
647 current_slave_count, test_params->bonded_slave_count);
649 current_slave_count = rte_eth_bond_active_slaves_get(
650 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
651 TEST_ASSERT_EQUAL(current_slave_count, 0,
652 "Number of active slaves (%d) is not expected value (%d).",
653 current_slave_count, 0);
659 remove_slaves_and_stop_bonded_device(void)
661 /* Clean up and remove slaves from bonded device */
662 free_virtualpmd_tx_queue();
663 while (test_params->bonded_slave_count > 0)
664 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
665 "test_remove_slave_from_bonded_device failed");
667 rte_eth_dev_stop(test_params->bonded_port_id);
668 rte_eth_stats_reset(test_params->bonded_port_id);
669 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
675 test_set_bonding_mode(void)
679 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
680 BONDING_MODE_ACTIVE_BACKUP,
681 BONDING_MODE_BALANCE,
682 BONDING_MODE_BROADCAST
685 /* Test supported link bonding modes */
686 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
687 /* Invalid port ID */
688 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
690 "Expected call to failed as invalid port (%d) specified.",
693 /* Non bonded device */
694 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
696 "Expected call to failed as invalid port (%d) specified.",
697 test_params->slave_port_ids[0]);
699 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
701 "Failed to set link bonding mode on port (%d) to (%d).",
702 test_params->bonded_port_id, bonding_modes[i]);
704 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
705 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
706 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
707 bonding_mode, test_params->bonded_port_id,
710 /* Invalid port ID */
711 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
712 TEST_ASSERT(bonding_mode < 0,
713 "Expected call to failed as invalid port (%d) specified.",
716 /* Non bonded device */
717 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
718 TEST_ASSERT(bonding_mode < 0,
719 "Expected call to failed as invalid port (%d) specified.",
720 test_params->slave_port_ids[0]);
723 return remove_slaves_and_stop_bonded_device();
727 test_set_primary_slave(void)
730 struct ether_addr read_mac_addr;
731 struct ether_addr *expected_mac_addr;
733 /* Add 4 slaves to bonded device */
734 for (i = test_params->bonded_slave_count; i < 4; i++)
735 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
736 "Failed to add slave to bonded device.");
738 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
739 BONDING_MODE_ROUND_ROBIN),
740 "Failed to set link bonding mode on port (%d) to (%d).",
741 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
743 /* Invalid port ID */
744 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
745 test_params->slave_port_ids[i]),
746 "Expected call to failed as invalid port specified.");
748 /* Non bonded device */
749 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
750 test_params->slave_port_ids[i]),
751 "Expected call to failed as invalid port specified.");
753 /* Set slave as primary
754 * Verify slave it is now primary slave
755 * Verify that MAC address of bonded device is that of primary slave
756 * Verify that MAC address of all bonded slaves are that of primary slave
758 for (i = 0; i < 4; i++) {
759 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
760 test_params->slave_port_ids[i]),
761 "Failed to set bonded port (%d) primary port to (%d)",
762 test_params->bonded_port_id, test_params->slave_port_ids[i]);
764 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
765 TEST_ASSERT(retval >= 0,
766 "Failed to read primary port from bonded port (%d)\n",
767 test_params->bonded_port_id);
769 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
770 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
771 test_params->bonded_port_id, retval,
772 test_params->slave_port_ids[i]);
774 /* stop/start bonded eth dev to apply new MAC */
775 rte_eth_dev_stop(test_params->bonded_port_id);
777 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
778 "Failed to start bonded port %d",
779 test_params->bonded_port_id);
781 expected_mac_addr = (struct ether_addr *)&slave_mac;
782 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
784 /* Check primary slave MAC */
785 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
786 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
787 sizeof(read_mac_addr)),
788 "bonded port mac address not set to that of primary port\n");
790 /* Check bonded MAC */
791 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
792 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
793 sizeof(read_mac_addr)),
794 "bonded port mac address not set to that of primary port\n");
796 /* Check other slaves MACs */
797 for (j = 0; j < 4; j++) {
799 rte_eth_macaddr_get(test_params->slave_port_ids[j],
801 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
802 sizeof(read_mac_addr)),
803 "slave port mac address not set to that of primary "
810 /* Test with none existent port */
811 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
812 "read primary port from expectedly");
814 /* Test with slave port */
815 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
816 "read primary port from expectedly\n");
818 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
819 "Failed to stop and remove slaves from bonded device");
822 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
823 "read primary port from expectedly\n");
829 test_set_explicit_bonded_mac(void)
832 struct ether_addr read_mac_addr;
833 struct ether_addr *mac_addr;
835 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
837 mac_addr = (struct ether_addr *)explicit_bonded_mac;
839 /* Invalid port ID */
840 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
841 "Expected call to failed as invalid port specified.");
843 /* Non bonded device */
844 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
845 test_params->slave_port_ids[0], mac_addr),
846 "Expected call to failed as invalid port specified.");
848 /* NULL MAC address */
849 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
850 test_params->bonded_port_id, NULL),
851 "Expected call to failed as NULL MAC specified");
853 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
854 test_params->bonded_port_id, mac_addr),
855 "Failed to set MAC address on bonded port (%d)",
856 test_params->bonded_port_id);
858 /* Add 4 slaves to bonded device */
859 for (i = test_params->bonded_slave_count; i < 4; i++) {
860 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
861 "Failed to add slave to bonded device.\n");
864 /* Check bonded MAC */
865 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
866 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
867 "bonded port mac address not set to that of primary port");
869 /* Check other slaves MACs */
870 for (i = 0; i < 4; i++) {
871 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
872 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
873 sizeof(read_mac_addr)),
874 "slave port mac address not set to that of primary port");
877 /* test resetting mac address on bonded device */
879 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
880 "Failed to reset MAC address on bonded port (%d)",
881 test_params->bonded_port_id);
884 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
885 "Reset MAC address on bonded port (%d) unexpectedly",
886 test_params->slave_port_ids[1]);
888 /* test resetting mac address on bonded device with no slaves */
889 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
890 "Failed to remove slaves and stop bonded device");
892 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
893 "Failed to reset MAC address on bonded port (%d)",
894 test_params->bonded_port_id);
899 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
902 test_set_bonded_port_initialization_mac_assignment(void)
904 int i, slave_count, bonded_port_id;
906 uint16_t slaves[RTE_MAX_ETHPORTS];
907 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
909 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
911 /* Initialize default values for MAC addresses */
912 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
913 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
916 * 1. a - Create / configure bonded / slave ethdevs
918 bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
919 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
920 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
922 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
923 "Failed to configure bonded ethdev");
925 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
926 char pmd_name[RTE_ETH_NAME_MAX_LEN];
928 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
930 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
932 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
933 &slave_mac_addr, rte_socket_id(), 1);
935 TEST_ASSERT(slave_port_ids[i] >= 0,
936 "Failed to create slave ethdev %s", pmd_name);
938 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
939 "Failed to configure virtual ethdev %s",
945 * 2. Add slave ethdevs to bonded device
947 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
948 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
950 "Failed to add slave (%d) to bonded port (%d).",
951 slave_port_ids[i], bonded_port_id);
954 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
956 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
957 "Number of slaves (%d) is not as expected (%d)",
958 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
962 * 3. Set explicit MAC address on bonded ethdev
964 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
965 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
967 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
968 bonded_port_id, &bonded_mac_addr),
969 "Failed to set MAC address on bonded port (%d)",
973 /* 4. a - Start bonded ethdev
974 * b - Enable slave devices
975 * c - Verify bonded/slaves ethdev MAC addresses
977 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
978 "Failed to start bonded pmd eth device %d.",
981 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
982 virtual_ethdev_simulate_link_status_interrupt(
983 slave_port_ids[i], 1);
986 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
987 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
988 sizeof(read_mac_addr)),
989 "bonded port mac address not as expected");
991 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
992 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
993 sizeof(read_mac_addr)),
994 "slave port 0 mac address not as expected");
996 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
997 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
998 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
999 sizeof(read_mac_addr)),
1000 "slave port 1 mac address not as expected");
1002 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1003 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1004 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1005 sizeof(read_mac_addr)),
1006 "slave port 2 mac address not as expected");
1009 /* 7. a - Change primary port
1010 * b - Stop / Start bonded port
1011 * d - Verify slave ethdev MAC addresses
1013 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1015 "failed to set primary port on bonded device.");
1017 rte_eth_dev_stop(bonded_port_id);
1018 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1019 "Failed to start bonded pmd eth device %d.",
1022 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1023 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1024 sizeof(read_mac_addr)),
1025 "bonded port mac address not as expected");
1027 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1028 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1029 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1030 sizeof(read_mac_addr)),
1031 "slave port 0 mac address not as expected");
1033 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1034 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1035 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1036 sizeof(read_mac_addr)),
1037 "slave port 1 mac address not as expected");
1039 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1040 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1041 sizeof(read_mac_addr)),
1042 "slave port 2 mac address not as expected");
1044 /* 6. a - Stop bonded ethdev
1045 * b - remove slave ethdevs
1046 * c - Verify slave ethdevs MACs are restored
1048 rte_eth_dev_stop(bonded_port_id);
1050 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1051 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1053 "Failed to remove slave %d from bonded port (%d).",
1054 slave_port_ids[i], bonded_port_id);
1057 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1060 TEST_ASSERT_EQUAL(slave_count, 0,
1061 "Number of slaves (%d) is great than expected (%d).",
1064 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1065 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1066 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1067 sizeof(read_mac_addr)),
1068 "slave port 0 mac address not as expected");
1070 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1071 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1072 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1073 sizeof(read_mac_addr)),
1074 "slave port 1 mac address not as expected");
1076 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1077 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1078 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1079 sizeof(read_mac_addr)),
1080 "slave port 2 mac address not as expected");
1087 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1088 uint16_t number_of_slaves, uint8_t enable_slave)
1090 /* Configure bonded device */
1091 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1092 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1093 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1096 /* Add slaves to bonded device */
1097 while (number_of_slaves > test_params->bonded_slave_count)
1098 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1099 "Failed to add slave (%d to bonding port (%d).",
1100 test_params->bonded_slave_count - 1,
1101 test_params->bonded_port_id);
1103 /* Set link bonding mode */
1104 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1106 "Failed to set link bonding mode on port (%d) to (%d).",
1107 test_params->bonded_port_id, bonding_mode);
1109 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1110 "Failed to start bonded pmd eth device %d.",
1111 test_params->bonded_port_id);
1114 enable_bonded_slaves();
1120 test_adding_slave_after_bonded_device_started(void)
1124 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1125 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1126 "Failed to add slaves to bonded device");
1128 /* Enabled slave devices */
1129 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1130 virtual_ethdev_simulate_link_status_interrupt(
1131 test_params->slave_port_ids[i], 1);
1134 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1135 test_params->slave_port_ids[test_params->bonded_slave_count]),
1136 "Failed to add slave to bonded port.\n");
1138 rte_eth_stats_reset(
1139 test_params->slave_port_ids[test_params->bonded_slave_count]);
1141 test_params->bonded_slave_count++;
1143 return remove_slaves_and_stop_bonded_device();
1146 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1147 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1149 int test_lsc_interrupt_count;
1153 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1154 enum rte_eth_event_type type __rte_unused,
1155 void *param __rte_unused,
1156 void *ret_param __rte_unused)
1158 pthread_mutex_lock(&mutex);
1159 test_lsc_interrupt_count++;
1161 pthread_cond_signal(&cvar);
1162 pthread_mutex_unlock(&mutex);
1168 lsc_timeout(int wait_us)
1175 gettimeofday(&tp, NULL);
1177 /* Convert from timeval to timespec */
1178 ts.tv_sec = tp.tv_sec;
1179 ts.tv_nsec = tp.tv_usec * 1000;
1180 ts.tv_nsec += wait_us * 1000;
1182 pthread_mutex_lock(&mutex);
1183 if (test_lsc_interrupt_count < 1)
1184 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1186 pthread_mutex_unlock(&mutex);
1188 if (retval == 0 && test_lsc_interrupt_count < 1)
1195 test_status_interrupt(void)
1198 uint16_t slaves[RTE_MAX_ETHPORTS];
1200 /* initialized bonding device with T slaves */
1201 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1202 BONDING_MODE_ROUND_ROBIN, 1,
1203 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1204 "Failed to initialise bonded device");
1206 test_lsc_interrupt_count = 0;
1208 /* register link status change interrupt callback */
1209 rte_eth_dev_callback_register(test_params->bonded_port_id,
1210 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1211 &test_params->bonded_port_id);
1213 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1214 slaves, RTE_MAX_ETHPORTS);
1216 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1217 "Number of active slaves (%d) is not as expected (%d)",
1218 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1220 /* Bring all 4 slaves link status to down and test that we have received a
1222 virtual_ethdev_simulate_link_status_interrupt(
1223 test_params->slave_port_ids[0], 0);
1224 virtual_ethdev_simulate_link_status_interrupt(
1225 test_params->slave_port_ids[1], 0);
1226 virtual_ethdev_simulate_link_status_interrupt(
1227 test_params->slave_port_ids[2], 0);
1229 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1230 "Received a link status change interrupt unexpectedly");
1232 virtual_ethdev_simulate_link_status_interrupt(
1233 test_params->slave_port_ids[3], 0);
1235 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1236 "timed out waiting for interrupt");
1238 TEST_ASSERT(test_lsc_interrupt_count > 0,
1239 "Did not receive link status change interrupt");
1241 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1242 slaves, RTE_MAX_ETHPORTS);
1244 TEST_ASSERT_EQUAL(slave_count, 0,
1245 "Number of active slaves (%d) is not as expected (%d)",
1248 /* bring one slave port up so link status will change */
1249 test_lsc_interrupt_count = 0;
1251 virtual_ethdev_simulate_link_status_interrupt(
1252 test_params->slave_port_ids[0], 1);
1254 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1255 "timed out waiting for interrupt");
1257 /* test that we have received another lsc interrupt */
1258 TEST_ASSERT(test_lsc_interrupt_count > 0,
1259 "Did not receive link status change interrupt");
1261 /* Verify that calling the same slave lsc interrupt doesn't cause another
1262 * lsc interrupt from bonded device */
1263 test_lsc_interrupt_count = 0;
1265 virtual_ethdev_simulate_link_status_interrupt(
1266 test_params->slave_port_ids[0], 1);
1268 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1269 "received unexpected interrupt");
1271 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1272 "Did not receive link status change interrupt");
1275 /* unregister lsc callback before exiting */
1276 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1277 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1278 &test_params->bonded_port_id);
1280 /* Clean up and remove slaves from bonded device */
1281 return remove_slaves_and_stop_bonded_device();
1285 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1286 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1287 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1289 uint16_t pktlen, generated_burst_size, ether_type;
1293 ether_type = ETHER_TYPE_IPv4;
1295 ether_type = ETHER_TYPE_IPv6;
1298 initialize_eth_header(test_params->pkt_eth_hdr,
1299 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1300 ether_type, vlan, vlan_id);
1302 initialize_eth_header(test_params->pkt_eth_hdr,
1303 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1304 ether_type, vlan, vlan_id);
1307 if (toggle_udp_port)
1308 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1311 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1316 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1317 dst_addr_1, pktlen);
1319 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1320 dst_addr_0, pktlen);
1322 ip_hdr = test_params->pkt_ipv4_hdr;
1325 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1326 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1329 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1330 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1333 ip_hdr = test_params->pkt_ipv6_hdr;
1336 /* Generate burst of packets to transmit */
1337 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1338 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1339 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1341 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1342 "Failed to generate packet burst");
1344 return generated_burst_size;
1347 /** Round Robin Mode Tests */
1350 test_roundrobin_tx_burst(void)
1353 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1354 struct rte_eth_stats port_stats;
1356 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1357 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1358 "Failed to initialise bonded device");
1360 burst_size = 20 * test_params->bonded_slave_count;
1362 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1363 "Burst size specified is greater than supported.");
1365 /* Generate test bursts of packets to transmit */
1366 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1367 burst_size, "failed to generate test burst");
1369 /* Send burst on bonded port */
1370 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1371 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1374 /* Verify bonded port tx stats */
1375 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1376 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1377 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1378 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1381 /* Verify slave ports tx stats */
1382 for (i = 0; i < test_params->bonded_slave_count; i++) {
1383 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1384 TEST_ASSERT_EQUAL(port_stats.opackets,
1385 (uint64_t)burst_size / test_params->bonded_slave_count,
1386 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1387 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1388 burst_size / test_params->bonded_slave_count);
1391 /* Put all slaves down and try and transmit */
1392 for (i = 0; i < test_params->bonded_slave_count; i++) {
1393 virtual_ethdev_simulate_link_status_interrupt(
1394 test_params->slave_port_ids[i], 0);
1397 /* Send burst on bonded port */
1398 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1399 pkt_burst, burst_size), 0,
1400 "tx burst return unexpected value");
1402 /* Clean up and remove slaves from bonded device */
1403 return remove_slaves_and_stop_bonded_device();
1407 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1411 for (i = 0; i < nb_mbufs; i++) {
1412 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1413 TEST_ASSERT_EQUAL(refcnt, val,
1414 "mbuf ref count (%d)is not the expected value (%d)",
1421 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1425 for (i = 0; i < nb_mbufs; i++)
1426 rte_pktmbuf_free(mbufs[i]);
1429 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1430 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1431 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1432 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1435 test_roundrobin_tx_burst_slave_tx_fail(void)
1437 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1438 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1440 struct rte_eth_stats port_stats;
1442 int i, first_fail_idx, tx_count;
1444 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1445 BONDING_MODE_ROUND_ROBIN, 0,
1446 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1447 "Failed to initialise bonded device");
1449 /* Generate test bursts of packets to transmit */
1450 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1451 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1452 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1453 "Failed to generate test packet burst");
1455 /* Copy references to packets which we expect not to be transmitted */
1456 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1457 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1458 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1459 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1461 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1462 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1463 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1466 /* Set virtual slave to only fail transmission of
1467 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1468 virtual_ethdev_tx_burst_fn_set_success(
1469 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1472 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1473 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1474 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1476 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1477 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1479 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1480 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1481 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1482 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1483 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1485 /* Verify that failed packet are expected failed packets */
1486 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1487 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1488 "expected mbuf (%d) pointer %p not expected pointer %p",
1489 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1492 /* Verify bonded port tx stats */
1493 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1495 TEST_ASSERT_EQUAL(port_stats.opackets,
1496 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1497 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1498 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1499 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1500 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1501 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1503 /* Verify slave ports tx stats */
1504 for (i = 0; i < test_params->bonded_slave_count; i++) {
1505 int slave_expected_tx_count;
1507 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1509 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1510 test_params->bonded_slave_count;
1512 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1513 slave_expected_tx_count = slave_expected_tx_count -
1514 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1516 TEST_ASSERT_EQUAL(port_stats.opackets,
1517 (uint64_t)slave_expected_tx_count,
1518 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1519 test_params->slave_port_ids[i],
1520 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1523 /* Verify that all mbufs have a ref value of zero */
1524 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1525 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1526 "mbufs refcnts not as expected");
1527 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1529 /* Clean up and remove slaves from bonded device */
1530 return remove_slaves_and_stop_bonded_device();
1534 test_roundrobin_rx_burst_on_single_slave(void)
1536 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1537 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1539 struct rte_eth_stats port_stats;
1541 int i, j, burst_size = 25;
1543 /* Initialize bonded device with 4 slaves in round robin mode */
1544 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1545 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1546 "Failed to initialize bonded device with slaves");
1548 /* Generate test bursts of packets to transmit */
1549 TEST_ASSERT_EQUAL(generate_test_burst(
1550 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1551 "burst generation failed");
1553 for (i = 0; i < test_params->bonded_slave_count; i++) {
1554 /* Add rx data to slave */
1555 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1556 &gen_pkt_burst[0], burst_size);
1558 /* Call rx burst on bonded device */
1559 /* Send burst on bonded port */
1560 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1561 test_params->bonded_port_id, 0, rx_pkt_burst,
1562 MAX_PKT_BURST), burst_size,
1563 "round-robin rx burst failed");
1565 /* Verify bonded device rx count */
1566 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1567 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1568 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1569 test_params->bonded_port_id,
1570 (unsigned int)port_stats.ipackets, burst_size);
1574 /* Verify bonded slave devices rx count */
1575 /* Verify slave ports tx stats */
1576 for (j = 0; j < test_params->bonded_slave_count; j++) {
1577 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1580 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1581 "Slave Port (%d) ipackets value (%u) not as expected"
1582 " (%d)", test_params->slave_port_ids[i],
1583 (unsigned int)port_stats.ipackets, burst_size);
1585 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1586 "Slave Port (%d) ipackets value (%u) not as expected"
1587 " (%d)", test_params->slave_port_ids[i],
1588 (unsigned int)port_stats.ipackets, 0);
1591 /* Reset bonded slaves stats */
1592 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1594 /* reset bonded device stats */
1595 rte_eth_stats_reset(test_params->bonded_port_id);
1599 for (i = 0; i < MAX_PKT_BURST; i++) {
1600 if (rx_pkt_burst[i] != NULL)
1601 rte_pktmbuf_free(rx_pkt_burst[i]);
1605 /* Clean up and remove slaves from bonded device */
1606 return remove_slaves_and_stop_bonded_device();
1609 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1612 test_roundrobin_rx_burst_on_multiple_slaves(void)
1614 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1616 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1617 struct rte_eth_stats port_stats;
1619 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1622 /* Initialize bonded device with 4 slaves in round robin mode */
1623 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1624 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1625 "Failed to initialize bonded device with slaves");
1627 /* Generate test bursts of packets to transmit */
1628 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1629 TEST_ASSERT_EQUAL(generate_test_burst(
1630 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1631 burst_size[i], "burst generation failed");
1634 /* Add rx data to slaves */
1635 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1636 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1637 &gen_pkt_burst[i][0], burst_size[i]);
1640 /* Call rx burst on bonded device */
1641 /* Send burst on bonded port */
1642 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1644 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1645 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1646 burst_size[0] + burst_size[1] + burst_size[2]);
1648 /* Verify bonded device rx count */
1649 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1650 TEST_ASSERT_EQUAL(port_stats.ipackets,
1651 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1652 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1653 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1654 burst_size[0] + burst_size[1] + burst_size[2]);
1656 /* Verify bonded slave devices rx counts */
1657 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1658 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1659 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1660 test_params->slave_port_ids[0],
1661 (unsigned int)port_stats.ipackets, burst_size[0]);
1663 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1664 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1665 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1666 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1669 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1670 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1671 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1672 test_params->slave_port_ids[2],
1673 (unsigned int)port_stats.ipackets, burst_size[2]);
1675 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1676 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1677 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1678 test_params->slave_port_ids[3],
1679 (unsigned int)port_stats.ipackets, 0);
1682 for (i = 0; i < MAX_PKT_BURST; i++) {
1683 if (rx_pkt_burst[i] != NULL)
1684 rte_pktmbuf_free(rx_pkt_burst[i]);
1687 /* Clean up and remove slaves from bonded device */
1688 return remove_slaves_and_stop_bonded_device();
1692 test_roundrobin_verify_mac_assignment(void)
1694 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1698 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1699 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1701 /* Initialize bonded device with 4 slaves in round robin mode */
1702 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1703 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1704 "Failed to initialize bonded device with slaves");
1706 /* Verify that all MACs are the same as first slave added to bonded dev */
1707 for (i = 0; i < test_params->bonded_slave_count; i++) {
1708 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1709 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1710 sizeof(read_mac_addr)),
1711 "slave port (%d) mac address not set to that of primary port",
1712 test_params->slave_port_ids[i]);
1715 /* change primary and verify that MAC addresses haven't changed */
1716 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1717 test_params->slave_port_ids[2]),
1718 "Failed to set bonded port (%d) primary port to (%d)",
1719 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1721 for (i = 0; i < test_params->bonded_slave_count; i++) {
1722 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1723 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1724 sizeof(read_mac_addr)),
1725 "slave port (%d) mac address has changed to that of primary"
1726 " port without stop/start toggle of bonded device",
1727 test_params->slave_port_ids[i]);
1730 /* stop / start bonded device and verify that primary MAC address is
1731 * propagate to bonded device and slaves */
1732 rte_eth_dev_stop(test_params->bonded_port_id);
1734 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1735 "Failed to start bonded device");
1737 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1738 TEST_ASSERT_SUCCESS(
1739 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1740 "bonded port (%d) mac address not set to that of new primary port",
1741 test_params->slave_port_ids[i]);
1743 for (i = 0; i < test_params->bonded_slave_count; i++) {
1744 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1745 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1746 sizeof(read_mac_addr)),
1747 "slave port (%d) mac address not set to that of new primary"
1748 " port", test_params->slave_port_ids[i]);
1751 /* Set explicit MAC address */
1752 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1753 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1754 "Failed to set MAC");
1756 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1757 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1758 sizeof(read_mac_addr)),
1759 "bonded port (%d) mac address not set to that of new primary port",
1760 test_params->slave_port_ids[i]);
1762 for (i = 0; i < test_params->bonded_slave_count; i++) {
1763 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1764 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1765 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1766 " that of new primary port\n", test_params->slave_port_ids[i]);
1769 /* Clean up and remove slaves from bonded device */
1770 return remove_slaves_and_stop_bonded_device();
1774 test_roundrobin_verify_promiscuous_enable_disable(void)
1776 int i, promiscuous_en;
1778 /* Initialize bonded device with 4 slaves in round robin mode */
1779 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1780 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1781 "Failed to initialize bonded device with slaves");
1783 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1785 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1786 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1787 "Port (%d) promiscuous mode not enabled",
1788 test_params->bonded_port_id);
1790 for (i = 0; i < test_params->bonded_slave_count; i++) {
1791 promiscuous_en = rte_eth_promiscuous_get(
1792 test_params->slave_port_ids[i]);
1793 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1794 "slave port (%d) promiscuous mode not enabled",
1795 test_params->slave_port_ids[i]);
1798 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1800 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1801 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1802 "Port (%d) promiscuous mode not disabled\n",
1803 test_params->bonded_port_id);
1805 for (i = 0; i < test_params->bonded_slave_count; i++) {
1806 promiscuous_en = rte_eth_promiscuous_get(
1807 test_params->slave_port_ids[i]);
1808 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1809 "Port (%d) promiscuous mode not disabled\n",
1810 test_params->slave_port_ids[i]);
1813 /* Clean up and remove slaves from bonded device */
1814 return remove_slaves_and_stop_bonded_device();
1817 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1818 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1821 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1823 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1824 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1825 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1827 struct rte_eth_stats port_stats;
1828 uint16_t slaves[RTE_MAX_ETHPORTS];
1830 int i, burst_size, slave_count;
1832 /* NULL all pointers in array to simplify cleanup */
1833 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1835 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1836 * in round robin mode */
1837 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1838 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1839 "Failed to initialize bonded device with slaves");
1841 /* Verify Current Slaves Count /Active Slave Count is */
1842 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1844 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1845 "Number of slaves (%d) is not as expected (%d).",
1846 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1848 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1849 slaves, RTE_MAX_ETHPORTS);
1850 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1851 "Number of active slaves (%d) is not as expected (%d).",
1852 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1854 /* Set 2 slaves eth_devs link status to down */
1855 virtual_ethdev_simulate_link_status_interrupt(
1856 test_params->slave_port_ids[1], 0);
1857 virtual_ethdev_simulate_link_status_interrupt(
1858 test_params->slave_port_ids[3], 0);
1860 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1861 slaves, RTE_MAX_ETHPORTS);
1862 TEST_ASSERT_EQUAL(slave_count,
1863 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1864 "Number of active slaves (%d) is not as expected (%d).\n",
1865 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1869 /* Verify that pkts are not sent on slaves with link status down:
1871 * 1. Generate test burst of traffic
1872 * 2. Transmit burst on bonded eth_dev
1873 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1874 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1877 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1878 burst_size, "generate_test_burst failed");
1880 rte_eth_stats_reset(test_params->bonded_port_id);
1884 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1885 burst_size), burst_size, "rte_eth_tx_burst failed");
1887 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1888 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1889 "Port (%d) opackets stats (%d) not expected (%d) value",
1890 test_params->bonded_port_id, (int)port_stats.opackets,
1893 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1894 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1895 "Port (%d) opackets stats (%d) not expected (%d) value",
1896 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1898 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1899 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1900 "Port (%d) opackets stats (%d) not expected (%d) value",
1901 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1903 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1904 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1905 "Port (%d) opackets stats (%d) not expected (%d) value",
1906 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1908 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1909 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1910 "Port (%d) opackets stats (%d) not expected (%d) value",
1911 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1913 /* Verify that pkts are not sent on slaves with link status down:
1915 * 1. Generate test bursts of traffic
1916 * 2. Add bursts on to virtual eth_devs
1917 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1918 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1919 * 4. Verify stats for bonded eth_dev
1920 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1922 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1923 TEST_ASSERT_EQUAL(generate_test_burst(
1924 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1925 burst_size, "failed to generate packet burst");
1927 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1928 &gen_pkt_burst[i][0], burst_size);
1931 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1932 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1933 burst_size + burst_size,
1934 "rte_eth_rx_burst failed");
1936 /* Verify bonded device rx count */
1937 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1938 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1939 "(%d) port_stats.ipackets not as expected\n",
1940 test_params->bonded_port_id);
1943 for (i = 0; i < MAX_PKT_BURST; i++) {
1944 if (rx_pkt_burst[i] != NULL)
1945 rte_pktmbuf_free(rx_pkt_burst[i]);
1948 /* Clean up and remove slaves from bonded device */
1949 return remove_slaves_and_stop_bonded_device();
1952 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1954 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1957 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1960 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1962 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1963 char slave_name[RTE_ETH_NAME_MAX_LEN];
1967 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1968 /* Generate slave name / MAC address */
1969 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1970 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
1972 /* Create slave devices with no ISR Support */
1973 if (polling_test_slaves[i] == -1) {
1974 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
1975 rte_socket_id(), 0);
1976 TEST_ASSERT(polling_test_slaves[i] >= 0,
1977 "Failed to create virtual virtual ethdev %s\n", slave_name);
1979 /* Configure slave */
1980 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
1981 "Failed to configure virtual ethdev %s(%d)", slave_name,
1982 polling_test_slaves[i]);
1985 /* Add slave to bonded device */
1986 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1987 polling_test_slaves[i]),
1988 "Failed to add slave %s(%d) to bonded device %d",
1989 slave_name, polling_test_slaves[i],
1990 test_params->bonded_port_id);
1993 /* Initialize bonded device */
1994 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
1995 "Failed to configure bonded device %d",
1996 test_params->bonded_port_id);
1999 /* Register link status change interrupt callback */
2000 rte_eth_dev_callback_register(test_params->bonded_port_id,
2001 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2002 &test_params->bonded_port_id);
2004 /* link status change callback for first slave link up */
2005 test_lsc_interrupt_count = 0;
2007 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2009 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2012 /* no link status change callback for second slave link up */
2013 test_lsc_interrupt_count = 0;
2015 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2017 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2019 /* link status change callback for both slave links down */
2020 test_lsc_interrupt_count = 0;
2022 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2023 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2025 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2027 /* Un-Register link status change interrupt callback */
2028 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2029 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2030 &test_params->bonded_port_id);
2033 /* Clean up and remove slaves from bonded device */
2034 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2036 TEST_ASSERT_SUCCESS(
2037 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2038 polling_test_slaves[i]),
2039 "Failed to remove slave %d from bonded port (%d)",
2040 polling_test_slaves[i], test_params->bonded_port_id);
2043 return remove_slaves_and_stop_bonded_device();
2047 /** Active Backup Mode Tests */
2050 test_activebackup_tx_burst(void)
2052 int i, pktlen, primary_port, burst_size;
2053 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2054 struct rte_eth_stats port_stats;
2056 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2057 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2058 "Failed to initialize bonded device with slaves");
2060 initialize_eth_header(test_params->pkt_eth_hdr,
2061 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2062 ETHER_TYPE_IPv4, 0, 0);
2063 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2065 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2066 dst_addr_0, pktlen);
2068 burst_size = 20 * test_params->bonded_slave_count;
2070 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2071 "Burst size specified is greater than supported.");
2073 /* Generate a burst of packets to transmit */
2074 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2075 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2076 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2077 burst_size, "failed to generate burst correctly");
2079 /* Send burst on bonded port */
2080 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2081 burst_size), burst_size, "tx burst failed");
2083 /* Verify bonded port tx stats */
2084 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2085 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2086 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2087 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2090 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2092 /* Verify slave ports tx stats */
2093 for (i = 0; i < test_params->bonded_slave_count; i++) {
2094 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2095 if (test_params->slave_port_ids[i] == primary_port) {
2096 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2097 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2098 test_params->bonded_port_id,
2099 (unsigned int)port_stats.opackets,
2100 burst_size / test_params->bonded_slave_count);
2102 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2103 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2104 test_params->bonded_port_id,
2105 (unsigned int)port_stats.opackets, 0);
2109 /* Put all slaves down and try and transmit */
2110 for (i = 0; i < test_params->bonded_slave_count; i++) {
2111 virtual_ethdev_simulate_link_status_interrupt(
2112 test_params->slave_port_ids[i], 0);
2115 /* Send burst on bonded port */
2116 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2117 pkts_burst, burst_size), 0, "Sending empty burst failed");
2119 /* Clean up and remove slaves from bonded device */
2120 return remove_slaves_and_stop_bonded_device();
2123 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2126 test_activebackup_rx_burst(void)
2128 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2129 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2131 struct rte_eth_stats port_stats;
2135 int i, j, burst_size = 17;
2137 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2138 BONDING_MODE_ACTIVE_BACKUP, 0,
2139 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2140 "Failed to initialize bonded device with slaves");
2142 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2143 TEST_ASSERT(primary_port >= 0,
2144 "failed to get primary slave for bonded port (%d)",
2145 test_params->bonded_port_id);
2147 for (i = 0; i < test_params->bonded_slave_count; i++) {
2148 /* Generate test bursts of packets to transmit */
2149 TEST_ASSERT_EQUAL(generate_test_burst(
2150 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2151 burst_size, "burst generation failed");
2153 /* Add rx data to slave */
2154 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2155 &gen_pkt_burst[0], burst_size);
2157 /* Call rx burst on bonded device */
2158 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2159 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2160 "rte_eth_rx_burst failed");
2162 if (test_params->slave_port_ids[i] == primary_port) {
2163 /* Verify bonded device rx count */
2164 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2165 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2166 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2167 test_params->bonded_port_id,
2168 (unsigned int)port_stats.ipackets, burst_size);
2170 /* Verify bonded slave devices rx count */
2171 for (j = 0; j < test_params->bonded_slave_count; j++) {
2172 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2174 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2175 "Slave Port (%d) ipackets value (%u) not as "
2176 "expected (%d)", test_params->slave_port_ids[i],
2177 (unsigned int)port_stats.ipackets, burst_size);
2179 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2180 "Slave Port (%d) ipackets value (%u) not as "
2181 "expected (%d)\n", test_params->slave_port_ids[i],
2182 (unsigned int)port_stats.ipackets, 0);
2186 for (j = 0; j < test_params->bonded_slave_count; j++) {
2187 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2188 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2189 "Slave Port (%d) ipackets value (%u) not as expected "
2190 "(%d)", test_params->slave_port_ids[i],
2191 (unsigned int)port_stats.ipackets, 0);
2196 for (i = 0; i < MAX_PKT_BURST; i++) {
2197 if (rx_pkt_burst[i] != NULL) {
2198 rte_pktmbuf_free(rx_pkt_burst[i]);
2199 rx_pkt_burst[i] = NULL;
2203 /* reset bonded device stats */
2204 rte_eth_stats_reset(test_params->bonded_port_id);
2207 /* Clean up and remove slaves from bonded device */
2208 return remove_slaves_and_stop_bonded_device();
2212 test_activebackup_verify_promiscuous_enable_disable(void)
2214 int i, primary_port, promiscuous_en;
2216 /* Initialize bonded device with 4 slaves in round robin mode */
2217 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2218 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2219 "Failed to initialize bonded device with slaves");
2221 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2222 TEST_ASSERT(primary_port >= 0,
2223 "failed to get primary slave for bonded port (%d)",
2224 test_params->bonded_port_id);
2226 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2228 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2229 "Port (%d) promiscuous mode not enabled",
2230 test_params->bonded_port_id);
2232 for (i = 0; i < test_params->bonded_slave_count; i++) {
2233 promiscuous_en = rte_eth_promiscuous_get(
2234 test_params->slave_port_ids[i]);
2235 if (primary_port == test_params->slave_port_ids[i]) {
2236 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2237 "slave port (%d) promiscuous mode not enabled",
2238 test_params->slave_port_ids[i]);
2240 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2241 "slave port (%d) promiscuous mode enabled",
2242 test_params->slave_port_ids[i]);
2247 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2249 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2250 "Port (%d) promiscuous mode not disabled\n",
2251 test_params->bonded_port_id);
2253 for (i = 0; i < test_params->bonded_slave_count; i++) {
2254 promiscuous_en = rte_eth_promiscuous_get(
2255 test_params->slave_port_ids[i]);
2256 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2257 "slave port (%d) promiscuous mode not disabled\n",
2258 test_params->slave_port_ids[i]);
2261 /* Clean up and remove slaves from bonded device */
2262 return remove_slaves_and_stop_bonded_device();
2266 test_activebackup_verify_mac_assignment(void)
2268 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2270 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2271 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2273 /* Initialize bonded device with 2 slaves in active backup mode */
2274 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2275 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2276 "Failed to initialize bonded device with slaves");
2278 /* Verify that bonded MACs is that of first slave and that the other slave
2279 * MAC hasn't been changed */
2280 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2281 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2282 sizeof(read_mac_addr)),
2283 "bonded port (%d) mac address not set to that of primary port",
2284 test_params->bonded_port_id);
2286 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2287 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2288 sizeof(read_mac_addr)),
2289 "slave port (%d) mac address not set to that of primary port",
2290 test_params->slave_port_ids[0]);
2292 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2293 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2294 sizeof(read_mac_addr)),
2295 "slave port (%d) mac address not as expected",
2296 test_params->slave_port_ids[1]);
2298 /* change primary and verify that MAC addresses haven't changed */
2299 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2300 test_params->slave_port_ids[1]), 0,
2301 "Failed to set bonded port (%d) primary port to (%d)",
2302 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2304 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2305 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2306 sizeof(read_mac_addr)),
2307 "bonded port (%d) mac address not set to that of primary port",
2308 test_params->bonded_port_id);
2310 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2311 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2312 sizeof(read_mac_addr)),
2313 "slave port (%d) mac address not set to that of primary port",
2314 test_params->slave_port_ids[0]);
2316 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2317 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2318 sizeof(read_mac_addr)),
2319 "slave port (%d) mac address not as expected",
2320 test_params->slave_port_ids[1]);
2322 /* stop / start bonded device and verify that primary MAC address is
2323 * propagated to bonded device and slaves */
2325 rte_eth_dev_stop(test_params->bonded_port_id);
2327 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2328 "Failed to start device");
2330 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2331 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2332 sizeof(read_mac_addr)),
2333 "bonded port (%d) mac address not set to that of primary port",
2334 test_params->bonded_port_id);
2336 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2337 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2338 sizeof(read_mac_addr)),
2339 "slave port (%d) mac address not as expected",
2340 test_params->slave_port_ids[0]);
2342 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2343 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2344 sizeof(read_mac_addr)),
2345 "slave port (%d) mac address not set to that of primary port",
2346 test_params->slave_port_ids[1]);
2348 /* Set explicit MAC address */
2349 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2350 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2351 "failed to set MAC address");
2353 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2354 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2355 sizeof(read_mac_addr)),
2356 "bonded port (%d) mac address not set to that of bonded port",
2357 test_params->bonded_port_id);
2359 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2361 sizeof(read_mac_addr)),
2362 "slave port (%d) mac address not as expected",
2363 test_params->slave_port_ids[0]);
2365 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2366 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2367 sizeof(read_mac_addr)),
2368 "slave port (%d) mac address not set to that of bonded port",
2369 test_params->slave_port_ids[1]);
2371 /* Clean up and remove slaves from bonded device */
2372 return remove_slaves_and_stop_bonded_device();
2376 test_activebackup_verify_slave_link_status_change_failover(void)
2378 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2379 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2380 struct rte_eth_stats port_stats;
2382 uint16_t slaves[RTE_MAX_ETHPORTS];
2384 int i, burst_size, slave_count, primary_port;
2388 memset(pkt_burst, 0, sizeof(pkt_burst));
2390 /* Generate packet burst for testing */
2391 TEST_ASSERT_EQUAL(generate_test_burst(
2392 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2393 "generate_test_burst failed");
2395 /* Initialize bonded device with 4 slaves in round robin mode */
2396 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2397 BONDING_MODE_ACTIVE_BACKUP, 0,
2398 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2399 "Failed to initialize bonded device with slaves");
2401 /* Verify Current Slaves Count /Active Slave Count is */
2402 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2404 TEST_ASSERT_EQUAL(slave_count, 4,
2405 "Number of slaves (%d) is not as expected (%d).",
2408 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2409 slaves, RTE_MAX_ETHPORTS);
2410 TEST_ASSERT_EQUAL(slave_count, 4,
2411 "Number of active slaves (%d) is not as expected (%d).",
2414 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2415 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2416 "Primary port not as expected");
2418 /* Bring 2 slaves down and verify active slave count */
2419 virtual_ethdev_simulate_link_status_interrupt(
2420 test_params->slave_port_ids[1], 0);
2421 virtual_ethdev_simulate_link_status_interrupt(
2422 test_params->slave_port_ids[3], 0);
2424 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2425 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2426 "Number of active slaves (%d) is not as expected (%d).",
2429 virtual_ethdev_simulate_link_status_interrupt(
2430 test_params->slave_port_ids[1], 1);
2431 virtual_ethdev_simulate_link_status_interrupt(
2432 test_params->slave_port_ids[3], 1);
2435 /* Bring primary port down, verify that active slave count is 3 and primary
2437 virtual_ethdev_simulate_link_status_interrupt(
2438 test_params->slave_port_ids[0], 0);
2440 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2441 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2443 "Number of active slaves (%d) is not as expected (%d).",
2446 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2447 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2448 "Primary port not as expected");
2450 /* Verify that pkts are sent on new primary slave */
2452 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2453 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2454 burst_size), burst_size, "rte_eth_tx_burst failed");
2456 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2457 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2458 "(%d) port_stats.opackets not as expected",
2459 test_params->slave_port_ids[2]);
2461 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2462 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2463 "(%d) port_stats.opackets not as expected\n",
2464 test_params->slave_port_ids[0]);
2466 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2467 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2468 "(%d) port_stats.opackets not as expected\n",
2469 test_params->slave_port_ids[1]);
2471 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2472 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2473 "(%d) port_stats.opackets not as expected\n",
2474 test_params->slave_port_ids[3]);
2476 /* Generate packet burst for testing */
2478 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2479 TEST_ASSERT_EQUAL(generate_test_burst(
2480 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2481 "generate_test_burst failed");
2483 virtual_ethdev_add_mbufs_to_rx_queue(
2484 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2487 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2488 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2489 burst_size, "rte_eth_rx_burst\n");
2491 /* Verify bonded device rx count */
2492 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2493 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2494 "(%d) port_stats.ipackets not as expected",
2495 test_params->bonded_port_id);
2497 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2498 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2499 "(%d) port_stats.opackets not as expected",
2500 test_params->slave_port_ids[2]);
2502 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2503 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2504 "(%d) port_stats.opackets not as expected",
2505 test_params->slave_port_ids[0]);
2507 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2508 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2509 "(%d) port_stats.opackets not as expected",
2510 test_params->slave_port_ids[1]);
2512 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2513 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2514 "(%d) port_stats.opackets not as expected",
2515 test_params->slave_port_ids[3]);
2517 /* Clean up and remove slaves from bonded device */
2518 return remove_slaves_and_stop_bonded_device();
2521 /** Balance Mode Tests */
2524 test_balance_xmit_policy_configuration(void)
2526 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2527 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2528 "Failed to initialize_bonded_device_with_slaves.");
2530 /* Invalid port id */
2531 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2532 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2533 "Expected call to failed as invalid port specified.");
2535 /* Set xmit policy on non bonded device */
2536 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2537 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2538 "Expected call to failed as invalid port specified.");
2541 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2542 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2543 "Failed to set balance xmit policy.");
2545 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2546 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2549 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2550 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2551 "Failed to set balance xmit policy.");
2553 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2554 BALANCE_XMIT_POLICY_LAYER23,
2555 "balance xmit policy not as expected.");
2558 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2559 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2560 "Failed to set balance xmit policy.");
2562 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2563 BALANCE_XMIT_POLICY_LAYER34,
2564 "balance xmit policy not as expected.");
2566 /* Invalid port id */
2567 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2568 "Expected call to failed as invalid port specified.");
2570 /* Clean up and remove slaves from bonded device */
2571 return remove_slaves_and_stop_bonded_device();
2574 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2577 test_balance_l2_tx_burst(void)
2579 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2580 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2584 struct rte_eth_stats port_stats;
2586 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2587 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2588 "Failed to initialize_bonded_device_with_slaves.");
2590 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2591 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2592 "Failed to set balance xmit policy.");
2594 initialize_eth_header(test_params->pkt_eth_hdr,
2595 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2596 ETHER_TYPE_IPv4, 0, 0);
2597 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2599 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2600 dst_addr_0, pktlen);
2602 /* Generate a burst 1 of packets to transmit */
2603 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2604 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2605 test_params->pkt_udp_hdr, burst_size[0],
2606 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2607 "failed to generate packet burst");
2609 initialize_eth_header(test_params->pkt_eth_hdr,
2610 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2611 ETHER_TYPE_IPv4, 0, 0);
2613 /* Generate a burst 2 of packets to transmit */
2614 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2615 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2616 test_params->pkt_udp_hdr, burst_size[1],
2617 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2618 "failed to generate packet burst");
2620 /* Send burst 1 on bonded port */
2621 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2622 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2623 &pkts_burst[i][0], burst_size[i]),
2624 burst_size[i], "Failed to transmit packet burst");
2627 /* Verify bonded port tx stats */
2628 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2629 TEST_ASSERT_EQUAL(port_stats.opackets,
2630 (uint64_t)(burst_size[0] + burst_size[1]),
2631 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2632 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2633 burst_size[0] + burst_size[1]);
2636 /* Verify slave ports tx stats */
2637 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2638 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2639 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2640 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2643 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2644 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2645 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2646 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2649 /* Put all slaves down and try and transmit */
2650 for (i = 0; i < test_params->bonded_slave_count; i++) {
2652 virtual_ethdev_simulate_link_status_interrupt(
2653 test_params->slave_port_ids[i], 0);
2656 /* Send burst on bonded port */
2657 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2658 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2659 0, "Expected zero packet");
2661 /* Clean up and remove slaves from bonded device */
2662 return remove_slaves_and_stop_bonded_device();
2666 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2667 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2669 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2671 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2672 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2674 struct rte_eth_stats port_stats;
2676 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2677 BONDING_MODE_BALANCE, 0, 2, 1),
2678 "Failed to initialize_bonded_device_with_slaves.");
2680 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2681 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2682 "Failed to set balance xmit policy.");
2687 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2688 "Burst size specified is greater than supported.");
2690 /* Generate test bursts of packets to transmit */
2691 TEST_ASSERT_EQUAL(generate_test_burst(
2692 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2693 burst_size_1, "failed to generate packet burst");
2695 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2696 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2697 "failed to generate packet burst");
2699 /* Send burst 1 on bonded port */
2700 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2702 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2704 /* Send burst 2 on bonded port */
2705 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2707 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2709 /* Verify bonded port tx stats */
2710 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2711 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2712 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2713 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2716 /* Verify slave ports tx stats */
2717 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2718 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2719 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2720 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2723 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2724 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2725 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2726 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2729 /* Put all slaves down and try and transmit */
2730 for (i = 0; i < test_params->bonded_slave_count; i++) {
2732 virtual_ethdev_simulate_link_status_interrupt(
2733 test_params->slave_port_ids[i], 0);
2736 /* Send burst on bonded port */
2737 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2738 test_params->bonded_port_id, 0, pkts_burst_1,
2739 burst_size_1), 0, "Expected zero packet");
2742 /* Clean up and remove slaves from bonded device */
2743 return remove_slaves_and_stop_bonded_device();
2747 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2749 return balance_l23_tx_burst(0, 1, 0, 1);
2753 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2755 return balance_l23_tx_burst(1, 1, 0, 1);
2759 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2761 return balance_l23_tx_burst(0, 0, 0, 1);
2765 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2767 return balance_l23_tx_burst(1, 0, 0, 1);
2771 test_balance_l23_tx_burst_toggle_mac_addr(void)
2773 return balance_l23_tx_burst(0, 0, 1, 0);
2777 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2778 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2779 uint8_t toggle_udp_port)
2781 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2783 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2784 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2786 struct rte_eth_stats port_stats;
2788 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2789 BONDING_MODE_BALANCE, 0, 2, 1),
2790 "Failed to initialize_bonded_device_with_slaves.");
2792 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2793 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2794 "Failed to set balance xmit policy.");
2799 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2800 "Burst size specified is greater than supported.");
2802 /* Generate test bursts of packets to transmit */
2803 TEST_ASSERT_EQUAL(generate_test_burst(
2804 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2805 burst_size_1, "failed to generate burst");
2807 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2808 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2809 toggle_udp_port), burst_size_2, "failed to generate burst");
2811 /* Send burst 1 on bonded port */
2812 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2814 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2816 /* Send burst 2 on bonded port */
2817 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2819 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2822 /* Verify bonded port tx stats */
2823 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2824 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2825 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2826 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2829 /* Verify slave ports tx stats */
2830 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2831 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2832 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2833 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2836 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2837 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2838 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2839 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2842 /* Put all slaves down and try and transmit */
2843 for (i = 0; i < test_params->bonded_slave_count; i++) {
2845 virtual_ethdev_simulate_link_status_interrupt(
2846 test_params->slave_port_ids[i], 0);
2849 /* Send burst on bonded port */
2850 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2851 test_params->bonded_port_id, 0, pkts_burst_1,
2852 burst_size_1), 0, "Expected zero packet");
2854 /* Clean up and remove slaves from bonded device */
2855 return remove_slaves_and_stop_bonded_device();
2859 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2861 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2865 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2867 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2871 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2873 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2877 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2879 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2883 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2885 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2889 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2891 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2894 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2895 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2896 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2897 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2898 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2901 test_balance_tx_burst_slave_tx_fail(void)
2903 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2904 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2906 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2908 struct rte_eth_stats port_stats;
2910 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2912 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2913 BONDING_MODE_BALANCE, 0,
2914 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2915 "Failed to initialise bonded device");
2917 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2918 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2919 "Failed to set balance xmit policy.");
2922 /* Generate test bursts for transmission */
2923 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2924 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2925 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2926 "Failed to generate test packet burst 1");
2928 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2929 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2931 /* copy mbuf referneces for expected transmission failures */
2932 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2933 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2935 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2936 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2937 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2938 "Failed to generate test packet burst 2");
2941 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2942 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2943 virtual_ethdev_tx_burst_fn_set_success(
2944 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2947 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2948 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2949 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2952 /* Transmit burst 1 */
2953 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2954 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2956 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2957 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2958 "Transmitted (%d) packets, expected to transmit (%d) packets",
2959 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2960 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2962 /* Verify that failed packet are expected failed packets */
2963 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
2964 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
2965 "expected mbuf (%d) pointer %p not expected pointer %p",
2966 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
2969 /* Transmit burst 2 */
2970 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2971 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2973 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2974 "Transmitted (%d) packets, expected to transmit (%d) packets",
2975 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2978 /* Verify bonded port tx stats */
2979 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2981 TEST_ASSERT_EQUAL(port_stats.opackets,
2982 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2983 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2984 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
2985 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2986 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2987 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2988 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2989 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2991 /* Verify slave ports tx stats */
2993 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2995 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
2996 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2997 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2998 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2999 test_params->slave_port_ids[0],
3000 (unsigned int)port_stats.opackets,
3001 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3002 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3007 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3009 TEST_ASSERT_EQUAL(port_stats.opackets,
3010 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3011 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3012 test_params->slave_port_ids[1],
3013 (unsigned int)port_stats.opackets,
3014 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3016 /* Verify that all mbufs have a ref value of zero */
3017 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3018 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3019 "mbufs refcnts not as expected");
3021 free_mbufs(&pkts_burst_1[tx_count_1],
3022 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3024 /* Clean up and remove slaves from bonded device */
3025 return remove_slaves_and_stop_bonded_device();
3028 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3031 test_balance_rx_burst(void)
3033 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3035 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3036 struct rte_eth_stats port_stats;
3038 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3041 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3043 /* Initialize bonded device with 4 slaves in round robin mode */
3044 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3045 BONDING_MODE_BALANCE, 0, 3, 1),
3046 "Failed to initialise bonded device");
3048 /* Generate test bursts of packets to transmit */
3049 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3050 TEST_ASSERT_EQUAL(generate_test_burst(
3051 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3052 0, 0), burst_size[i],
3053 "failed to generate packet burst");
3056 /* Add rx data to slaves */
3057 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3058 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3059 &gen_pkt_burst[i][0], burst_size[i]);
3062 /* Call rx burst on bonded device */
3063 /* Send burst on bonded port */
3064 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3065 rx_pkt_burst, MAX_PKT_BURST),
3066 burst_size[0] + burst_size[1] + burst_size[2],
3067 "balance rx burst failed\n");
3069 /* Verify bonded device rx count */
3070 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3071 TEST_ASSERT_EQUAL(port_stats.ipackets,
3072 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3073 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3074 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3075 burst_size[0] + burst_size[1] + burst_size[2]);
3078 /* Verify bonded slave devices rx counts */
3079 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3080 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3081 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3082 test_params->slave_port_ids[0],
3083 (unsigned int)port_stats.ipackets, burst_size[0]);
3085 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3086 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3087 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3088 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3091 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3092 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3093 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3094 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3097 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3098 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3099 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3100 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3104 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3105 for (j = 0; j < MAX_PKT_BURST; j++) {
3106 if (gen_pkt_burst[i][j] != NULL) {
3107 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3108 gen_pkt_burst[i][j] = NULL;
3113 /* Clean up and remove slaves from bonded device */
3114 return remove_slaves_and_stop_bonded_device();
3118 test_balance_verify_promiscuous_enable_disable(void)
3122 /* Initialize bonded device with 4 slaves in round robin mode */
3123 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3124 BONDING_MODE_BALANCE, 0, 4, 1),
3125 "Failed to initialise bonded device");
3127 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3129 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3130 "Port (%d) promiscuous mode not enabled",
3131 test_params->bonded_port_id);
3133 for (i = 0; i < test_params->bonded_slave_count; i++) {
3134 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3135 test_params->slave_port_ids[i]), 1,
3136 "Port (%d) promiscuous mode not enabled",
3137 test_params->slave_port_ids[i]);
3140 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3142 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3143 "Port (%d) promiscuous mode not disabled",
3144 test_params->bonded_port_id);
3146 for (i = 0; i < test_params->bonded_slave_count; i++) {
3147 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3148 test_params->slave_port_ids[i]), 0,
3149 "Port (%d) promiscuous mode not disabled",
3150 test_params->slave_port_ids[i]);
3153 /* Clean up and remove slaves from bonded device */
3154 return remove_slaves_and_stop_bonded_device();
3158 test_balance_verify_mac_assignment(void)
3160 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3162 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3163 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3165 /* Initialize bonded device with 2 slaves in active backup mode */
3166 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3167 BONDING_MODE_BALANCE, 0, 2, 1),
3168 "Failed to initialise bonded device");
3170 /* Verify that bonded MACs is that of first slave and that the other slave
3171 * MAC hasn't been changed */
3172 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3173 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3174 sizeof(read_mac_addr)),
3175 "bonded port (%d) mac address not set to that of primary port",
3176 test_params->bonded_port_id);
3178 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3179 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3180 sizeof(read_mac_addr)),
3181 "slave port (%d) mac address not set to that of primary port",
3182 test_params->slave_port_ids[0]);
3184 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3185 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3186 sizeof(read_mac_addr)),
3187 "slave port (%d) mac address not set to that of primary port",
3188 test_params->slave_port_ids[1]);
3190 /* change primary and verify that MAC addresses haven't changed */
3191 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3192 test_params->slave_port_ids[1]),
3193 "Failed to set bonded port (%d) primary port to (%d)\n",
3194 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3196 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3197 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3198 sizeof(read_mac_addr)),
3199 "bonded port (%d) mac address not set to that of primary port",
3200 test_params->bonded_port_id);
3202 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3203 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3204 sizeof(read_mac_addr)),
3205 "slave port (%d) mac address not set to that of primary port",
3206 test_params->slave_port_ids[0]);
3208 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3209 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3210 sizeof(read_mac_addr)),
3211 "slave port (%d) mac address not set to that of primary port",
3212 test_params->slave_port_ids[1]);
3214 /* stop / start bonded device and verify that primary MAC address is
3215 * propagated to bonded device and slaves */
3217 rte_eth_dev_stop(test_params->bonded_port_id);
3219 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3220 "Failed to start bonded device");
3222 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3223 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3224 sizeof(read_mac_addr)),
3225 "bonded port (%d) mac address not set to that of primary port",
3226 test_params->bonded_port_id);
3228 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3229 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3230 sizeof(read_mac_addr)),
3231 "slave port (%d) mac address not set to that of primary port",
3232 test_params->slave_port_ids[0]);
3234 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3235 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3236 sizeof(read_mac_addr)),
3237 "slave port (%d) mac address not set to that of primary port",
3238 test_params->slave_port_ids[1]);
3240 /* Set explicit MAC address */
3241 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3242 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3243 "failed to set MAC");
3245 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3246 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3247 sizeof(read_mac_addr)),
3248 "bonded port (%d) mac address not set to that of bonded port",
3249 test_params->bonded_port_id);
3251 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3252 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3253 sizeof(read_mac_addr)),
3254 "slave port (%d) mac address not as expected\n",
3255 test_params->slave_port_ids[0]);
3257 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3258 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3259 sizeof(read_mac_addr)),
3260 "slave port (%d) mac address not set to that of bonded port",
3261 test_params->slave_port_ids[1]);
3263 /* Clean up and remove slaves from bonded device */
3264 return remove_slaves_and_stop_bonded_device();
3267 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3270 test_balance_verify_slave_link_status_change_behaviour(void)
3272 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3273 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3274 struct rte_eth_stats port_stats;
3276 uint16_t slaves[RTE_MAX_ETHPORTS];
3278 int i, burst_size, slave_count;
3280 memset(pkt_burst, 0, sizeof(pkt_burst));
3282 /* Initialize bonded device with 4 slaves in round robin mode */
3283 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3284 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3285 "Failed to initialise bonded device");
3287 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3288 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3289 "Failed to set balance xmit policy.");
3292 /* Verify Current Slaves Count /Active Slave Count is */
3293 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3295 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3296 "Number of slaves (%d) is not as expected (%d).",
3297 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3299 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3300 slaves, RTE_MAX_ETHPORTS);
3301 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3302 "Number of active slaves (%d) is not as expected (%d).",
3303 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3305 /* Set 2 slaves link status to down */
3306 virtual_ethdev_simulate_link_status_interrupt(
3307 test_params->slave_port_ids[1], 0);
3308 virtual_ethdev_simulate_link_status_interrupt(
3309 test_params->slave_port_ids[3], 0);
3311 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3312 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3313 "Number of active slaves (%d) is not as expected (%d).",
3316 /* Send to sets of packet burst and verify that they are balanced across
3320 TEST_ASSERT_EQUAL(generate_test_burst(
3321 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3322 "generate_test_burst failed");
3324 TEST_ASSERT_EQUAL(generate_test_burst(
3325 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3326 "generate_test_burst failed");
3328 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3329 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3330 burst_size, "rte_eth_tx_burst failed");
3332 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3333 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3334 burst_size, "rte_eth_tx_burst failed");
3337 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3338 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3339 "(%d) port_stats.opackets (%d) not as expected (%d).",
3340 test_params->bonded_port_id, (int)port_stats.opackets,
3341 burst_size + burst_size);
3343 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3344 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3345 "(%d) port_stats.opackets (%d) not as expected (%d).",
3346 test_params->slave_port_ids[0], (int)port_stats.opackets,
3349 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3350 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3351 "(%d) port_stats.opackets (%d) not as expected (%d).",
3352 test_params->slave_port_ids[2], (int)port_stats.opackets,
3355 /* verify that all packets get send on primary slave when no other slaves
3357 virtual_ethdev_simulate_link_status_interrupt(
3358 test_params->slave_port_ids[2], 0);
3360 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3361 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3362 "Number of active slaves (%d) is not as expected (%d).",
3365 TEST_ASSERT_EQUAL(generate_test_burst(
3366 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3367 "generate_test_burst failed");
3369 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3370 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3371 burst_size, "rte_eth_tx_burst failed");
3373 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3374 TEST_ASSERT_EQUAL(port_stats.opackets,
3375 (uint64_t)(burst_size + burst_size + burst_size),
3376 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3377 test_params->bonded_port_id, (int)port_stats.opackets,
3378 burst_size + burst_size + burst_size);
3380 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3381 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3382 "(%d) port_stats.opackets (%d) not as expected (%d).",
3383 test_params->slave_port_ids[0], (int)port_stats.opackets,
3384 burst_size + burst_size);
3386 virtual_ethdev_simulate_link_status_interrupt(
3387 test_params->slave_port_ids[0], 0);
3388 virtual_ethdev_simulate_link_status_interrupt(
3389 test_params->slave_port_ids[1], 1);
3390 virtual_ethdev_simulate_link_status_interrupt(
3391 test_params->slave_port_ids[2], 1);
3392 virtual_ethdev_simulate_link_status_interrupt(
3393 test_params->slave_port_ids[3], 1);
3395 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3396 TEST_ASSERT_EQUAL(generate_test_burst(
3397 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3398 "Failed to generate packet burst");
3400 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3401 &pkt_burst[i][0], burst_size);
3404 /* Verify that pkts are not received on slaves with link status down */
3406 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3409 /* Verify bonded device rx count */
3410 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3411 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3412 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3413 test_params->bonded_port_id, (int)port_stats.ipackets,
3416 /* Clean up and remove slaves from bonded device */
3417 return remove_slaves_and_stop_bonded_device();
3421 test_broadcast_tx_burst(void)
3423 int i, pktlen, burst_size;
3424 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3426 struct rte_eth_stats port_stats;
3428 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3429 BONDING_MODE_BROADCAST, 0, 2, 1),
3430 "Failed to initialise bonded device");
3432 initialize_eth_header(test_params->pkt_eth_hdr,
3433 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3434 ETHER_TYPE_IPv4, 0, 0);
3436 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3438 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3439 dst_addr_0, pktlen);
3441 burst_size = 20 * test_params->bonded_slave_count;
3443 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3444 "Burst size specified is greater than supported.");
3446 /* Generate a burst of packets to transmit */
3447 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3448 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3449 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3450 1), burst_size, "Failed to generate packet burst");
3452 /* Send burst on bonded port */
3453 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3454 pkts_burst, burst_size), burst_size,
3455 "Bonded Port (%d) rx burst failed, packets transmitted value "
3456 "not as expected (%d)",
3457 test_params->bonded_port_id, burst_size);
3459 /* Verify bonded port tx stats */
3460 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3461 TEST_ASSERT_EQUAL(port_stats.opackets,
3462 (uint64_t)burst_size * test_params->bonded_slave_count,
3463 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3464 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3467 /* Verify slave ports tx stats */
3468 for (i = 0; i < test_params->bonded_slave_count; i++) {
3469 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3470 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3471 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3472 test_params->bonded_port_id,
3473 (unsigned int)port_stats.opackets, burst_size);
3476 /* Put all slaves down and try and transmit */
3477 for (i = 0; i < test_params->bonded_slave_count; i++) {
3479 virtual_ethdev_simulate_link_status_interrupt(
3480 test_params->slave_port_ids[i], 0);
3483 /* Send burst on bonded port */
3484 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3485 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3486 "transmitted an unexpected number of packets");
3488 /* Clean up and remove slaves from bonded device */
3489 return remove_slaves_and_stop_bonded_device();
3493 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3494 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3495 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3496 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3499 test_broadcast_tx_burst_slave_tx_fail(void)
3501 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3502 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3504 struct rte_eth_stats port_stats;
3508 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3509 BONDING_MODE_BROADCAST, 0,
3510 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3511 "Failed to initialise bonded device");
3513 /* Generate test bursts for transmission */
3514 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3515 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3516 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3517 "Failed to generate test packet burst");
3519 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3520 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3521 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3524 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3525 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3526 virtual_ethdev_tx_burst_fn_set_success(
3527 test_params->slave_port_ids[0],
3529 virtual_ethdev_tx_burst_fn_set_success(
3530 test_params->slave_port_ids[1],
3532 virtual_ethdev_tx_burst_fn_set_success(
3533 test_params->slave_port_ids[2],
3536 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3537 test_params->slave_port_ids[0],
3538 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3540 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3541 test_params->slave_port_ids[1],
3542 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3544 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3545 test_params->slave_port_ids[2],
3546 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3548 /* Transmit burst */
3549 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3550 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3552 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3553 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3554 "Transmitted (%d) packets, expected to transmit (%d) packets",
3555 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3556 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3558 /* Verify that failed packet are expected failed packets */
3559 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3560 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3561 "expected mbuf (%d) pointer %p not expected pointer %p",
3562 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3565 /* Verify slave ports tx stats */
3567 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3569 TEST_ASSERT_EQUAL(port_stats.opackets,
3570 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3571 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3572 "Port (%d) opackets value (%u) not as expected (%d)",
3573 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3574 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3575 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3578 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3580 TEST_ASSERT_EQUAL(port_stats.opackets,
3581 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3582 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3583 "Port (%d) opackets value (%u) not as expected (%d)",
3584 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3585 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3586 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3588 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3590 TEST_ASSERT_EQUAL(port_stats.opackets,
3591 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3592 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3593 "Port (%d) opackets value (%u) not as expected (%d)",
3594 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3595 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3596 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3599 /* Verify that all mbufs who transmission failed have a ref value of one */
3600 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3601 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3602 "mbufs refcnts not as expected");
3604 free_mbufs(&pkts_burst[tx_count],
3605 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3607 /* Clean up and remove slaves from bonded device */
3608 return remove_slaves_and_stop_bonded_device();
3611 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3614 test_broadcast_rx_burst(void)
3616 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3618 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3619 struct rte_eth_stats port_stats;
3621 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3624 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3626 /* Initialize bonded device with 4 slaves in round robin mode */
3627 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3628 BONDING_MODE_BROADCAST, 0, 3, 1),
3629 "Failed to initialise bonded device");
3631 /* Generate test bursts of packets to transmit */
3632 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3633 TEST_ASSERT_EQUAL(generate_test_burst(
3634 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3635 burst_size[i], "failed to generate packet burst");
3638 /* Add rx data to slave 0 */
3639 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3640 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3641 &gen_pkt_burst[i][0], burst_size[i]);
3645 /* Call rx burst on bonded device */
3646 /* Send burst on bonded port */
3647 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3648 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3649 burst_size[0] + burst_size[1] + burst_size[2],
3652 /* Verify bonded device rx count */
3653 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3654 TEST_ASSERT_EQUAL(port_stats.ipackets,
3655 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3656 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3657 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3658 burst_size[0] + burst_size[1] + burst_size[2]);
3661 /* Verify bonded slave devices rx counts */
3662 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3663 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3664 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3665 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3668 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3669 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3670 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3671 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3674 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3675 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3676 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3677 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3680 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3681 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3682 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3683 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3686 /* free mbufs allocate for rx testing */
3687 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3688 for (j = 0; j < MAX_PKT_BURST; j++) {
3689 if (gen_pkt_burst[i][j] != NULL) {
3690 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3691 gen_pkt_burst[i][j] = NULL;
3696 /* Clean up and remove slaves from bonded device */
3697 return remove_slaves_and_stop_bonded_device();
3701 test_broadcast_verify_promiscuous_enable_disable(void)
3705 /* Initialize bonded device with 4 slaves in round robin mode */
3706 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3707 BONDING_MODE_BROADCAST, 0, 4, 1),
3708 "Failed to initialise bonded device");
3710 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3713 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3714 "Port (%d) promiscuous mode not enabled",
3715 test_params->bonded_port_id);
3717 for (i = 0; i < test_params->bonded_slave_count; i++) {
3718 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3719 test_params->slave_port_ids[i]), 1,
3720 "Port (%d) promiscuous mode not enabled",
3721 test_params->slave_port_ids[i]);
3724 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3726 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3727 "Port (%d) promiscuous mode not disabled",
3728 test_params->bonded_port_id);
3730 for (i = 0; i < test_params->bonded_slave_count; i++) {
3731 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3732 test_params->slave_port_ids[i]), 0,
3733 "Port (%d) promiscuous mode not disabled",
3734 test_params->slave_port_ids[i]);
3737 /* Clean up and remove slaves from bonded device */
3738 return remove_slaves_and_stop_bonded_device();
3742 test_broadcast_verify_mac_assignment(void)
3744 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3748 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3749 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3751 /* Initialize bonded device with 4 slaves in round robin mode */
3752 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3753 BONDING_MODE_BROADCAST, 0, 4, 1),
3754 "Failed to initialise bonded device");
3756 /* Verify that all MACs are the same as first slave added to bonded
3758 for (i = 0; i < test_params->bonded_slave_count; i++) {
3759 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3760 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3761 sizeof(read_mac_addr)),
3762 "slave port (%d) mac address not set to that of primary port",
3763 test_params->slave_port_ids[i]);
3766 /* change primary and verify that MAC addresses haven't changed */
3767 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3768 test_params->slave_port_ids[2]),
3769 "Failed to set bonded port (%d) primary port to (%d)",
3770 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3772 for (i = 0; i < test_params->bonded_slave_count; i++) {
3773 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3774 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3775 sizeof(read_mac_addr)),
3776 "slave port (%d) mac address has changed to that of primary "
3777 "port without stop/start toggle of bonded device",
3778 test_params->slave_port_ids[i]);
3781 /* stop / start bonded device and verify that primary MAC address is
3782 * propagated to bonded device and slaves */
3784 rte_eth_dev_stop(test_params->bonded_port_id);
3786 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3787 "Failed to start bonded device");
3789 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3790 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3791 sizeof(read_mac_addr)),
3792 "bonded port (%d) mac address not set to that of new primary port",
3793 test_params->slave_port_ids[i]);
3795 for (i = 0; i < test_params->bonded_slave_count; i++) {
3796 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3797 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3798 sizeof(read_mac_addr)),
3799 "slave port (%d) mac address not set to that of new primary "
3800 "port", test_params->slave_port_ids[i]);
3803 /* Set explicit MAC address */
3804 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3805 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3806 "Failed to set MAC address");
3808 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3809 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3810 sizeof(read_mac_addr)),
3811 "bonded port (%d) mac address not set to that of new primary port",
3812 test_params->slave_port_ids[i]);
3815 for (i = 0; i < test_params->bonded_slave_count; i++) {
3816 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3817 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3818 sizeof(read_mac_addr)),
3819 "slave port (%d) mac address not set to that of new primary "
3820 "port", test_params->slave_port_ids[i]);
3823 /* Clean up and remove slaves from bonded device */
3824 return remove_slaves_and_stop_bonded_device();
3827 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3829 test_broadcast_verify_slave_link_status_change_behaviour(void)
3831 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3832 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3833 struct rte_eth_stats port_stats;
3835 uint16_t slaves[RTE_MAX_ETHPORTS];
3837 int i, burst_size, slave_count;
3839 memset(pkt_burst, 0, sizeof(pkt_burst));
3841 /* Initialize bonded device with 4 slaves in round robin mode */
3842 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3843 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3844 1), "Failed to initialise bonded device");
3846 /* Verify Current Slaves Count /Active Slave Count is */
3847 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3849 TEST_ASSERT_EQUAL(slave_count, 4,
3850 "Number of slaves (%d) is not as expected (%d).",
3853 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3854 slaves, RTE_MAX_ETHPORTS);
3855 TEST_ASSERT_EQUAL(slave_count, 4,
3856 "Number of active slaves (%d) is not as expected (%d).",
3859 /* Set 2 slaves link status to down */
3860 virtual_ethdev_simulate_link_status_interrupt(
3861 test_params->slave_port_ids[1], 0);
3862 virtual_ethdev_simulate_link_status_interrupt(
3863 test_params->slave_port_ids[3], 0);
3865 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3866 slaves, RTE_MAX_ETHPORTS);
3867 TEST_ASSERT_EQUAL(slave_count, 2,
3868 "Number of active slaves (%d) is not as expected (%d).",
3871 for (i = 0; i < test_params->bonded_slave_count; i++)
3872 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3874 /* Verify that pkts are not sent on slaves with link status down */
3877 TEST_ASSERT_EQUAL(generate_test_burst(
3878 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3879 "generate_test_burst failed");
3881 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3882 &pkt_burst[0][0], burst_size), burst_size,
3883 "rte_eth_tx_burst failed\n");
3885 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3886 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3887 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3888 test_params->bonded_port_id, (int)port_stats.opackets,
3889 burst_size * slave_count);
3891 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3892 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3893 "(%d) port_stats.opackets not as expected",
3894 test_params->slave_port_ids[0]);
3896 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3897 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3898 "(%d) port_stats.opackets not as expected",
3899 test_params->slave_port_ids[1]);
3901 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3902 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3903 "(%d) port_stats.opackets not as expected",
3904 test_params->slave_port_ids[2]);
3907 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3908 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3909 "(%d) port_stats.opackets not as expected",
3910 test_params->slave_port_ids[3]);
3913 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3914 TEST_ASSERT_EQUAL(generate_test_burst(
3915 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3916 burst_size, "failed to generate packet burst");
3918 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3919 &pkt_burst[i][0], burst_size);
3922 /* Verify that pkts are not received on slaves with link status down */
3923 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3924 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3925 burst_size + burst_size, "rte_eth_rx_burst failed");
3928 /* Verify bonded device rx count */
3929 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3930 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3931 "(%d) port_stats.ipackets not as expected\n",
3932 test_params->bonded_port_id);
3934 /* Clean up and remove slaves from bonded device */
3935 return remove_slaves_and_stop_bonded_device();
3939 test_reconfigure_bonded_device(void)
3941 test_params->nb_rx_q = 4;
3942 test_params->nb_tx_q = 4;
3944 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3945 "failed to reconfigure bonded device");
3947 test_params->nb_rx_q = 2;
3948 test_params->nb_tx_q = 2;
3950 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3951 "failed to reconfigure bonded device with less rx/tx queues");
3958 test_close_bonded_device(void)
3960 rte_eth_dev_close(test_params->bonded_port_id);
3965 testsuite_teardown(void)
3967 free(test_params->pkt_eth_hdr);
3968 test_params->pkt_eth_hdr = NULL;
3970 /* Clean up and remove slaves from bonded device */
3971 remove_slaves_and_stop_bonded_device();
3975 free_virtualpmd_tx_queue(void)
3977 int i, slave_port, to_free_cnt;
3978 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
3980 /* Free tx queue of virtual pmd */
3981 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
3983 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
3984 test_params->slave_port_ids[slave_port],
3985 pkts_to_free, MAX_PKT_BURST);
3986 for (i = 0; i < to_free_cnt; i++)
3987 rte_pktmbuf_free(pkts_to_free[i]);
3992 test_tlb_tx_burst(void)
3994 int i, burst_size, nb_tx;
3995 uint64_t nb_tx2 = 0;
3996 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
3997 struct rte_eth_stats port_stats[32];
3998 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4001 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4002 (BONDING_MODE_TLB, 1, 3, 1),
4003 "Failed to initialise bonded device");
4005 burst_size = 20 * test_params->bonded_slave_count;
4007 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4008 "Burst size specified is greater than supported.\n");
4011 /* Generate bursts of packets */
4012 for (i = 0; i < 400000; i++) {
4013 /*test two types of mac src own(bonding) and others */
4015 initialize_eth_header(test_params->pkt_eth_hdr,
4016 (struct ether_addr *)src_mac,
4017 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4019 initialize_eth_header(test_params->pkt_eth_hdr,
4020 (struct ether_addr *)test_params->default_slave_mac,
4021 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4023 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4025 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4026 dst_addr_0, pktlen);
4027 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4028 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4029 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4030 /* Send burst on bonded port */
4031 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4035 free_virtualpmd_tx_queue();
4037 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4038 "number of packet not equal burst size");
4044 /* Verify bonded port tx stats */
4045 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4047 all_bond_opackets = port_stats[0].opackets;
4048 all_bond_obytes = port_stats[0].obytes;
4050 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4051 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4052 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4056 /* Verify slave ports tx stats */
4057 for (i = 0; i < test_params->bonded_slave_count; i++) {
4058 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4059 sum_ports_opackets += port_stats[i].opackets;
4062 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4063 "Total packets sent by slaves is not equal to packets sent by bond interface");
4065 /* checking if distribution of packets is balanced over slaves */
4066 for (i = 0; i < test_params->bonded_slave_count; i++) {
4067 TEST_ASSERT(port_stats[i].obytes > 0 &&
4068 port_stats[i].obytes < all_bond_obytes,
4069 "Packets are not balanced over slaves");
4072 /* Put all slaves down and try and transmit */
4073 for (i = 0; i < test_params->bonded_slave_count; i++) {
4074 virtual_ethdev_simulate_link_status_interrupt(
4075 test_params->slave_port_ids[i], 0);
4078 /* Send burst on bonded port */
4079 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4081 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4083 /* Clean ugit checkout masterp and remove slaves from bonded device */
4084 return remove_slaves_and_stop_bonded_device();
4087 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4090 test_tlb_rx_burst(void)
4092 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4093 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4095 struct rte_eth_stats port_stats;
4099 uint16_t i, j, nb_rx, burst_size = 17;
4101 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4102 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4104 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4105 "Failed to initialize bonded device");
4108 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4109 TEST_ASSERT(primary_port >= 0,
4110 "failed to get primary slave for bonded port (%d)",
4111 test_params->bonded_port_id);
4113 for (i = 0; i < test_params->bonded_slave_count; i++) {
4114 /* Generate test bursts of packets to transmit */
4115 TEST_ASSERT_EQUAL(generate_test_burst(
4116 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4117 "burst generation failed");
4119 /* Add rx data to slave */
4120 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4121 &gen_pkt_burst[0], burst_size);
4123 /* Call rx burst on bonded device */
4124 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4125 &rx_pkt_burst[0], MAX_PKT_BURST);
4127 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4129 if (test_params->slave_port_ids[i] == primary_port) {
4130 /* Verify bonded device rx count */
4131 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4132 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4133 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4134 test_params->bonded_port_id,
4135 (unsigned int)port_stats.ipackets, burst_size);
4137 /* Verify bonded slave devices rx count */
4138 for (j = 0; j < test_params->bonded_slave_count; j++) {
4139 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4141 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4142 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4143 test_params->slave_port_ids[i],
4144 (unsigned int)port_stats.ipackets, burst_size);
4146 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4147 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4148 test_params->slave_port_ids[i],
4149 (unsigned int)port_stats.ipackets, 0);
4153 for (j = 0; j < test_params->bonded_slave_count; j++) {
4154 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4155 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4156 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4157 test_params->slave_port_ids[i],
4158 (unsigned int)port_stats.ipackets, 0);
4163 for (i = 0; i < burst_size; i++)
4164 rte_pktmbuf_free(rx_pkt_burst[i]);
4166 /* reset bonded device stats */
4167 rte_eth_stats_reset(test_params->bonded_port_id);
4170 /* Clean up and remove slaves from bonded device */
4171 return remove_slaves_and_stop_bonded_device();
4175 test_tlb_verify_promiscuous_enable_disable(void)
4177 int i, primary_port, promiscuous_en;
4179 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4180 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4181 BONDING_MODE_TLB, 0, 4, 1),
4182 "Failed to initialize bonded device");
4184 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4185 TEST_ASSERT(primary_port >= 0,
4186 "failed to get primary slave for bonded port (%d)",
4187 test_params->bonded_port_id);
4189 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4191 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4192 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4193 "Port (%d) promiscuous mode not enabled\n",
4194 test_params->bonded_port_id);
4195 for (i = 0; i < test_params->bonded_slave_count; i++) {
4196 promiscuous_en = rte_eth_promiscuous_get(
4197 test_params->slave_port_ids[i]);
4198 if (primary_port == test_params->slave_port_ids[i]) {
4199 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4200 "Port (%d) promiscuous mode not enabled\n",
4201 test_params->bonded_port_id);
4203 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4204 "Port (%d) promiscuous mode enabled\n",
4205 test_params->bonded_port_id);
4210 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4212 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4213 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4214 "Port (%d) promiscuous mode not disabled\n",
4215 test_params->bonded_port_id);
4217 for (i = 0; i < test_params->bonded_slave_count; i++) {
4218 promiscuous_en = rte_eth_promiscuous_get(
4219 test_params->slave_port_ids[i]);
4220 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4221 "slave port (%d) promiscuous mode not disabled\n",
4222 test_params->slave_port_ids[i]);
4225 /* Clean up and remove slaves from bonded device */
4226 return remove_slaves_and_stop_bonded_device();
4230 test_tlb_verify_mac_assignment(void)
4232 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4234 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4235 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4237 /* Initialize bonded device with 2 slaves in active backup mode */
4238 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4239 BONDING_MODE_TLB, 0, 2, 1),
4240 "Failed to initialize bonded device");
4242 /* Verify that bonded MACs is that of first slave and that the other slave
4243 * MAC hasn't been changed */
4244 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4245 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4246 sizeof(read_mac_addr)),
4247 "bonded port (%d) mac address not set to that of primary port",
4248 test_params->bonded_port_id);
4250 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4251 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4252 sizeof(read_mac_addr)),
4253 "slave port (%d) mac address not set to that of primary port",
4254 test_params->slave_port_ids[0]);
4256 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4257 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4258 sizeof(read_mac_addr)),
4259 "slave port (%d) mac address not as expected",
4260 test_params->slave_port_ids[1]);
4262 /* change primary and verify that MAC addresses haven't changed */
4263 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4264 test_params->slave_port_ids[1]), 0,
4265 "Failed to set bonded port (%d) primary port to (%d)",
4266 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4268 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4269 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4270 sizeof(read_mac_addr)),
4271 "bonded port (%d) mac address not set to that of primary port",
4272 test_params->bonded_port_id);
4274 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4275 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4276 sizeof(read_mac_addr)),
4277 "slave port (%d) mac address not set to that of primary port",
4278 test_params->slave_port_ids[0]);
4280 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4281 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4282 sizeof(read_mac_addr)),
4283 "slave port (%d) mac address not as expected",
4284 test_params->slave_port_ids[1]);
4286 /* stop / start bonded device and verify that primary MAC address is
4287 * propagated to bonded device and slaves */
4289 rte_eth_dev_stop(test_params->bonded_port_id);
4291 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4292 "Failed to start device");
4294 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4295 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4296 sizeof(read_mac_addr)),
4297 "bonded port (%d) mac address not set to that of primary port",
4298 test_params->bonded_port_id);
4300 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4301 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4302 sizeof(read_mac_addr)),
4303 "slave port (%d) mac address not as expected",
4304 test_params->slave_port_ids[0]);
4306 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4307 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4308 sizeof(read_mac_addr)),
4309 "slave port (%d) mac address not set to that of primary port",
4310 test_params->slave_port_ids[1]);
4313 /* Set explicit MAC address */
4314 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4315 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4316 "failed to set MAC address");
4318 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4319 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4320 sizeof(read_mac_addr)),
4321 "bonded port (%d) mac address not set to that of bonded port",
4322 test_params->bonded_port_id);
4324 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4325 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4326 sizeof(read_mac_addr)),
4327 "slave port (%d) mac address not as expected",
4328 test_params->slave_port_ids[0]);
4330 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4331 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4332 sizeof(read_mac_addr)),
4333 "slave port (%d) mac address not set to that of bonded port",
4334 test_params->slave_port_ids[1]);
4336 /* Clean up and remove slaves from bonded device */
4337 return remove_slaves_and_stop_bonded_device();
4341 test_tlb_verify_slave_link_status_change_failover(void)
4343 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4344 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4345 struct rte_eth_stats port_stats;
4347 uint16_t slaves[RTE_MAX_ETHPORTS];
4349 int i, burst_size, slave_count, primary_port;
4353 memset(pkt_burst, 0, sizeof(pkt_burst));
4357 /* Initialize bonded device with 4 slaves in round robin mode */
4358 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4359 BONDING_MODE_TLB, 0,
4360 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4361 "Failed to initialize bonded device with slaves");
4363 /* Verify Current Slaves Count /Active Slave Count is */
4364 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4366 TEST_ASSERT_EQUAL(slave_count, 4,
4367 "Number of slaves (%d) is not as expected (%d).\n",
4370 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4371 slaves, RTE_MAX_ETHPORTS);
4372 TEST_ASSERT_EQUAL(slave_count, (int)4,
4373 "Number of slaves (%d) is not as expected (%d).\n",
4376 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4377 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4378 "Primary port not as expected");
4380 /* Bring 2 slaves down and verify active slave count */
4381 virtual_ethdev_simulate_link_status_interrupt(
4382 test_params->slave_port_ids[1], 0);
4383 virtual_ethdev_simulate_link_status_interrupt(
4384 test_params->slave_port_ids[3], 0);
4386 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4387 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4388 "Number of active slaves (%d) is not as expected (%d).",
4391 virtual_ethdev_simulate_link_status_interrupt(
4392 test_params->slave_port_ids[1], 1);
4393 virtual_ethdev_simulate_link_status_interrupt(
4394 test_params->slave_port_ids[3], 1);
4397 /* Bring primary port down, verify that active slave count is 3 and primary
4399 virtual_ethdev_simulate_link_status_interrupt(
4400 test_params->slave_port_ids[0], 0);
4402 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4403 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4404 "Number of active slaves (%d) is not as expected (%d).",
4407 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4408 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4409 "Primary port not as expected");
4410 rte_delay_us(500000);
4411 /* Verify that pkts are sent on new primary slave */
4412 for (i = 0; i < 4; i++) {
4413 TEST_ASSERT_EQUAL(generate_test_burst(
4414 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4415 "generate_test_burst failed\n");
4416 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4417 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4418 "rte_eth_tx_burst failed\n");
4419 rte_delay_us(11000);
4422 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4423 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4424 "(%d) port_stats.opackets not as expected\n",
4425 test_params->slave_port_ids[0]);
4427 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4428 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4429 "(%d) port_stats.opackets not as expected\n",
4430 test_params->slave_port_ids[1]);
4432 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4433 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4434 "(%d) port_stats.opackets not as expected\n",
4435 test_params->slave_port_ids[2]);
4437 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4438 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4439 "(%d) port_stats.opackets not as expected\n",
4440 test_params->slave_port_ids[3]);
4443 /* Generate packet burst for testing */
4445 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4446 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4450 virtual_ethdev_add_mbufs_to_rx_queue(
4451 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4454 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4455 MAX_PKT_BURST) != burst_size) {
4456 printf("rte_eth_rx_burst\n");
4461 /* Verify bonded device rx count */
4462 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4463 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4464 "(%d) port_stats.ipackets not as expected\n",
4465 test_params->bonded_port_id);
4467 /* Clean up and remove slaves from bonded device */
4468 return remove_slaves_and_stop_bonded_device();
4471 #define TEST_ALB_SLAVE_COUNT 2
4473 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4474 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4475 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4476 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4478 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4479 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4480 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4481 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4482 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4485 test_alb_change_mac_in_reply_sent(void)
4487 struct rte_mbuf *pkt;
4488 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4490 struct ether_hdr *eth_pkt;
4491 struct arp_hdr *arp_pkt;
4493 int slave_idx, nb_pkts, pkt_idx;
4496 struct ether_addr bond_mac, client_mac;
4497 struct ether_addr *slave_mac1, *slave_mac2;
4499 TEST_ASSERT_SUCCESS(
4500 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4501 0, TEST_ALB_SLAVE_COUNT, 1),
4502 "Failed to initialize_bonded_device_with_slaves.");
4504 /* Flush tx queue */
4505 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4506 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4508 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4509 test_params->slave_port_ids[slave_idx], pkts_sent,
4514 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4518 * Generating four packets with different mac and ip addresses and sending
4519 * them through the bonding port.
4521 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4522 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4523 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4524 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4526 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4527 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4529 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4531 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4532 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4533 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4534 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4536 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4537 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4539 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4541 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4542 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4543 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4544 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4546 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4547 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4549 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4551 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4552 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4553 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4554 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4556 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4557 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4559 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4562 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4564 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4567 * Checking if packets are properly distributed on bonding ports. Packets
4568 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4570 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4571 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4572 test_params->slave_port_ids[slave_idx], pkts_sent,
4575 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4576 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4577 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4579 if (slave_idx%2 == 0) {
4580 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4585 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4594 retval += remove_slaves_and_stop_bonded_device();
4599 test_alb_reply_from_client(void)
4601 struct ether_hdr *eth_pkt;
4602 struct arp_hdr *arp_pkt;
4604 struct rte_mbuf *pkt;
4605 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4607 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4610 struct ether_addr bond_mac, client_mac;
4611 struct ether_addr *slave_mac1, *slave_mac2;
4613 TEST_ASSERT_SUCCESS(
4614 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4615 0, TEST_ALB_SLAVE_COUNT, 1),
4616 "Failed to initialize_bonded_device_with_slaves.");
4618 /* Flush tx queue */
4619 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4620 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4621 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4622 test_params->slave_port_ids[slave_idx], pkts_sent,
4627 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4631 * Generating four packets with different mac and ip addresses and placing
4632 * them in the rx queue to be received by the bonding driver on rx_burst.
4634 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4635 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4636 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4637 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4639 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4640 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4642 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4645 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4646 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4647 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4648 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4650 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4651 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4653 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4656 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4657 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4658 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4659 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4661 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4662 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4664 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4667 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4668 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4669 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4670 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4672 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4673 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4675 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4679 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4680 * packets to every client in alb table.
4682 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4683 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4685 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4686 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4689 * Checking if update ARP packets were properly send on slave ports.
4691 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4692 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4693 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4694 nb_pkts_sum += nb_pkts;
4696 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4697 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4698 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4700 if (slave_idx%2 == 0) {
4701 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4706 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4714 /* Check if proper number of packets was send */
4715 if (nb_pkts_sum < 4) {
4721 retval += remove_slaves_and_stop_bonded_device();
4726 test_alb_receive_vlan_reply(void)
4728 struct ether_hdr *eth_pkt;
4729 struct vlan_hdr *vlan_pkt;
4730 struct arp_hdr *arp_pkt;
4732 struct rte_mbuf *pkt;
4733 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4735 int slave_idx, nb_pkts, pkt_idx;
4738 struct ether_addr bond_mac, client_mac;
4740 TEST_ASSERT_SUCCESS(
4741 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4742 0, TEST_ALB_SLAVE_COUNT, 1),
4743 "Failed to initialize_bonded_device_with_slaves.");
4745 /* Flush tx queue */
4746 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4747 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4748 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4749 test_params->slave_port_ids[slave_idx], pkts_sent,
4754 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4758 * Generating packet with double VLAN header and placing it in the rx queue.
4760 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4761 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4762 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4763 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4765 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4766 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4767 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4768 vlan_pkt = vlan_pkt+1;
4769 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4770 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4771 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4772 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4774 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4777 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4778 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4781 * Checking if VLAN headers in generated ARP Update packet are correct.
4783 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4784 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4785 test_params->slave_port_ids[slave_idx], pkts_sent,
4788 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4789 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4790 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4791 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4795 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4799 vlan_pkt = vlan_pkt+1;
4800 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4804 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4812 retval += remove_slaves_and_stop_bonded_device();
4817 test_alb_ipv4_tx(void)
4819 int burst_size, retval, pkts_send;
4820 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4824 TEST_ASSERT_SUCCESS(
4825 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4826 0, TEST_ALB_SLAVE_COUNT, 1),
4827 "Failed to initialize_bonded_device_with_slaves.");
4831 /* Generate test bursts of packets to transmit */
4832 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4838 * Checking if ipv4 traffic is transmitted via TLB policy.
4840 pkts_send = rte_eth_tx_burst(
4841 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4842 if (pkts_send != burst_size) {
4848 retval += remove_slaves_and_stop_bonded_device();
4852 static struct unit_test_suite link_bonding_test_suite = {
4853 .suite_name = "Link Bonding Unit Test Suite",
4854 .setup = test_setup,
4855 .teardown = testsuite_teardown,
4856 .unit_test_cases = {
4857 TEST_CASE(test_create_bonded_device),
4858 TEST_CASE(test_create_bonded_device_with_invalid_params),
4859 TEST_CASE(test_add_slave_to_bonded_device),
4860 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4861 TEST_CASE(test_remove_slave_from_bonded_device),
4862 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4863 TEST_CASE(test_get_slaves_from_bonded_device),
4864 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4865 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4866 TEST_CASE(test_start_bonded_device),
4867 TEST_CASE(test_stop_bonded_device),
4868 TEST_CASE(test_set_bonding_mode),
4869 TEST_CASE(test_set_primary_slave),
4870 TEST_CASE(test_set_explicit_bonded_mac),
4871 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4872 TEST_CASE(test_status_interrupt),
4873 TEST_CASE(test_adding_slave_after_bonded_device_started),
4874 TEST_CASE(test_roundrobin_tx_burst),
4875 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4876 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4877 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4878 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4879 TEST_CASE(test_roundrobin_verify_mac_assignment),
4880 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4881 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4882 TEST_CASE(test_activebackup_tx_burst),
4883 TEST_CASE(test_activebackup_rx_burst),
4884 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4885 TEST_CASE(test_activebackup_verify_mac_assignment),
4886 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4887 TEST_CASE(test_balance_xmit_policy_configuration),
4888 TEST_CASE(test_balance_l2_tx_burst),
4889 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4890 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4891 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4892 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4893 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4894 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4895 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4896 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4897 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4898 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4899 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4900 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4901 TEST_CASE(test_balance_rx_burst),
4902 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4903 TEST_CASE(test_balance_verify_mac_assignment),
4904 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4905 TEST_CASE(test_tlb_tx_burst),
4906 TEST_CASE(test_tlb_rx_burst),
4907 TEST_CASE(test_tlb_verify_mac_assignment),
4908 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4909 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4910 TEST_CASE(test_alb_change_mac_in_reply_sent),
4911 TEST_CASE(test_alb_reply_from_client),
4912 TEST_CASE(test_alb_receive_vlan_reply),
4913 TEST_CASE(test_alb_ipv4_tx),
4914 TEST_CASE(test_broadcast_tx_burst),
4915 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4916 TEST_CASE(test_broadcast_rx_burst),
4917 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4918 TEST_CASE(test_broadcast_verify_mac_assignment),
4919 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4920 TEST_CASE(test_reconfigure_bonded_device),
4921 TEST_CASE(test_close_bonded_device),
4923 TEST_CASES_END() /**< NULL terminate unit test array */
4929 test_link_bonding(void)
4931 return unit_test_suite_runner(&link_bonding_test_suite);
4934 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);