1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
13 #include <sys/queue.h>
15 #include <rte_cycles.h>
16 #include <rte_byteorder.h>
17 #include <rte_common.h>
18 #include <rte_debug.h>
19 #include <rte_ethdev.h>
20 #include <ethdev_driver.h>
22 #include <rte_lcore.h>
23 #include <rte_memory.h>
24 #include <rte_string_fns.h>
25 #include <rte_eth_bond.h>
27 #include "virtual_pmd.h"
28 #include "packet_burst_generator.h"
32 #define TEST_MAX_NUMBER_OF_PORTS (6)
34 #define RX_RING_SIZE 1024
35 #define RX_FREE_THRESH 32
40 #define TX_RING_SIZE 1024
41 #define TX_FREE_THRESH 32
45 #define TX_RSBIT_THRESH 32
47 #define MBUF_CACHE_SIZE (250)
48 #define BURST_SIZE (32)
50 #define RTE_TEST_RX_DESC_MAX (2048)
51 #define RTE_TEST_TX_DESC_MAX (2048)
52 #define MAX_PKT_BURST (512)
53 #define DEF_PKT_BURST (16)
55 #define BONDED_DEV_NAME ("net_bonding_ut")
57 #define INVALID_SOCKET_ID (-1)
58 #define INVALID_PORT_ID (-1)
59 #define INVALID_BONDING_MODE (-1)
62 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
63 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
65 struct link_bonding_unittest_params {
66 int16_t bonded_port_id;
67 int16_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
68 uint16_t bonded_slave_count;
74 struct rte_mempool *mbuf_pool;
76 struct rte_ether_addr *default_slave_mac;
77 struct rte_ether_addr *default_bonded_mac;
80 struct rte_ether_hdr *pkt_eth_hdr;
81 struct rte_ipv4_hdr *pkt_ipv4_hdr;
82 struct rte_ipv6_hdr *pkt_ipv6_hdr;
83 struct rte_udp_hdr *pkt_udp_hdr;
87 static struct rte_ipv4_hdr pkt_ipv4_hdr;
88 static struct rte_ipv6_hdr pkt_ipv6_hdr;
89 static struct rte_udp_hdr pkt_udp_hdr;
91 static struct link_bonding_unittest_params default_params = {
93 .slave_port_ids = { -1 },
94 .bonded_slave_count = 0,
95 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
102 .default_slave_mac = (struct rte_ether_addr *)slave_mac,
103 .default_bonded_mac = (struct rte_ether_addr *)bonded_mac,
106 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
107 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
108 .pkt_udp_hdr = &pkt_udp_hdr
112 static struct link_bonding_unittest_params *test_params = &default_params;
114 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
115 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
116 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
118 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
119 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
120 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
122 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
123 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
124 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
125 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
126 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
127 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
129 static uint16_t src_port = 1024;
130 static uint16_t dst_port_0 = 1024;
131 static uint16_t dst_port_1 = 2024;
133 static uint16_t vlan_id = 0x100;
135 static struct rte_eth_conf default_pmd_conf = {
137 .mq_mode = RTE_ETH_MQ_RX_NONE,
141 .mq_mode = RTE_ETH_MQ_TX_NONE,
146 static const struct rte_eth_rxconf rx_conf_default = {
148 .pthresh = RX_PTHRESH,
149 .hthresh = RX_HTHRESH,
150 .wthresh = RX_WTHRESH,
152 .rx_free_thresh = RX_FREE_THRESH,
156 static struct rte_eth_txconf tx_conf_default = {
158 .pthresh = TX_PTHRESH,
159 .hthresh = TX_HTHRESH,
160 .wthresh = TX_WTHRESH,
162 .tx_free_thresh = TX_FREE_THRESH,
163 .tx_rs_thresh = TX_RSBIT_THRESH,
166 static void free_virtualpmd_tx_queue(void);
171 configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
176 default_pmd_conf.intr_conf.lsc = 1;
178 default_pmd_conf.intr_conf.lsc = 0;
180 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
181 test_params->nb_tx_q, &default_pmd_conf),
182 "rte_eth_dev_configure for port %d failed", port_id);
184 int ret = rte_eth_dev_set_mtu(port_id, 1550);
185 RTE_TEST_ASSERT(ret == 0 || ret == -ENOTSUP,
186 "rte_eth_dev_set_mtu for port %d failed", port_id);
188 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
189 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
190 rte_eth_dev_socket_id(port_id), &rx_conf_default,
191 test_params->mbuf_pool) ,
192 "rte_eth_rx_queue_setup for port %d failed", port_id);
194 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
195 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
196 rte_eth_dev_socket_id(port_id), &tx_conf_default),
197 "rte_eth_tx_queue_setup for port %d failed", port_id);
200 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
201 "rte_eth_dev_start for port %d failed", port_id);
206 static int slaves_initialized;
207 static int mac_slaves_initialized;
209 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
210 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
216 int i, nb_mbuf_per_pool;
217 struct rte_ether_addr *mac_addr = (struct rte_ether_addr *)slave_mac;
219 /* Allocate ethernet packet header with space for VLAN header */
220 if (test_params->pkt_eth_hdr == NULL) {
221 test_params->pkt_eth_hdr = malloc(sizeof(struct rte_ether_hdr) +
222 sizeof(struct rte_vlan_hdr));
224 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
225 "Ethernet header struct allocation failed!");
228 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
229 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
230 if (test_params->mbuf_pool == NULL) {
231 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
232 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
233 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
234 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
235 "rte_mempool_create failed");
238 /* Create / Initialize virtual eth devs */
239 if (!slaves_initialized) {
240 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
241 char pmd_name[RTE_ETH_NAME_MAX_LEN];
243 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
245 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
247 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
248 mac_addr, rte_socket_id(), 1);
249 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
250 "Failed to create virtual virtual ethdev %s", pmd_name);
252 TEST_ASSERT_SUCCESS(configure_ethdev(
253 test_params->slave_port_ids[i], 1, 0),
254 "Failed to configure virtual ethdev %s", pmd_name);
256 slaves_initialized = 1;
263 test_create_bonded_device(void)
265 int current_slave_count;
267 uint16_t slaves[RTE_MAX_ETHPORTS];
269 /* Don't try to recreate bonded device if re-running test suite*/
270 if (test_params->bonded_port_id == -1) {
271 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
272 test_params->bonding_mode, rte_socket_id());
274 TEST_ASSERT(test_params->bonded_port_id >= 0,
275 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
277 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
278 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
281 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
282 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
283 test_params->bonded_port_id, test_params->bonding_mode);
285 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
286 slaves, RTE_MAX_ETHPORTS);
288 TEST_ASSERT_EQUAL(current_slave_count, 0,
289 "Number of slaves %d is great than expected %d.",
290 current_slave_count, 0);
292 current_slave_count = rte_eth_bond_active_slaves_get(
293 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
295 TEST_ASSERT_EQUAL(current_slave_count, 0,
296 "Number of active slaves %d is great than expected %d.",
297 current_slave_count, 0);
304 test_create_bonded_device_with_invalid_params(void)
308 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
311 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
313 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
315 test_params->bonding_mode = INVALID_BONDING_MODE;
317 /* Invalid bonding mode */
318 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
320 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
322 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
324 /* Invalid socket id */
325 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
327 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
333 test_add_slave_to_bonded_device(void)
335 int current_slave_count;
337 uint16_t slaves[RTE_MAX_ETHPORTS];
339 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
340 test_params->slave_port_ids[test_params->bonded_slave_count]),
341 "Failed to add slave (%d) to bonded port (%d).",
342 test_params->slave_port_ids[test_params->bonded_slave_count],
343 test_params->bonded_port_id);
345 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
346 slaves, RTE_MAX_ETHPORTS);
347 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
348 "Number of slaves (%d) is greater than expected (%d).",
349 current_slave_count, test_params->bonded_slave_count + 1);
351 current_slave_count = rte_eth_bond_active_slaves_get(
352 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
353 TEST_ASSERT_EQUAL(current_slave_count, 0,
354 "Number of active slaves (%d) is not as expected (%d).\n",
355 current_slave_count, 0);
357 test_params->bonded_slave_count++;
363 test_add_slave_to_invalid_bonded_device(void)
365 /* Invalid port ID */
366 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
367 test_params->slave_port_ids[test_params->bonded_slave_count]),
368 "Expected call to failed as invalid port specified.");
370 /* Non bonded device */
371 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
372 test_params->slave_port_ids[test_params->bonded_slave_count]),
373 "Expected call to failed as invalid port specified.");
380 test_remove_slave_from_bonded_device(void)
382 int current_slave_count;
383 struct rte_ether_addr read_mac_addr, *mac_addr;
384 uint16_t slaves[RTE_MAX_ETHPORTS];
386 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
387 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
388 "Failed to remove slave %d from bonded port (%d).",
389 test_params->slave_port_ids[test_params->bonded_slave_count-1],
390 test_params->bonded_port_id);
393 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
394 slaves, RTE_MAX_ETHPORTS);
396 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
397 "Number of slaves (%d) is great than expected (%d).\n",
398 current_slave_count, test_params->bonded_slave_count - 1);
401 mac_addr = (struct rte_ether_addr *)slave_mac;
402 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] =
403 test_params->bonded_slave_count-1;
405 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(
406 test_params->slave_port_ids[test_params->bonded_slave_count-1],
408 "Failed to get mac address (port %d)",
409 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
410 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
411 "bonded port mac address not set to that of primary port\n");
414 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
416 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
419 test_params->bonded_slave_count--;
425 test_remove_slave_from_invalid_bonded_device(void)
427 /* Invalid port ID */
428 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
429 test_params->bonded_port_id + 5,
430 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
431 "Expected call to failed as invalid port specified.");
433 /* Non bonded device */
434 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
435 test_params->slave_port_ids[0],
436 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
437 "Expected call to failed as invalid port specified.");
442 static int bonded_id = 2;
445 test_add_already_bonded_slave_to_bonded_device(void)
447 int port_id, current_slave_count;
448 uint16_t slaves[RTE_MAX_ETHPORTS];
449 char pmd_name[RTE_ETH_NAME_MAX_LEN];
451 test_add_slave_to_bonded_device();
453 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
454 slaves, RTE_MAX_ETHPORTS);
455 TEST_ASSERT_EQUAL(current_slave_count, 1,
456 "Number of slaves (%d) is not that expected (%d).",
457 current_slave_count, 1);
459 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
461 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
463 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
465 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
466 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
468 "Added slave (%d) to bonded port (%d) unexpectedly.",
469 test_params->slave_port_ids[test_params->bonded_slave_count-1],
472 return test_remove_slave_from_bonded_device();
477 test_get_slaves_from_bonded_device(void)
479 int current_slave_count;
480 uint16_t slaves[RTE_MAX_ETHPORTS];
482 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
483 "Failed to add slave to bonded device");
485 /* Invalid port id */
486 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
488 TEST_ASSERT(current_slave_count < 0,
489 "Invalid port id unexpectedly succeeded");
491 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
492 slaves, RTE_MAX_ETHPORTS);
493 TEST_ASSERT(current_slave_count < 0,
494 "Invalid port id unexpectedly succeeded");
496 /* Invalid slaves pointer */
497 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
498 NULL, RTE_MAX_ETHPORTS);
499 TEST_ASSERT(current_slave_count < 0,
500 "Invalid slave array unexpectedly succeeded");
502 current_slave_count = rte_eth_bond_active_slaves_get(
503 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
504 TEST_ASSERT(current_slave_count < 0,
505 "Invalid slave array unexpectedly succeeded");
507 /* non bonded device*/
508 current_slave_count = rte_eth_bond_slaves_get(
509 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
510 TEST_ASSERT(current_slave_count < 0,
511 "Invalid port id unexpectedly succeeded");
513 current_slave_count = rte_eth_bond_active_slaves_get(
514 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
515 TEST_ASSERT(current_slave_count < 0,
516 "Invalid port id unexpectedly succeeded");
518 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
519 "Failed to remove slaves from bonded device");
526 test_add_remove_multiple_slaves_to_from_bonded_device(void)
530 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
531 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
532 "Failed to add slave to bonded device");
534 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
535 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
536 "Failed to remove slaves from bonded device");
542 enable_bonded_slaves(void)
546 for (i = 0; i < test_params->bonded_slave_count; i++) {
547 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
550 virtual_ethdev_simulate_link_status_interrupt(
551 test_params->slave_port_ids[i], 1);
556 test_start_bonded_device(void)
558 struct rte_eth_link link_status;
560 int current_slave_count, current_bonding_mode, primary_port;
561 uint16_t slaves[RTE_MAX_ETHPORTS];
564 /* Add slave to bonded device*/
565 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
566 "Failed to add slave to bonded device");
568 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
569 "Failed to start bonded pmd eth device %d.",
570 test_params->bonded_port_id);
572 /* Change link status of virtual pmd so it will be added to the active
573 * slave list of the bonded device*/
574 virtual_ethdev_simulate_link_status_interrupt(
575 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
577 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
578 slaves, RTE_MAX_ETHPORTS);
579 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
580 "Number of slaves (%d) is not expected value (%d).",
581 current_slave_count, test_params->bonded_slave_count);
583 current_slave_count = rte_eth_bond_active_slaves_get(
584 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
585 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
586 "Number of active slaves (%d) is not expected value (%d).",
587 current_slave_count, test_params->bonded_slave_count);
589 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
590 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
591 "Bonded device mode (%d) is not expected value (%d).\n",
592 current_bonding_mode, test_params->bonding_mode);
594 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
595 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
596 "Primary port (%d) is not expected value (%d).",
597 primary_port, test_params->slave_port_ids[0]);
599 retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
600 TEST_ASSERT(retval >= 0,
601 "Bonded port (%d) link get failed: %s\n",
602 test_params->bonded_port_id, rte_strerror(-retval));
603 TEST_ASSERT_EQUAL(link_status.link_status, 1,
604 "Bonded port (%d) status (%d) is not expected value (%d).\n",
605 test_params->bonded_port_id, link_status.link_status, 1);
611 test_stop_bonded_device(void)
613 int current_slave_count;
614 uint16_t slaves[RTE_MAX_ETHPORTS];
616 struct rte_eth_link link_status;
619 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
620 "Failed to stop bonded port %u",
621 test_params->bonded_port_id);
623 retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
624 TEST_ASSERT(retval >= 0,
625 "Bonded port (%d) link get failed: %s\n",
626 test_params->bonded_port_id, rte_strerror(-retval));
627 TEST_ASSERT_EQUAL(link_status.link_status, 0,
628 "Bonded port (%d) status (%d) is not expected value (%d).",
629 test_params->bonded_port_id, link_status.link_status, 0);
631 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
632 slaves, RTE_MAX_ETHPORTS);
633 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
634 "Number of slaves (%d) is not expected value (%d).",
635 current_slave_count, test_params->bonded_slave_count);
637 current_slave_count = rte_eth_bond_active_slaves_get(
638 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
639 TEST_ASSERT_EQUAL(current_slave_count, 0,
640 "Number of active slaves (%d) is not expected value (%d).",
641 current_slave_count, 0);
647 remove_slaves_and_stop_bonded_device(void)
649 /* Clean up and remove slaves from bonded device */
650 free_virtualpmd_tx_queue();
651 while (test_params->bonded_slave_count > 0)
652 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
653 "test_remove_slave_from_bonded_device failed");
655 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
656 "Failed to stop bonded port %u",
657 test_params->bonded_port_id);
659 rte_eth_stats_reset(test_params->bonded_port_id);
660 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
666 test_set_bonding_mode(void)
670 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
671 BONDING_MODE_ACTIVE_BACKUP,
672 BONDING_MODE_BALANCE,
673 BONDING_MODE_BROADCAST
676 /* Test supported link bonding modes */
677 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
678 /* Invalid port ID */
679 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
681 "Expected call to failed as invalid port (%d) specified.",
684 /* Non bonded device */
685 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
687 "Expected call to failed as invalid port (%d) specified.",
688 test_params->slave_port_ids[0]);
690 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
692 "Failed to set link bonding mode on port (%d) to (%d).",
693 test_params->bonded_port_id, bonding_modes[i]);
695 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
696 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
697 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
698 bonding_mode, test_params->bonded_port_id,
701 /* Invalid port ID */
702 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
703 TEST_ASSERT(bonding_mode < 0,
704 "Expected call to failed as invalid port (%d) specified.",
707 /* Non bonded device */
708 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
709 TEST_ASSERT(bonding_mode < 0,
710 "Expected call to failed as invalid port (%d) specified.",
711 test_params->slave_port_ids[0]);
714 return remove_slaves_and_stop_bonded_device();
718 test_set_primary_slave(void)
721 struct rte_ether_addr read_mac_addr;
722 struct rte_ether_addr *expected_mac_addr;
724 /* Add 4 slaves to bonded device */
725 for (i = test_params->bonded_slave_count; i < 4; i++)
726 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
727 "Failed to add slave to bonded device.");
729 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
730 BONDING_MODE_ROUND_ROBIN),
731 "Failed to set link bonding mode on port (%d) to (%d).",
732 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
734 /* Invalid port ID */
735 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
736 test_params->slave_port_ids[i]),
737 "Expected call to failed as invalid port specified.");
739 /* Non bonded device */
740 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
741 test_params->slave_port_ids[i]),
742 "Expected call to failed as invalid port specified.");
744 /* Set slave as primary
745 * Verify slave it is now primary slave
746 * Verify that MAC address of bonded device is that of primary slave
747 * Verify that MAC address of all bonded slaves are that of primary slave
749 for (i = 0; i < 4; i++) {
750 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
751 test_params->slave_port_ids[i]),
752 "Failed to set bonded port (%d) primary port to (%d)",
753 test_params->bonded_port_id, test_params->slave_port_ids[i]);
755 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
756 TEST_ASSERT(retval >= 0,
757 "Failed to read primary port from bonded port (%d)\n",
758 test_params->bonded_port_id);
760 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
761 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
762 test_params->bonded_port_id, retval,
763 test_params->slave_port_ids[i]);
765 /* stop/start bonded eth dev to apply new MAC */
766 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
767 "Failed to stop bonded port %u",
768 test_params->bonded_port_id);
770 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
771 "Failed to start bonded port %d",
772 test_params->bonded_port_id);
774 expected_mac_addr = (struct rte_ether_addr *)&slave_mac;
775 expected_mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
777 /* Check primary slave MAC */
778 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
779 "Failed to get mac address (port %d)",
780 test_params->slave_port_ids[i]);
781 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
782 sizeof(read_mac_addr)),
783 "bonded port mac address not set to that of primary port\n");
785 /* Check bonded MAC */
786 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
787 "Failed to get mac address (port %d)",
788 test_params->bonded_port_id);
789 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
790 sizeof(read_mac_addr)),
791 "bonded port mac address not set to that of primary port\n");
793 /* Check other slaves MACs */
794 for (j = 0; j < 4; j++) {
796 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[j],
798 "Failed to get mac address (port %d)",
799 test_params->slave_port_ids[j]);
800 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
801 sizeof(read_mac_addr)),
802 "slave port mac address not set to that of primary "
809 /* Test with none existent port */
810 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
811 "read primary port from expectedly");
813 /* Test with slave port */
814 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
815 "read primary port from expectedly\n");
817 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
818 "Failed to stop and remove slaves from bonded device");
821 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
822 "read primary port from expectedly\n");
828 test_set_explicit_bonded_mac(void)
831 struct rte_ether_addr read_mac_addr;
832 struct rte_ether_addr *mac_addr;
834 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
836 mac_addr = (struct rte_ether_addr *)explicit_bonded_mac;
838 /* Invalid port ID */
839 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
840 "Expected call to failed as invalid port specified.");
842 /* Non bonded device */
843 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
844 test_params->slave_port_ids[0], mac_addr),
845 "Expected call to failed as invalid port specified.");
847 /* NULL MAC address */
848 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
849 test_params->bonded_port_id, NULL),
850 "Expected call to failed as NULL MAC specified");
852 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
853 test_params->bonded_port_id, mac_addr),
854 "Failed to set MAC address on bonded port (%d)",
855 test_params->bonded_port_id);
857 /* Add 4 slaves to bonded device */
858 for (i = test_params->bonded_slave_count; i < 4; i++) {
859 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
860 "Failed to add slave to bonded device.\n");
863 /* Check bonded MAC */
864 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
865 "Failed to get mac address (port %d)",
866 test_params->bonded_port_id);
867 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
868 "bonded port mac address not set to that of primary port");
870 /* Check other slaves MACs */
871 for (i = 0; i < 4; i++) {
872 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
873 "Failed to get mac address (port %d)",
874 test_params->slave_port_ids[i]);
875 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
876 sizeof(read_mac_addr)),
877 "slave port mac address not set to that of primary port");
880 /* test resetting mac address on bonded device */
882 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
883 "Failed to reset MAC address on bonded port (%d)",
884 test_params->bonded_port_id);
887 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
888 "Reset MAC address on bonded port (%d) unexpectedly",
889 test_params->slave_port_ids[1]);
891 /* test resetting mac address on bonded device with no slaves */
892 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
893 "Failed to remove slaves and stop bonded device");
895 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
896 "Failed to reset MAC address on bonded port (%d)",
897 test_params->bonded_port_id);
902 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
905 test_set_bonded_port_initialization_mac_assignment(void)
909 uint16_t slaves[RTE_MAX_ETHPORTS];
910 static int bonded_port_id = -1;
911 static int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
913 struct rte_ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
915 /* Initialize default values for MAC addresses */
916 memcpy(&slave_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
917 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
920 * 1. a - Create / configure bonded / slave ethdevs
922 if (bonded_port_id == -1) {
923 bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
924 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
925 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
927 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
928 "Failed to configure bonded ethdev");
931 if (!mac_slaves_initialized) {
932 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
933 char pmd_name[RTE_ETH_NAME_MAX_LEN];
935 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] =
938 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN,
941 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
942 &slave_mac_addr, rte_socket_id(), 1);
944 TEST_ASSERT(slave_port_ids[i] >= 0,
945 "Failed to create slave ethdev %s",
948 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
949 "Failed to configure virtual ethdev %s",
952 mac_slaves_initialized = 1;
957 * 2. Add slave ethdevs to bonded device
959 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
960 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
962 "Failed to add slave (%d) to bonded port (%d).",
963 slave_port_ids[i], bonded_port_id);
966 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
968 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
969 "Number of slaves (%d) is not as expected (%d)",
970 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
974 * 3. Set explicit MAC address on bonded ethdev
976 bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-2] = 0xFF;
977 bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0xAA;
979 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
980 bonded_port_id, &bonded_mac_addr),
981 "Failed to set MAC address on bonded port (%d)",
985 /* 4. a - Start bonded ethdev
986 * b - Enable slave devices
987 * c - Verify bonded/slaves ethdev MAC addresses
989 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
990 "Failed to start bonded pmd eth device %d.",
993 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
994 virtual_ethdev_simulate_link_status_interrupt(
995 slave_port_ids[i], 1);
998 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(bonded_port_id, &read_mac_addr),
999 "Failed to get mac address (port %d)",
1001 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1002 sizeof(read_mac_addr)),
1003 "bonded port mac address not as expected");
1005 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1006 "Failed to get mac address (port %d)",
1008 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1009 sizeof(read_mac_addr)),
1010 "slave port 0 mac address not as expected");
1012 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1013 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1014 "Failed to get mac address (port %d)",
1016 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1017 sizeof(read_mac_addr)),
1018 "slave port 1 mac address not as expected");
1020 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1021 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1022 "Failed to get mac address (port %d)",
1024 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1025 sizeof(read_mac_addr)),
1026 "slave port 2 mac address not as expected");
1029 /* 7. a - Change primary port
1030 * b - Stop / Start bonded port
1031 * d - Verify slave ethdev MAC addresses
1033 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1035 "failed to set primary port on bonded device.");
1037 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(bonded_port_id),
1038 "Failed to stop bonded port %u",
1041 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1042 "Failed to start bonded pmd eth device %d.",
1045 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(bonded_port_id, &read_mac_addr),
1046 "Failed to get mac address (port %d)",
1048 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1049 sizeof(read_mac_addr)),
1050 "bonded port mac address not as expected");
1052 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1053 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1054 "Failed to get mac address (port %d)",
1056 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1057 sizeof(read_mac_addr)),
1058 "slave port 0 mac address not as expected");
1060 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1061 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1062 "Failed to get mac address (port %d)",
1064 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1065 sizeof(read_mac_addr)),
1066 "slave port 1 mac address not as expected");
1068 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1069 "Failed to get mac address (port %d)",
1071 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1072 sizeof(read_mac_addr)),
1073 "slave port 2 mac address not as expected");
1075 /* 6. a - Stop bonded ethdev
1076 * b - remove slave ethdevs
1077 * c - Verify slave ethdevs MACs are restored
1079 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(bonded_port_id),
1080 "Failed to stop bonded port %u",
1083 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1084 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1086 "Failed to remove slave %d from bonded port (%d).",
1087 slave_port_ids[i], bonded_port_id);
1090 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1093 TEST_ASSERT_EQUAL(slave_count, 0,
1094 "Number of slaves (%d) is great than expected (%d).",
1097 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1098 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1099 "Failed to get mac address (port %d)",
1101 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1102 sizeof(read_mac_addr)),
1103 "slave port 0 mac address not as expected");
1105 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1106 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1107 "Failed to get mac address (port %d)",
1109 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1110 sizeof(read_mac_addr)),
1111 "slave port 1 mac address not as expected");
1113 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1114 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1115 "Failed to get mac address (port %d)",
1117 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1118 sizeof(read_mac_addr)),
1119 "slave port 2 mac address not as expected");
1126 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1127 uint16_t number_of_slaves, uint8_t enable_slave)
1129 /* Configure bonded device */
1130 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1131 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1132 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1135 /* Add slaves to bonded device */
1136 while (number_of_slaves > test_params->bonded_slave_count)
1137 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1138 "Failed to add slave (%d to bonding port (%d).",
1139 test_params->bonded_slave_count - 1,
1140 test_params->bonded_port_id);
1142 /* Set link bonding mode */
1143 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1145 "Failed to set link bonding mode on port (%d) to (%d).",
1146 test_params->bonded_port_id, bonding_mode);
1148 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1149 "Failed to start bonded pmd eth device %d.",
1150 test_params->bonded_port_id);
1153 enable_bonded_slaves();
1159 test_adding_slave_after_bonded_device_started(void)
1163 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1164 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1165 "Failed to add slaves to bonded device");
1167 /* Enabled slave devices */
1168 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1169 virtual_ethdev_simulate_link_status_interrupt(
1170 test_params->slave_port_ids[i], 1);
1173 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1174 test_params->slave_port_ids[test_params->bonded_slave_count]),
1175 "Failed to add slave to bonded port.\n");
1177 rte_eth_stats_reset(
1178 test_params->slave_port_ids[test_params->bonded_slave_count]);
1180 test_params->bonded_slave_count++;
1182 return remove_slaves_and_stop_bonded_device();
1185 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1186 #define TEST_LSC_WAIT_TIMEOUT_US 500000
1188 int test_lsc_interrupt_count;
1192 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1193 enum rte_eth_event_type type __rte_unused,
1194 void *param __rte_unused,
1195 void *ret_param __rte_unused)
1197 pthread_mutex_lock(&mutex);
1198 test_lsc_interrupt_count++;
1200 pthread_cond_signal(&cvar);
1201 pthread_mutex_unlock(&mutex);
1207 lsc_timeout(int wait_us)
1214 gettimeofday(&tp, NULL);
1216 /* Convert from timeval to timespec */
1217 ts.tv_sec = tp.tv_sec;
1218 ts.tv_nsec = tp.tv_usec * 1000;
1219 ts.tv_nsec += wait_us * 1000;
1220 /* Normalize tv_nsec to [0,999999999L] */
1221 while (ts.tv_nsec > 1000000000L) {
1222 ts.tv_nsec -= 1000000000L;
1226 pthread_mutex_lock(&mutex);
1227 if (test_lsc_interrupt_count < 1)
1228 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1230 pthread_mutex_unlock(&mutex);
1232 if (retval == 0 && test_lsc_interrupt_count < 1)
1239 test_status_interrupt(void)
1242 uint16_t slaves[RTE_MAX_ETHPORTS];
1244 /* initialized bonding device with T slaves */
1245 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1246 BONDING_MODE_ROUND_ROBIN, 1,
1247 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1248 "Failed to initialise bonded device");
1250 test_lsc_interrupt_count = 0;
1252 /* register link status change interrupt callback */
1253 rte_eth_dev_callback_register(test_params->bonded_port_id,
1254 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1255 &test_params->bonded_port_id);
1257 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1258 slaves, RTE_MAX_ETHPORTS);
1260 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1261 "Number of active slaves (%d) is not as expected (%d)",
1262 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1264 /* Bring all 4 slaves link status to down and test that we have received a
1266 virtual_ethdev_simulate_link_status_interrupt(
1267 test_params->slave_port_ids[0], 0);
1268 virtual_ethdev_simulate_link_status_interrupt(
1269 test_params->slave_port_ids[1], 0);
1270 virtual_ethdev_simulate_link_status_interrupt(
1271 test_params->slave_port_ids[2], 0);
1273 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1274 "Received a link status change interrupt unexpectedly");
1276 virtual_ethdev_simulate_link_status_interrupt(
1277 test_params->slave_port_ids[3], 0);
1279 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) == 0,
1280 "timed out waiting for interrupt");
1282 TEST_ASSERT(test_lsc_interrupt_count > 0,
1283 "Did not receive link status change interrupt");
1285 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1286 slaves, RTE_MAX_ETHPORTS);
1288 TEST_ASSERT_EQUAL(slave_count, 0,
1289 "Number of active slaves (%d) is not as expected (%d)",
1292 /* bring one slave port up so link status will change */
1293 test_lsc_interrupt_count = 0;
1295 virtual_ethdev_simulate_link_status_interrupt(
1296 test_params->slave_port_ids[0], 1);
1298 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) == 0,
1299 "timed out waiting for interrupt");
1301 /* test that we have received another lsc interrupt */
1302 TEST_ASSERT(test_lsc_interrupt_count > 0,
1303 "Did not receive link status change interrupt");
1305 /* Verify that calling the same slave lsc interrupt doesn't cause another
1306 * lsc interrupt from bonded device */
1307 test_lsc_interrupt_count = 0;
1309 virtual_ethdev_simulate_link_status_interrupt(
1310 test_params->slave_port_ids[0], 1);
1312 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) != 0,
1313 "received unexpected interrupt");
1315 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1316 "Did not receive link status change interrupt");
1319 /* unregister lsc callback before exiting */
1320 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1321 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1322 &test_params->bonded_port_id);
1324 /* Clean up and remove slaves from bonded device */
1325 return remove_slaves_and_stop_bonded_device();
1329 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1330 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1331 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1333 uint16_t pktlen, generated_burst_size, ether_type;
1337 ether_type = RTE_ETHER_TYPE_IPV4;
1339 ether_type = RTE_ETHER_TYPE_IPV6;
1342 initialize_eth_header(test_params->pkt_eth_hdr,
1343 (struct rte_ether_addr *)src_mac,
1344 (struct rte_ether_addr *)dst_mac_1,
1345 ether_type, vlan, vlan_id);
1347 initialize_eth_header(test_params->pkt_eth_hdr,
1348 (struct rte_ether_addr *)src_mac,
1349 (struct rte_ether_addr *)dst_mac_0,
1350 ether_type, vlan, vlan_id);
1353 if (toggle_udp_port)
1354 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1357 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1362 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1363 dst_addr_1, pktlen);
1365 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1366 dst_addr_0, pktlen);
1368 ip_hdr = test_params->pkt_ipv4_hdr;
1371 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1372 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1375 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1376 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1379 ip_hdr = test_params->pkt_ipv6_hdr;
1382 /* Generate burst of packets to transmit */
1383 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1384 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1385 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1387 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1388 "Failed to generate packet burst");
1390 return generated_burst_size;
1393 /** Round Robin Mode Tests */
1396 test_roundrobin_tx_burst(void)
1399 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1400 struct rte_eth_stats port_stats;
1402 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1403 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1404 "Failed to initialise bonded device");
1406 burst_size = 20 * test_params->bonded_slave_count;
1408 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1409 "Burst size specified is greater than supported.");
1411 /* Generate test bursts of packets to transmit */
1412 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1413 burst_size, "failed to generate test burst");
1415 /* Send burst on bonded port */
1416 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1417 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1420 /* Verify bonded port tx stats */
1421 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1422 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1423 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1424 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1427 /* Verify slave ports tx stats */
1428 for (i = 0; i < test_params->bonded_slave_count; i++) {
1429 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1430 TEST_ASSERT_EQUAL(port_stats.opackets,
1431 (uint64_t)burst_size / test_params->bonded_slave_count,
1432 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1433 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1434 burst_size / test_params->bonded_slave_count);
1437 /* Put all slaves down and try and transmit */
1438 for (i = 0; i < test_params->bonded_slave_count; i++) {
1439 virtual_ethdev_simulate_link_status_interrupt(
1440 test_params->slave_port_ids[i], 0);
1443 /* Send burst on bonded port */
1444 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1445 pkt_burst, burst_size), 0,
1446 "tx burst return unexpected value");
1448 /* Clean up and remove slaves from bonded device */
1449 return remove_slaves_and_stop_bonded_device();
1453 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1457 for (i = 0; i < nb_mbufs; i++) {
1458 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1459 TEST_ASSERT_EQUAL(refcnt, val,
1460 "mbuf ref count (%d)is not the expected value (%d)",
1467 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1471 for (i = 0; i < nb_mbufs; i++)
1472 rte_pktmbuf_free(mbufs[i]);
1475 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1476 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1477 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1478 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1481 test_roundrobin_tx_burst_slave_tx_fail(void)
1483 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1484 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1486 struct rte_eth_stats port_stats;
1488 int i, first_fail_idx, tx_count;
1490 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1491 BONDING_MODE_ROUND_ROBIN, 0,
1492 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1493 "Failed to initialise bonded device");
1495 /* Generate test bursts of packets to transmit */
1496 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1497 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1498 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1499 "Failed to generate test packet burst");
1501 /* Copy references to packets which we expect not to be transmitted */
1502 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1503 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1504 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1505 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1507 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1508 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1509 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1512 /* Set virtual slave to only fail transmission of
1513 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1514 virtual_ethdev_tx_burst_fn_set_success(
1515 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1518 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1519 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1520 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1522 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1523 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1525 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1526 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1527 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1528 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1529 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1531 /* Verify that failed packet are expected failed packets */
1532 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1533 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1534 "expected mbuf (%d) pointer %p not expected pointer %p",
1535 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1538 /* Verify bonded port tx stats */
1539 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1541 TEST_ASSERT_EQUAL(port_stats.opackets,
1542 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1543 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1544 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1545 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1546 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1547 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1549 /* Verify slave ports tx stats */
1550 for (i = 0; i < test_params->bonded_slave_count; i++) {
1551 int slave_expected_tx_count;
1553 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1555 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1556 test_params->bonded_slave_count;
1558 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1559 slave_expected_tx_count = slave_expected_tx_count -
1560 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1562 TEST_ASSERT_EQUAL(port_stats.opackets,
1563 (uint64_t)slave_expected_tx_count,
1564 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1565 test_params->slave_port_ids[i],
1566 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1569 /* Verify that all mbufs have a ref value of zero */
1570 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1571 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1572 "mbufs refcnts not as expected");
1573 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1575 /* Clean up and remove slaves from bonded device */
1576 return remove_slaves_and_stop_bonded_device();
1580 test_roundrobin_rx_burst_on_single_slave(void)
1582 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1583 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1585 struct rte_eth_stats port_stats;
1587 int i, j, burst_size = 25;
1589 /* Initialize bonded device with 4 slaves in round robin mode */
1590 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1591 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1592 "Failed to initialize bonded device with slaves");
1594 /* Generate test bursts of packets to transmit */
1595 TEST_ASSERT_EQUAL(generate_test_burst(
1596 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1597 "burst generation failed");
1599 for (i = 0; i < test_params->bonded_slave_count; i++) {
1600 /* Add rx data to slave */
1601 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1602 &gen_pkt_burst[0], burst_size);
1604 /* Call rx burst on bonded device */
1605 /* Send burst on bonded port */
1606 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1607 test_params->bonded_port_id, 0, rx_pkt_burst,
1608 MAX_PKT_BURST), burst_size,
1609 "round-robin rx burst failed");
1611 /* Verify bonded device rx count */
1612 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1613 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1614 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1615 test_params->bonded_port_id,
1616 (unsigned int)port_stats.ipackets, burst_size);
1620 /* Verify bonded slave devices rx count */
1621 /* Verify slave ports tx stats */
1622 for (j = 0; j < test_params->bonded_slave_count; j++) {
1623 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1626 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1627 "Slave Port (%d) ipackets value (%u) not as expected"
1628 " (%d)", test_params->slave_port_ids[i],
1629 (unsigned int)port_stats.ipackets, burst_size);
1631 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1632 "Slave Port (%d) ipackets value (%u) not as expected"
1633 " (%d)", test_params->slave_port_ids[i],
1634 (unsigned int)port_stats.ipackets, 0);
1637 /* Reset bonded slaves stats */
1638 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1640 /* reset bonded device stats */
1641 rte_eth_stats_reset(test_params->bonded_port_id);
1645 for (i = 0; i < MAX_PKT_BURST; i++) {
1646 rte_pktmbuf_free(rx_pkt_burst[i]);
1650 /* Clean up and remove slaves from bonded device */
1651 return remove_slaves_and_stop_bonded_device();
1654 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1657 test_roundrobin_rx_burst_on_multiple_slaves(void)
1659 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1661 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1662 struct rte_eth_stats port_stats;
1664 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1667 /* Initialize bonded device with 4 slaves in round robin mode */
1668 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1669 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1670 "Failed to initialize bonded device with slaves");
1672 /* Generate test bursts of packets to transmit */
1673 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1674 TEST_ASSERT_EQUAL(generate_test_burst(
1675 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1676 burst_size[i], "burst generation failed");
1679 /* Add rx data to slaves */
1680 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1681 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1682 &gen_pkt_burst[i][0], burst_size[i]);
1685 /* Call rx burst on bonded device */
1686 /* Send burst on bonded port */
1687 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1689 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1690 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1691 burst_size[0] + burst_size[1] + burst_size[2]);
1693 /* Verify bonded device rx count */
1694 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1695 TEST_ASSERT_EQUAL(port_stats.ipackets,
1696 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1697 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1698 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1699 burst_size[0] + burst_size[1] + burst_size[2]);
1701 /* Verify bonded slave devices rx counts */
1702 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1703 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1704 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1705 test_params->slave_port_ids[0],
1706 (unsigned int)port_stats.ipackets, burst_size[0]);
1708 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1709 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1710 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1711 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1714 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1715 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1716 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1717 test_params->slave_port_ids[2],
1718 (unsigned int)port_stats.ipackets, burst_size[2]);
1720 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1721 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1722 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1723 test_params->slave_port_ids[3],
1724 (unsigned int)port_stats.ipackets, 0);
1727 for (i = 0; i < MAX_PKT_BURST; i++) {
1728 rte_pktmbuf_free(rx_pkt_burst[i]);
1731 /* Clean up and remove slaves from bonded device */
1732 return remove_slaves_and_stop_bonded_device();
1736 test_roundrobin_verify_mac_assignment(void)
1738 struct rte_ether_addr read_mac_addr;
1739 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_2;
1743 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
1744 "Failed to get mac address (port %d)",
1745 test_params->slave_port_ids[0]);
1746 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2),
1747 "Failed to get mac address (port %d)",
1748 test_params->slave_port_ids[2]);
1750 /* Initialize bonded device with 4 slaves in round robin mode */
1751 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1752 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1753 "Failed to initialize bonded device with slaves");
1755 /* Verify that all MACs are the same as first slave added to bonded dev */
1756 for (i = 0; i < test_params->bonded_slave_count; i++) {
1757 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1758 "Failed to get mac address (port %d)",
1759 test_params->slave_port_ids[i]);
1760 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1761 sizeof(read_mac_addr)),
1762 "slave port (%d) mac address not set to that of primary port",
1763 test_params->slave_port_ids[i]);
1766 /* change primary and verify that MAC addresses haven't changed */
1767 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1768 test_params->slave_port_ids[2]),
1769 "Failed to set bonded port (%d) primary port to (%d)",
1770 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1772 for (i = 0; i < test_params->bonded_slave_count; i++) {
1773 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1774 "Failed to get mac address (port %d)",
1775 test_params->slave_port_ids[i]);
1776 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1777 sizeof(read_mac_addr)),
1778 "slave port (%d) mac address has changed to that of primary"
1779 " port without stop/start toggle of bonded device",
1780 test_params->slave_port_ids[i]);
1783 /* stop / start bonded device and verify that primary MAC address is
1784 * propagate to bonded device and slaves */
1785 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
1786 "Failed to stop bonded port %u",
1787 test_params->bonded_port_id);
1789 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1790 "Failed to start bonded device");
1792 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1793 "Failed to get mac address (port %d)",
1794 test_params->bonded_port_id);
1795 TEST_ASSERT_SUCCESS(
1796 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1797 "bonded port (%d) mac address not set to that of new primary port",
1798 test_params->slave_port_ids[i]);
1800 for (i = 0; i < test_params->bonded_slave_count; i++) {
1801 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1802 "Failed to get mac address (port %d)",
1803 test_params->slave_port_ids[i]);
1804 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1805 sizeof(read_mac_addr)),
1806 "slave port (%d) mac address not set to that of new primary"
1807 " port", test_params->slave_port_ids[i]);
1810 /* Set explicit MAC address */
1811 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1812 test_params->bonded_port_id,
1813 (struct rte_ether_addr *)bonded_mac),
1814 "Failed to set MAC");
1816 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1817 "Failed to get mac address (port %d)",
1818 test_params->bonded_port_id);
1819 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1820 sizeof(read_mac_addr)),
1821 "bonded port (%d) mac address not set to that of new primary port",
1822 test_params->slave_port_ids[i]);
1824 for (i = 0; i < test_params->bonded_slave_count; i++) {
1825 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1826 "Failed to get mac address (port %d)",
1827 test_params->slave_port_ids[i]);
1828 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1829 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1830 " that of new primary port\n", test_params->slave_port_ids[i]);
1833 /* Clean up and remove slaves from bonded device */
1834 return remove_slaves_and_stop_bonded_device();
1838 test_roundrobin_verify_promiscuous_enable_disable(void)
1840 int i, promiscuous_en;
1843 /* Initialize bonded device with 4 slaves in round robin mode */
1844 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1845 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1846 "Failed to initialize bonded device with slaves");
1848 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
1849 TEST_ASSERT_SUCCESS(ret,
1850 "Failed to enable promiscuous mode for port %d: %s",
1851 test_params->bonded_port_id, rte_strerror(-ret));
1853 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1854 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1855 "Port (%d) promiscuous mode not enabled",
1856 test_params->bonded_port_id);
1858 for (i = 0; i < test_params->bonded_slave_count; i++) {
1859 promiscuous_en = rte_eth_promiscuous_get(
1860 test_params->slave_port_ids[i]);
1861 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1862 "slave port (%d) promiscuous mode not enabled",
1863 test_params->slave_port_ids[i]);
1866 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
1867 TEST_ASSERT_SUCCESS(ret,
1868 "Failed to disable promiscuous mode for port %d: %s",
1869 test_params->bonded_port_id, rte_strerror(-ret));
1871 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1872 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1873 "Port (%d) promiscuous mode not disabled\n",
1874 test_params->bonded_port_id);
1876 for (i = 0; i < test_params->bonded_slave_count; i++) {
1877 promiscuous_en = rte_eth_promiscuous_get(
1878 test_params->slave_port_ids[i]);
1879 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1880 "Port (%d) promiscuous mode not disabled\n",
1881 test_params->slave_port_ids[i]);
1884 /* Clean up and remove slaves from bonded device */
1885 return remove_slaves_and_stop_bonded_device();
1888 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1889 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1892 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1894 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1895 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1896 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1898 struct rte_eth_stats port_stats;
1899 uint16_t slaves[RTE_MAX_ETHPORTS];
1901 int i, burst_size, slave_count;
1903 /* NULL all pointers in array to simplify cleanup */
1904 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1906 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1907 * in round robin mode */
1908 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1909 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1910 "Failed to initialize bonded device with slaves");
1912 /* Verify Current Slaves Count /Active Slave Count is */
1913 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1915 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1916 "Number of slaves (%d) is not as expected (%d).",
1917 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1919 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1920 slaves, RTE_MAX_ETHPORTS);
1921 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1922 "Number of active slaves (%d) is not as expected (%d).",
1923 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1925 /* Set 2 slaves eth_devs link status to down */
1926 virtual_ethdev_simulate_link_status_interrupt(
1927 test_params->slave_port_ids[1], 0);
1928 virtual_ethdev_simulate_link_status_interrupt(
1929 test_params->slave_port_ids[3], 0);
1931 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1932 slaves, RTE_MAX_ETHPORTS);
1933 TEST_ASSERT_EQUAL(slave_count,
1934 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1935 "Number of active slaves (%d) is not as expected (%d).\n",
1936 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1940 /* Verify that pkts are not sent on slaves with link status down:
1942 * 1. Generate test burst of traffic
1943 * 2. Transmit burst on bonded eth_dev
1944 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1945 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1948 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1949 burst_size, "generate_test_burst failed");
1951 rte_eth_stats_reset(test_params->bonded_port_id);
1955 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1956 burst_size), burst_size, "rte_eth_tx_burst failed");
1958 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1959 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1960 "Port (%d) opackets stats (%d) not expected (%d) value",
1961 test_params->bonded_port_id, (int)port_stats.opackets,
1964 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1965 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1966 "Port (%d) opackets stats (%d) not expected (%d) value",
1967 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1969 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1970 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1971 "Port (%d) opackets stats (%d) not expected (%d) value",
1972 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1974 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1975 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1976 "Port (%d) opackets stats (%d) not expected (%d) value",
1977 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1979 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1980 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1981 "Port (%d) opackets stats (%d) not expected (%d) value",
1982 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1984 /* Verify that pkts are not sent on slaves with link status down:
1986 * 1. Generate test bursts of traffic
1987 * 2. Add bursts on to virtual eth_devs
1988 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1989 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1990 * 4. Verify stats for bonded eth_dev
1991 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1993 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1994 TEST_ASSERT_EQUAL(generate_test_burst(
1995 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1996 burst_size, "failed to generate packet burst");
1998 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1999 &gen_pkt_burst[i][0], burst_size);
2002 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2003 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2004 burst_size + burst_size,
2005 "rte_eth_rx_burst failed");
2007 /* Verify bonded device rx count */
2008 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2009 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
2010 "(%d) port_stats.ipackets not as expected\n",
2011 test_params->bonded_port_id);
2014 for (i = 0; i < MAX_PKT_BURST; i++) {
2015 rte_pktmbuf_free(rx_pkt_burst[i]);
2018 /* Clean up and remove slaves from bonded device */
2019 return remove_slaves_and_stop_bonded_device();
2022 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
2024 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
2027 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2030 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2032 struct rte_ether_addr *mac_addr =
2033 (struct rte_ether_addr *)polling_slave_mac;
2034 char slave_name[RTE_ETH_NAME_MAX_LEN];
2038 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2039 /* Generate slave name / MAC address */
2040 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2041 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
2043 /* Create slave devices with no ISR Support */
2044 if (polling_test_slaves[i] == -1) {
2045 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2046 rte_socket_id(), 0);
2047 TEST_ASSERT(polling_test_slaves[i] >= 0,
2048 "Failed to create virtual virtual ethdev %s\n", slave_name);
2050 /* Configure slave */
2051 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2052 "Failed to configure virtual ethdev %s(%d)", slave_name,
2053 polling_test_slaves[i]);
2056 /* Add slave to bonded device */
2057 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2058 polling_test_slaves[i]),
2059 "Failed to add slave %s(%d) to bonded device %d",
2060 slave_name, polling_test_slaves[i],
2061 test_params->bonded_port_id);
2064 /* Initialize bonded device */
2065 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2066 "Failed to configure bonded device %d",
2067 test_params->bonded_port_id);
2070 /* Register link status change interrupt callback */
2071 rte_eth_dev_callback_register(test_params->bonded_port_id,
2072 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2073 &test_params->bonded_port_id);
2075 /* link status change callback for first slave link up */
2076 test_lsc_interrupt_count = 0;
2078 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2080 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2083 /* no link status change callback for second slave link up */
2084 test_lsc_interrupt_count = 0;
2086 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2088 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2090 /* link status change callback for both slave links down */
2091 test_lsc_interrupt_count = 0;
2093 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2094 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2096 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2098 /* Un-Register link status change interrupt callback */
2099 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2100 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2101 &test_params->bonded_port_id);
2104 /* Clean up and remove slaves from bonded device */
2105 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2107 TEST_ASSERT_SUCCESS(
2108 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2109 polling_test_slaves[i]),
2110 "Failed to remove slave %d from bonded port (%d)",
2111 polling_test_slaves[i], test_params->bonded_port_id);
2114 return remove_slaves_and_stop_bonded_device();
2118 /** Active Backup Mode Tests */
2121 test_activebackup_tx_burst(void)
2123 int i, pktlen, primary_port, burst_size;
2124 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2125 struct rte_eth_stats port_stats;
2127 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2128 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2129 "Failed to initialize bonded device with slaves");
2131 initialize_eth_header(test_params->pkt_eth_hdr,
2132 (struct rte_ether_addr *)src_mac,
2133 (struct rte_ether_addr *)dst_mac_0,
2134 RTE_ETHER_TYPE_IPV4, 0, 0);
2135 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2137 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2138 dst_addr_0, pktlen);
2140 burst_size = 20 * test_params->bonded_slave_count;
2142 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2143 "Burst size specified is greater than supported.");
2145 /* Generate a burst of packets to transmit */
2146 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2147 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2148 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2149 burst_size, "failed to generate burst correctly");
2151 /* Send burst on bonded port */
2152 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2153 burst_size), burst_size, "tx burst failed");
2155 /* Verify bonded port tx stats */
2156 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2157 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2158 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2159 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2162 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2164 /* Verify slave ports tx stats */
2165 for (i = 0; i < test_params->bonded_slave_count; i++) {
2166 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2167 if (test_params->slave_port_ids[i] == primary_port) {
2168 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2169 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2170 test_params->bonded_port_id,
2171 (unsigned int)port_stats.opackets,
2172 burst_size / test_params->bonded_slave_count);
2174 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2175 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2176 test_params->bonded_port_id,
2177 (unsigned int)port_stats.opackets, 0);
2181 /* Put all slaves down and try and transmit */
2182 for (i = 0; i < test_params->bonded_slave_count; i++) {
2183 virtual_ethdev_simulate_link_status_interrupt(
2184 test_params->slave_port_ids[i], 0);
2187 /* Send burst on bonded port */
2188 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2189 pkts_burst, burst_size), 0, "Sending empty burst failed");
2191 /* Clean up and remove slaves from bonded device */
2192 return remove_slaves_and_stop_bonded_device();
2195 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2198 test_activebackup_rx_burst(void)
2200 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2201 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2203 struct rte_eth_stats port_stats;
2207 int i, j, burst_size = 17;
2209 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2210 BONDING_MODE_ACTIVE_BACKUP, 0,
2211 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2212 "Failed to initialize bonded device with slaves");
2214 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2215 TEST_ASSERT(primary_port >= 0,
2216 "failed to get primary slave for bonded port (%d)",
2217 test_params->bonded_port_id);
2219 for (i = 0; i < test_params->bonded_slave_count; i++) {
2220 /* Generate test bursts of packets to transmit */
2221 TEST_ASSERT_EQUAL(generate_test_burst(
2222 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2223 burst_size, "burst generation failed");
2225 /* Add rx data to slave */
2226 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2227 &gen_pkt_burst[0], burst_size);
2229 /* Call rx burst on bonded device */
2230 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2231 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2232 "rte_eth_rx_burst failed");
2234 if (test_params->slave_port_ids[i] == primary_port) {
2235 /* Verify bonded device rx count */
2236 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2237 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2238 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2239 test_params->bonded_port_id,
2240 (unsigned int)port_stats.ipackets, burst_size);
2242 /* Verify bonded slave devices rx count */
2243 for (j = 0; j < test_params->bonded_slave_count; j++) {
2244 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2246 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2247 "Slave Port (%d) ipackets value (%u) not as "
2248 "expected (%d)", test_params->slave_port_ids[i],
2249 (unsigned int)port_stats.ipackets, burst_size);
2251 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2252 "Slave Port (%d) ipackets value (%u) not as "
2253 "expected (%d)\n", test_params->slave_port_ids[i],
2254 (unsigned int)port_stats.ipackets, 0);
2258 for (j = 0; j < test_params->bonded_slave_count; j++) {
2259 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2260 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2261 "Slave Port (%d) ipackets value (%u) not as expected "
2262 "(%d)", test_params->slave_port_ids[i],
2263 (unsigned int)port_stats.ipackets, 0);
2268 for (i = 0; i < MAX_PKT_BURST; i++) {
2269 if (rx_pkt_burst[i] != NULL) {
2270 rte_pktmbuf_free(rx_pkt_burst[i]);
2271 rx_pkt_burst[i] = NULL;
2275 /* reset bonded device stats */
2276 rte_eth_stats_reset(test_params->bonded_port_id);
2279 /* Clean up and remove slaves from bonded device */
2280 return remove_slaves_and_stop_bonded_device();
2284 test_activebackup_verify_promiscuous_enable_disable(void)
2286 int i, primary_port, promiscuous_en;
2289 /* Initialize bonded device with 4 slaves in round robin mode */
2290 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2291 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2292 "Failed to initialize bonded device with slaves");
2294 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2295 TEST_ASSERT(primary_port >= 0,
2296 "failed to get primary slave for bonded port (%d)",
2297 test_params->bonded_port_id);
2299 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
2300 TEST_ASSERT_SUCCESS(ret,
2301 "Failed to enable promiscuous mode for port %d: %s",
2302 test_params->bonded_port_id, rte_strerror(-ret));
2304 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2305 "Port (%d) promiscuous mode not enabled",
2306 test_params->bonded_port_id);
2308 for (i = 0; i < test_params->bonded_slave_count; i++) {
2309 promiscuous_en = rte_eth_promiscuous_get(
2310 test_params->slave_port_ids[i]);
2311 if (primary_port == test_params->slave_port_ids[i]) {
2312 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2313 "slave port (%d) promiscuous mode not enabled",
2314 test_params->slave_port_ids[i]);
2316 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2317 "slave port (%d) promiscuous mode enabled",
2318 test_params->slave_port_ids[i]);
2323 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
2324 TEST_ASSERT_SUCCESS(ret,
2325 "Failed to disable promiscuous mode for port %d: %s",
2326 test_params->bonded_port_id, rte_strerror(-ret));
2328 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2329 "Port (%d) promiscuous mode not disabled\n",
2330 test_params->bonded_port_id);
2332 for (i = 0; i < test_params->bonded_slave_count; i++) {
2333 promiscuous_en = rte_eth_promiscuous_get(
2334 test_params->slave_port_ids[i]);
2335 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2336 "slave port (%d) promiscuous mode not disabled\n",
2337 test_params->slave_port_ids[i]);
2340 /* Clean up and remove slaves from bonded device */
2341 return remove_slaves_and_stop_bonded_device();
2345 test_activebackup_verify_mac_assignment(void)
2347 struct rte_ether_addr read_mac_addr;
2348 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
2350 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
2351 "Failed to get mac address (port %d)",
2352 test_params->slave_port_ids[0]);
2353 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
2354 "Failed to get mac address (port %d)",
2355 test_params->slave_port_ids[1]);
2357 /* Initialize bonded device with 2 slaves in active backup mode */
2358 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2359 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2360 "Failed to initialize bonded device with slaves");
2362 /* Verify that bonded MACs is that of first slave and that the other slave
2363 * MAC hasn't been changed */
2364 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2365 "Failed to get mac address (port %d)",
2366 test_params->bonded_port_id);
2367 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2368 sizeof(read_mac_addr)),
2369 "bonded port (%d) mac address not set to that of primary port",
2370 test_params->bonded_port_id);
2372 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2373 "Failed to get mac address (port %d)",
2374 test_params->slave_port_ids[0]);
2375 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2376 sizeof(read_mac_addr)),
2377 "slave port (%d) mac address not set to that of primary port",
2378 test_params->slave_port_ids[0]);
2380 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2381 "Failed to get mac address (port %d)",
2382 test_params->slave_port_ids[1]);
2383 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2384 sizeof(read_mac_addr)),
2385 "slave port (%d) mac address not as expected",
2386 test_params->slave_port_ids[1]);
2388 /* change primary and verify that MAC addresses haven't changed */
2389 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2390 test_params->slave_port_ids[1]), 0,
2391 "Failed to set bonded port (%d) primary port to (%d)",
2392 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2394 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2395 "Failed to get mac address (port %d)",
2396 test_params->bonded_port_id);
2397 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2398 sizeof(read_mac_addr)),
2399 "bonded port (%d) mac address not set to that of primary port",
2400 test_params->bonded_port_id);
2402 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2403 "Failed to get mac address (port %d)",
2404 test_params->slave_port_ids[0]);
2405 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2406 sizeof(read_mac_addr)),
2407 "slave port (%d) mac address not set to that of primary port",
2408 test_params->slave_port_ids[0]);
2410 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2411 "Failed to get mac address (port %d)",
2412 test_params->slave_port_ids[1]);
2413 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2414 sizeof(read_mac_addr)),
2415 "slave port (%d) mac address not as expected",
2416 test_params->slave_port_ids[1]);
2418 /* stop / start bonded device and verify that primary MAC address is
2419 * propagated to bonded device and slaves */
2421 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
2422 "Failed to stop bonded port %u",
2423 test_params->bonded_port_id);
2425 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2426 "Failed to start device");
2428 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2429 "Failed to get mac address (port %d)",
2430 test_params->bonded_port_id);
2431 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2432 sizeof(read_mac_addr)),
2433 "bonded port (%d) mac address not set to that of primary port",
2434 test_params->bonded_port_id);
2436 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2437 "Failed to get mac address (port %d)",
2438 test_params->slave_port_ids[0]);
2439 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2440 sizeof(read_mac_addr)),
2441 "slave port (%d) mac address not as expected",
2442 test_params->slave_port_ids[0]);
2444 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2445 "Failed to get mac address (port %d)",
2446 test_params->slave_port_ids[1]);
2447 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2448 sizeof(read_mac_addr)),
2449 "slave port (%d) mac address not set to that of primary port",
2450 test_params->slave_port_ids[1]);
2452 /* Set explicit MAC address */
2453 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2454 test_params->bonded_port_id,
2455 (struct rte_ether_addr *)bonded_mac),
2456 "failed to set MAC address");
2458 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2459 "Failed to get mac address (port %d)",
2460 test_params->bonded_port_id);
2461 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2462 sizeof(read_mac_addr)),
2463 "bonded port (%d) mac address not set to that of bonded port",
2464 test_params->bonded_port_id);
2466 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2467 "Failed to get mac address (port %d)",
2468 test_params->slave_port_ids[0]);
2469 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2470 sizeof(read_mac_addr)),
2471 "slave port (%d) mac address not as expected",
2472 test_params->slave_port_ids[0]);
2474 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2475 "Failed to get mac address (port %d)",
2476 test_params->slave_port_ids[1]);
2477 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2478 sizeof(read_mac_addr)),
2479 "slave port (%d) mac address not set to that of bonded port",
2480 test_params->slave_port_ids[1]);
2482 /* Clean up and remove slaves from bonded device */
2483 return remove_slaves_and_stop_bonded_device();
2487 test_activebackup_verify_slave_link_status_change_failover(void)
2489 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2490 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2491 struct rte_eth_stats port_stats;
2493 uint16_t slaves[RTE_MAX_ETHPORTS];
2495 int i, burst_size, slave_count, primary_port;
2499 memset(pkt_burst, 0, sizeof(pkt_burst));
2501 /* Generate packet burst for testing */
2502 TEST_ASSERT_EQUAL(generate_test_burst(
2503 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2504 "generate_test_burst failed");
2506 /* Initialize bonded device with 4 slaves in round robin mode */
2507 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2508 BONDING_MODE_ACTIVE_BACKUP, 0,
2509 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2510 "Failed to initialize bonded device with slaves");
2512 /* Verify Current Slaves Count /Active Slave Count is */
2513 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2515 TEST_ASSERT_EQUAL(slave_count, 4,
2516 "Number of slaves (%d) is not as expected (%d).",
2519 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2520 slaves, RTE_MAX_ETHPORTS);
2521 TEST_ASSERT_EQUAL(slave_count, 4,
2522 "Number of active slaves (%d) is not as expected (%d).",
2525 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2526 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2527 "Primary port not as expected");
2529 /* Bring 2 slaves down and verify active slave count */
2530 virtual_ethdev_simulate_link_status_interrupt(
2531 test_params->slave_port_ids[1], 0);
2532 virtual_ethdev_simulate_link_status_interrupt(
2533 test_params->slave_port_ids[3], 0);
2535 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2536 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2537 "Number of active slaves (%d) is not as expected (%d).",
2540 virtual_ethdev_simulate_link_status_interrupt(
2541 test_params->slave_port_ids[1], 1);
2542 virtual_ethdev_simulate_link_status_interrupt(
2543 test_params->slave_port_ids[3], 1);
2546 /* Bring primary port down, verify that active slave count is 3 and primary
2548 virtual_ethdev_simulate_link_status_interrupt(
2549 test_params->slave_port_ids[0], 0);
2551 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2552 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2554 "Number of active slaves (%d) is not as expected (%d).",
2557 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2558 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2559 "Primary port not as expected");
2561 /* Verify that pkts are sent on new primary slave */
2563 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2564 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2565 burst_size), burst_size, "rte_eth_tx_burst failed");
2567 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2568 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2569 "(%d) port_stats.opackets not as expected",
2570 test_params->slave_port_ids[2]);
2572 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2573 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2574 "(%d) port_stats.opackets not as expected\n",
2575 test_params->slave_port_ids[0]);
2577 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2578 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2579 "(%d) port_stats.opackets not as expected\n",
2580 test_params->slave_port_ids[1]);
2582 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2583 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2584 "(%d) port_stats.opackets not as expected\n",
2585 test_params->slave_port_ids[3]);
2587 /* Generate packet burst for testing */
2589 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2590 TEST_ASSERT_EQUAL(generate_test_burst(
2591 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2592 "generate_test_burst failed");
2594 virtual_ethdev_add_mbufs_to_rx_queue(
2595 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2598 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2599 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2600 burst_size, "rte_eth_rx_burst\n");
2602 /* Verify bonded device rx count */
2603 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2604 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2605 "(%d) port_stats.ipackets not as expected",
2606 test_params->bonded_port_id);
2608 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2609 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2610 "(%d) port_stats.opackets not as expected",
2611 test_params->slave_port_ids[2]);
2613 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2614 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2615 "(%d) port_stats.opackets not as expected",
2616 test_params->slave_port_ids[0]);
2618 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2619 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2620 "(%d) port_stats.opackets not as expected",
2621 test_params->slave_port_ids[1]);
2623 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2624 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2625 "(%d) port_stats.opackets not as expected",
2626 test_params->slave_port_ids[3]);
2628 /* Clean up and remove slaves from bonded device */
2629 return remove_slaves_and_stop_bonded_device();
2632 /** Balance Mode Tests */
2635 test_balance_xmit_policy_configuration(void)
2637 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2638 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2639 "Failed to initialize_bonded_device_with_slaves.");
2641 /* Invalid port id */
2642 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2643 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2644 "Expected call to failed as invalid port specified.");
2646 /* Set xmit policy on non bonded device */
2647 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2648 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2649 "Expected call to failed as invalid port specified.");
2652 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2653 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2654 "Failed to set balance xmit policy.");
2656 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2657 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2660 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2661 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2662 "Failed to set balance xmit policy.");
2664 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2665 BALANCE_XMIT_POLICY_LAYER23,
2666 "balance xmit policy not as expected.");
2669 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2670 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2671 "Failed to set balance xmit policy.");
2673 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2674 BALANCE_XMIT_POLICY_LAYER34,
2675 "balance xmit policy not as expected.");
2677 /* Invalid port id */
2678 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2679 "Expected call to failed as invalid port specified.");
2681 /* Clean up and remove slaves from bonded device */
2682 return remove_slaves_and_stop_bonded_device();
2685 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2688 test_balance_l2_tx_burst(void)
2690 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2691 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2695 struct rte_eth_stats port_stats;
2697 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2698 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2699 "Failed to initialize_bonded_device_with_slaves.");
2701 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2702 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2703 "Failed to set balance xmit policy.");
2705 initialize_eth_header(test_params->pkt_eth_hdr,
2706 (struct rte_ether_addr *)src_mac,
2707 (struct rte_ether_addr *)dst_mac_0,
2708 RTE_ETHER_TYPE_IPV4, 0, 0);
2709 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2711 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2712 dst_addr_0, pktlen);
2714 /* Generate a burst 1 of packets to transmit */
2715 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2716 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2717 test_params->pkt_udp_hdr, burst_size[0],
2718 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2719 "failed to generate packet burst");
2721 initialize_eth_header(test_params->pkt_eth_hdr,
2722 (struct rte_ether_addr *)src_mac,
2723 (struct rte_ether_addr *)dst_mac_1,
2724 RTE_ETHER_TYPE_IPV4, 0, 0);
2726 /* Generate a burst 2 of packets to transmit */
2727 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2728 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2729 test_params->pkt_udp_hdr, burst_size[1],
2730 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2731 "failed to generate packet burst");
2733 /* Send burst 1 on bonded port */
2734 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2735 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2736 &pkts_burst[i][0], burst_size[i]),
2737 burst_size[i], "Failed to transmit packet burst");
2740 /* Verify bonded port tx stats */
2741 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2742 TEST_ASSERT_EQUAL(port_stats.opackets,
2743 (uint64_t)(burst_size[0] + burst_size[1]),
2744 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2745 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2746 burst_size[0] + burst_size[1]);
2749 /* Verify slave ports tx stats */
2750 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2751 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2752 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2753 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2756 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2757 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2758 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2759 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2762 /* Put all slaves down and try and transmit */
2763 for (i = 0; i < test_params->bonded_slave_count; i++) {
2765 virtual_ethdev_simulate_link_status_interrupt(
2766 test_params->slave_port_ids[i], 0);
2769 /* Send burst on bonded port */
2770 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2771 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2772 0, "Expected zero packet");
2774 /* Clean up and remove slaves from bonded device */
2775 return remove_slaves_and_stop_bonded_device();
2779 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2780 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2782 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2784 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2785 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2787 struct rte_eth_stats port_stats;
2789 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2790 BONDING_MODE_BALANCE, 0, 2, 1),
2791 "Failed to initialize_bonded_device_with_slaves.");
2793 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2794 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2795 "Failed to set balance xmit policy.");
2800 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2801 "Burst size specified is greater than supported.");
2803 /* Generate test bursts of packets to transmit */
2804 TEST_ASSERT_EQUAL(generate_test_burst(
2805 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2806 burst_size_1, "failed to generate packet burst");
2808 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2809 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2810 "failed to generate packet burst");
2812 /* Send burst 1 on bonded port */
2813 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2815 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2817 /* Send burst 2 on bonded port */
2818 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2820 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
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");
2855 /* Clean up and remove slaves from bonded device */
2856 return remove_slaves_and_stop_bonded_device();
2860 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2862 return balance_l23_tx_burst(0, 1, 0, 1);
2866 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2868 return balance_l23_tx_burst(1, 1, 0, 1);
2872 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2874 return balance_l23_tx_burst(0, 0, 0, 1);
2878 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2880 return balance_l23_tx_burst(1, 0, 0, 1);
2884 test_balance_l23_tx_burst_toggle_mac_addr(void)
2886 return balance_l23_tx_burst(0, 0, 1, 0);
2890 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2891 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2892 uint8_t toggle_udp_port)
2894 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2896 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2897 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2899 struct rte_eth_stats port_stats;
2901 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2902 BONDING_MODE_BALANCE, 0, 2, 1),
2903 "Failed to initialize_bonded_device_with_slaves.");
2905 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2906 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2907 "Failed to set balance xmit policy.");
2912 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2913 "Burst size specified is greater than supported.");
2915 /* Generate test bursts of packets to transmit */
2916 TEST_ASSERT_EQUAL(generate_test_burst(
2917 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2918 burst_size_1, "failed to generate burst");
2920 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2921 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2922 toggle_udp_port), burst_size_2, "failed to generate burst");
2924 /* Send burst 1 on bonded port */
2925 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2927 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2929 /* Send burst 2 on bonded port */
2930 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2932 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2935 /* Verify bonded port tx stats */
2936 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2937 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2938 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2939 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2942 /* Verify slave ports tx stats */
2943 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2944 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2945 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2946 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2949 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2950 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2951 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2952 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2955 /* Put all slaves down and try and transmit */
2956 for (i = 0; i < test_params->bonded_slave_count; i++) {
2958 virtual_ethdev_simulate_link_status_interrupt(
2959 test_params->slave_port_ids[i], 0);
2962 /* Send burst on bonded port */
2963 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2964 test_params->bonded_port_id, 0, pkts_burst_1,
2965 burst_size_1), 0, "Expected zero packet");
2967 /* Clean up and remove slaves from bonded device */
2968 return remove_slaves_and_stop_bonded_device();
2972 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2974 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2978 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2980 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2984 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2986 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2990 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2992 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2996 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2998 return balance_l34_tx_burst(1, 0, 0, 1, 0);
3002 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
3004 return balance_l34_tx_burst(0, 0, 0, 0, 1);
3007 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
3008 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
3009 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
3010 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
3011 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
3014 test_balance_tx_burst_slave_tx_fail(void)
3016 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
3017 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
3019 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
3021 struct rte_eth_stats port_stats;
3023 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
3025 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3026 BONDING_MODE_BALANCE, 0,
3027 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3028 "Failed to initialise bonded device");
3030 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3031 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3032 "Failed to set balance xmit policy.");
3035 /* Generate test bursts for transmission */
3036 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
3037 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
3038 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
3039 "Failed to generate test packet burst 1");
3041 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3042 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
3044 /* copy mbuf references for expected transmission failures */
3045 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
3046 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
3048 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
3049 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
3050 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3051 "Failed to generate test packet burst 2");
3054 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3055 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3056 virtual_ethdev_tx_burst_fn_set_success(
3057 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3060 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3061 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3062 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3065 /* Transmit burst 1 */
3066 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3067 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3069 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3070 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3071 "Transmitted (%d) packets, expected to transmit (%d) packets",
3072 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3073 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3075 /* Verify that failed packet are expected failed packets */
3076 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3077 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3078 "expected mbuf (%d) pointer %p not expected pointer %p",
3079 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3082 /* Transmit burst 2 */
3083 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3084 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3086 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3087 "Transmitted (%d) packets, expected to transmit (%d) packets",
3088 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3091 /* Verify bonded port tx stats */
3092 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3094 TEST_ASSERT_EQUAL(port_stats.opackets,
3095 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3096 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3097 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3098 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3099 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3100 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3101 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3102 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3104 /* Verify slave ports tx stats */
3106 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3108 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3109 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3110 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3111 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3112 test_params->slave_port_ids[0],
3113 (unsigned int)port_stats.opackets,
3114 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3115 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3120 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3122 TEST_ASSERT_EQUAL(port_stats.opackets,
3123 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3124 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3125 test_params->slave_port_ids[1],
3126 (unsigned int)port_stats.opackets,
3127 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3129 /* Verify that all mbufs have a ref value of zero */
3130 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3131 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3132 "mbufs refcnts not as expected");
3134 free_mbufs(&pkts_burst_1[tx_count_1],
3135 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3137 /* Clean up and remove slaves from bonded device */
3138 return remove_slaves_and_stop_bonded_device();
3141 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3144 test_balance_rx_burst(void)
3146 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3148 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3149 struct rte_eth_stats port_stats;
3151 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3154 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3156 /* Initialize bonded device with 4 slaves in round robin mode */
3157 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3158 BONDING_MODE_BALANCE, 0, 3, 1),
3159 "Failed to initialise bonded device");
3161 /* Generate test bursts of packets to transmit */
3162 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3163 TEST_ASSERT_EQUAL(generate_test_burst(
3164 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3165 0, 0), burst_size[i],
3166 "failed to generate packet burst");
3169 /* Add rx data to slaves */
3170 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3171 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3172 &gen_pkt_burst[i][0], burst_size[i]);
3175 /* Call rx burst on bonded device */
3176 /* Send burst on bonded port */
3177 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3178 rx_pkt_burst, MAX_PKT_BURST),
3179 burst_size[0] + burst_size[1] + burst_size[2],
3180 "balance rx burst failed\n");
3182 /* Verify bonded device rx count */
3183 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3184 TEST_ASSERT_EQUAL(port_stats.ipackets,
3185 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3186 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3187 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3188 burst_size[0] + burst_size[1] + burst_size[2]);
3191 /* Verify bonded slave devices rx counts */
3192 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3193 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3194 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3195 test_params->slave_port_ids[0],
3196 (unsigned int)port_stats.ipackets, burst_size[0]);
3198 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3199 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3200 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3201 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3204 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3205 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3206 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3207 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3210 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3211 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3212 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3213 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3217 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3218 for (j = 0; j < MAX_PKT_BURST; j++) {
3219 if (gen_pkt_burst[i][j] != NULL) {
3220 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3221 gen_pkt_burst[i][j] = NULL;
3226 /* Clean up and remove slaves from bonded device */
3227 return remove_slaves_and_stop_bonded_device();
3231 test_balance_verify_promiscuous_enable_disable(void)
3236 /* Initialize bonded device with 4 slaves in round robin mode */
3237 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3238 BONDING_MODE_BALANCE, 0, 4, 1),
3239 "Failed to initialise bonded device");
3241 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3242 TEST_ASSERT_SUCCESS(ret,
3243 "Failed to enable promiscuous mode for port %d: %s",
3244 test_params->bonded_port_id, rte_strerror(-ret));
3246 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3247 "Port (%d) promiscuous mode not enabled",
3248 test_params->bonded_port_id);
3250 for (i = 0; i < test_params->bonded_slave_count; i++) {
3251 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3252 test_params->slave_port_ids[i]), 1,
3253 "Port (%d) promiscuous mode not enabled",
3254 test_params->slave_port_ids[i]);
3257 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3258 TEST_ASSERT_SUCCESS(ret,
3259 "Failed to disable promiscuous mode for port %d: %s",
3260 test_params->bonded_port_id, rte_strerror(-ret));
3262 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3263 "Port (%d) promiscuous mode not disabled",
3264 test_params->bonded_port_id);
3266 for (i = 0; i < test_params->bonded_slave_count; i++) {
3267 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3268 test_params->slave_port_ids[i]), 0,
3269 "Port (%d) promiscuous mode not disabled",
3270 test_params->slave_port_ids[i]);
3273 /* Clean up and remove slaves from bonded device */
3274 return remove_slaves_and_stop_bonded_device();
3278 test_balance_verify_mac_assignment(void)
3280 struct rte_ether_addr read_mac_addr;
3281 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3283 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3284 "Failed to get mac address (port %d)",
3285 test_params->slave_port_ids[0]);
3286 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
3287 "Failed to get mac address (port %d)",
3288 test_params->slave_port_ids[1]);
3290 /* Initialize bonded device with 2 slaves in active backup mode */
3291 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3292 BONDING_MODE_BALANCE, 0, 2, 1),
3293 "Failed to initialise bonded device");
3295 /* Verify that bonded MACs is that of first slave and that the other slave
3296 * MAC hasn't been changed */
3297 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3298 "Failed to get mac address (port %d)",
3299 test_params->bonded_port_id);
3300 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3301 sizeof(read_mac_addr)),
3302 "bonded port (%d) mac address not set to that of primary port",
3303 test_params->bonded_port_id);
3305 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3306 "Failed to get mac address (port %d)",
3307 test_params->slave_port_ids[0]);
3308 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3309 sizeof(read_mac_addr)),
3310 "slave port (%d) mac address not set to that of primary port",
3311 test_params->slave_port_ids[0]);
3313 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3314 "Failed to get mac address (port %d)",
3315 test_params->slave_port_ids[1]);
3316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3317 sizeof(read_mac_addr)),
3318 "slave port (%d) mac address not set to that of primary port",
3319 test_params->slave_port_ids[1]);
3321 /* change primary and verify that MAC addresses haven't changed */
3322 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3323 test_params->slave_port_ids[1]),
3324 "Failed to set bonded port (%d) primary port to (%d)\n",
3325 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3327 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3328 "Failed to get mac address (port %d)",
3329 test_params->bonded_port_id);
3330 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3331 sizeof(read_mac_addr)),
3332 "bonded port (%d) mac address not set to that of primary port",
3333 test_params->bonded_port_id);
3335 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3336 "Failed to get mac address (port %d)",
3337 test_params->slave_port_ids[0]);
3338 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3339 sizeof(read_mac_addr)),
3340 "slave port (%d) mac address not set to that of primary port",
3341 test_params->slave_port_ids[0]);
3343 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3344 "Failed to get mac address (port %d)",
3345 test_params->slave_port_ids[1]);
3346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3347 sizeof(read_mac_addr)),
3348 "slave port (%d) mac address not set to that of primary port",
3349 test_params->slave_port_ids[1]);
3351 /* stop / start bonded device and verify that primary MAC address is
3352 * propagated to bonded device and slaves */
3354 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
3355 "Failed to stop bonded port %u",
3356 test_params->bonded_port_id);
3358 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3359 "Failed to start bonded device");
3361 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3362 "Failed to get mac address (port %d)",
3363 test_params->bonded_port_id);
3364 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3365 sizeof(read_mac_addr)),
3366 "bonded port (%d) mac address not set to that of primary port",
3367 test_params->bonded_port_id);
3369 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3370 "Failed to get mac address (port %d)",
3371 test_params->slave_port_ids[0]);
3372 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3373 sizeof(read_mac_addr)),
3374 "slave port (%d) mac address not set to that of primary port",
3375 test_params->slave_port_ids[0]);
3377 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3378 "Failed to get mac address (port %d)",
3379 test_params->slave_port_ids[1]);
3380 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3381 sizeof(read_mac_addr)),
3382 "slave port (%d) mac address not set to that of primary port",
3383 test_params->slave_port_ids[1]);
3385 /* Set explicit MAC address */
3386 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3387 test_params->bonded_port_id,
3388 (struct rte_ether_addr *)bonded_mac),
3389 "failed to set MAC");
3391 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3392 "Failed to get mac address (port %d)",
3393 test_params->bonded_port_id);
3394 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3395 sizeof(read_mac_addr)),
3396 "bonded port (%d) mac address not set to that of bonded port",
3397 test_params->bonded_port_id);
3399 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3400 "Failed to get mac address (port %d)",
3401 test_params->slave_port_ids[0]);
3402 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3403 sizeof(read_mac_addr)),
3404 "slave port (%d) mac address not as expected\n",
3405 test_params->slave_port_ids[0]);
3407 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3408 "Failed to get mac address (port %d)",
3409 test_params->slave_port_ids[1]);
3410 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3411 sizeof(read_mac_addr)),
3412 "slave port (%d) mac address not set to that of bonded port",
3413 test_params->slave_port_ids[1]);
3415 /* Clean up and remove slaves from bonded device */
3416 return remove_slaves_and_stop_bonded_device();
3419 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3422 test_balance_verify_slave_link_status_change_behaviour(void)
3424 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3425 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3426 struct rte_eth_stats port_stats;
3428 uint16_t slaves[RTE_MAX_ETHPORTS];
3430 int i, burst_size, slave_count;
3432 memset(pkt_burst, 0, sizeof(pkt_burst));
3434 /* Initialize bonded device with 4 slaves in round robin mode */
3435 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3436 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3437 "Failed to initialise bonded device");
3439 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3440 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3441 "Failed to set balance xmit policy.");
3444 /* Verify Current Slaves Count /Active Slave Count is */
3445 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3447 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3448 "Number of slaves (%d) is not as expected (%d).",
3449 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3451 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3452 slaves, RTE_MAX_ETHPORTS);
3453 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3454 "Number of active slaves (%d) is not as expected (%d).",
3455 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3457 /* Set 2 slaves link status to down */
3458 virtual_ethdev_simulate_link_status_interrupt(
3459 test_params->slave_port_ids[1], 0);
3460 virtual_ethdev_simulate_link_status_interrupt(
3461 test_params->slave_port_ids[3], 0);
3463 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3464 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3465 "Number of active slaves (%d) is not as expected (%d).",
3468 /* Send to sets of packet burst and verify that they are balanced across
3472 TEST_ASSERT_EQUAL(generate_test_burst(
3473 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3474 "generate_test_burst failed");
3476 TEST_ASSERT_EQUAL(generate_test_burst(
3477 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3478 "generate_test_burst failed");
3480 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3481 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3482 burst_size, "rte_eth_tx_burst failed");
3484 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3485 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3486 burst_size, "rte_eth_tx_burst failed");
3489 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3490 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3491 "(%d) port_stats.opackets (%d) not as expected (%d).",
3492 test_params->bonded_port_id, (int)port_stats.opackets,
3493 burst_size + burst_size);
3495 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3496 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3497 "(%d) port_stats.opackets (%d) not as expected (%d).",
3498 test_params->slave_port_ids[0], (int)port_stats.opackets,
3501 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3502 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3503 "(%d) port_stats.opackets (%d) not as expected (%d).",
3504 test_params->slave_port_ids[2], (int)port_stats.opackets,
3507 /* verify that all packets get send on primary slave when no other slaves
3509 virtual_ethdev_simulate_link_status_interrupt(
3510 test_params->slave_port_ids[2], 0);
3512 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3513 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3514 "Number of active slaves (%d) is not as expected (%d).",
3517 TEST_ASSERT_EQUAL(generate_test_burst(
3518 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3519 "generate_test_burst failed");
3521 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3522 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3523 burst_size, "rte_eth_tx_burst failed");
3525 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3526 TEST_ASSERT_EQUAL(port_stats.opackets,
3527 (uint64_t)(burst_size + burst_size + burst_size),
3528 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3529 test_params->bonded_port_id, (int)port_stats.opackets,
3530 burst_size + burst_size + burst_size);
3532 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3533 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3534 "(%d) port_stats.opackets (%d) not as expected (%d).",
3535 test_params->slave_port_ids[0], (int)port_stats.opackets,
3536 burst_size + burst_size);
3538 virtual_ethdev_simulate_link_status_interrupt(
3539 test_params->slave_port_ids[0], 0);
3540 virtual_ethdev_simulate_link_status_interrupt(
3541 test_params->slave_port_ids[1], 1);
3542 virtual_ethdev_simulate_link_status_interrupt(
3543 test_params->slave_port_ids[2], 1);
3544 virtual_ethdev_simulate_link_status_interrupt(
3545 test_params->slave_port_ids[3], 1);
3547 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3548 TEST_ASSERT_EQUAL(generate_test_burst(
3549 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3550 "Failed to generate packet burst");
3552 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3553 &pkt_burst[i][0], burst_size);
3556 /* Verify that pkts are not received on slaves with link status down */
3558 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3561 /* Verify bonded device rx count */
3562 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3563 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3564 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3565 test_params->bonded_port_id, (int)port_stats.ipackets,
3568 /* Clean up and remove slaves from bonded device */
3569 return remove_slaves_and_stop_bonded_device();
3573 test_broadcast_tx_burst(void)
3575 int i, pktlen, burst_size;
3576 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3578 struct rte_eth_stats port_stats;
3580 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3581 BONDING_MODE_BROADCAST, 0, 2, 1),
3582 "Failed to initialise bonded device");
3584 initialize_eth_header(test_params->pkt_eth_hdr,
3585 (struct rte_ether_addr *)src_mac,
3586 (struct rte_ether_addr *)dst_mac_0,
3587 RTE_ETHER_TYPE_IPV4, 0, 0);
3589 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3591 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3592 dst_addr_0, pktlen);
3594 burst_size = 20 * test_params->bonded_slave_count;
3596 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3597 "Burst size specified is greater than supported.");
3599 /* Generate a burst of packets to transmit */
3600 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3601 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3602 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3603 1), burst_size, "Failed to generate packet burst");
3605 /* Send burst on bonded port */
3606 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3607 pkts_burst, burst_size), burst_size,
3608 "Bonded Port (%d) rx burst failed, packets transmitted value "
3609 "not as expected (%d)",
3610 test_params->bonded_port_id, burst_size);
3612 /* Verify bonded port tx stats */
3613 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3614 TEST_ASSERT_EQUAL(port_stats.opackets,
3615 (uint64_t)burst_size * test_params->bonded_slave_count,
3616 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3617 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3620 /* Verify slave ports tx stats */
3621 for (i = 0; i < test_params->bonded_slave_count; i++) {
3622 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3623 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3624 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3625 test_params->bonded_port_id,
3626 (unsigned int)port_stats.opackets, burst_size);
3629 /* Put all slaves down and try and transmit */
3630 for (i = 0; i < test_params->bonded_slave_count; i++) {
3632 virtual_ethdev_simulate_link_status_interrupt(
3633 test_params->slave_port_ids[i], 0);
3636 /* Send burst on bonded port */
3637 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3638 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3639 "transmitted an unexpected number of packets");
3641 /* Clean up and remove slaves from bonded device */
3642 return remove_slaves_and_stop_bonded_device();
3646 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3647 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3648 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3649 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3652 test_broadcast_tx_burst_slave_tx_fail(void)
3654 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3655 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3657 struct rte_eth_stats port_stats;
3661 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3662 BONDING_MODE_BROADCAST, 0,
3663 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3664 "Failed to initialise bonded device");
3666 /* Generate test bursts for transmission */
3667 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3668 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3669 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3670 "Failed to generate test packet burst");
3672 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3673 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3674 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3677 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3678 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3679 virtual_ethdev_tx_burst_fn_set_success(
3680 test_params->slave_port_ids[0],
3682 virtual_ethdev_tx_burst_fn_set_success(
3683 test_params->slave_port_ids[1],
3685 virtual_ethdev_tx_burst_fn_set_success(
3686 test_params->slave_port_ids[2],
3689 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3690 test_params->slave_port_ids[0],
3691 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3693 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3694 test_params->slave_port_ids[1],
3695 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3697 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3698 test_params->slave_port_ids[2],
3699 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3701 /* Transmit burst */
3702 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3703 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3705 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3706 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3707 "Transmitted (%d) packets, expected to transmit (%d) packets",
3708 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3709 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3711 /* Verify that failed packet are expected failed packets */
3712 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3713 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3714 "expected mbuf (%d) pointer %p not expected pointer %p",
3715 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3718 /* Verify slave ports tx stats */
3720 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3722 TEST_ASSERT_EQUAL(port_stats.opackets,
3723 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3724 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3725 "Port (%d) opackets value (%u) not as expected (%d)",
3726 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3727 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3728 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3731 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3733 TEST_ASSERT_EQUAL(port_stats.opackets,
3734 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3735 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3736 "Port (%d) opackets value (%u) not as expected (%d)",
3737 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3738 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3739 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3741 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3743 TEST_ASSERT_EQUAL(port_stats.opackets,
3744 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3745 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3746 "Port (%d) opackets value (%u) not as expected (%d)",
3747 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3748 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3749 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3752 /* Verify that all mbufs who transmission failed have a ref value of one */
3753 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3754 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3755 "mbufs refcnts not as expected");
3757 free_mbufs(&pkts_burst[tx_count],
3758 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3760 /* Clean up and remove slaves from bonded device */
3761 return remove_slaves_and_stop_bonded_device();
3764 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3767 test_broadcast_rx_burst(void)
3769 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3771 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3772 struct rte_eth_stats port_stats;
3774 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3777 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3779 /* Initialize bonded device with 4 slaves in round robin mode */
3780 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3781 BONDING_MODE_BROADCAST, 0, 3, 1),
3782 "Failed to initialise bonded device");
3784 /* Generate test bursts of packets to transmit */
3785 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3786 TEST_ASSERT_EQUAL(generate_test_burst(
3787 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3788 burst_size[i], "failed to generate packet burst");
3791 /* Add rx data to slave 0 */
3792 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3793 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3794 &gen_pkt_burst[i][0], burst_size[i]);
3798 /* Call rx burst on bonded device */
3799 /* Send burst on bonded port */
3800 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3801 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3802 burst_size[0] + burst_size[1] + burst_size[2],
3805 /* Verify bonded device rx count */
3806 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3807 TEST_ASSERT_EQUAL(port_stats.ipackets,
3808 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3809 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3810 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3811 burst_size[0] + burst_size[1] + burst_size[2]);
3814 /* Verify bonded slave devices rx counts */
3815 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3816 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3817 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3818 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3821 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3822 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3823 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3824 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3827 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3828 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3829 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3830 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3833 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3834 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3835 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3836 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3839 /* free mbufs allocate for rx testing */
3840 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3841 for (j = 0; j < MAX_PKT_BURST; j++) {
3842 if (gen_pkt_burst[i][j] != NULL) {
3843 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3844 gen_pkt_burst[i][j] = NULL;
3849 /* Clean up and remove slaves from bonded device */
3850 return remove_slaves_and_stop_bonded_device();
3854 test_broadcast_verify_promiscuous_enable_disable(void)
3859 /* Initialize bonded device with 4 slaves in round robin mode */
3860 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3861 BONDING_MODE_BROADCAST, 0, 4, 1),
3862 "Failed to initialise bonded device");
3864 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3865 TEST_ASSERT_SUCCESS(ret,
3866 "Failed to enable promiscuous mode for port %d: %s",
3867 test_params->bonded_port_id, rte_strerror(-ret));
3870 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3871 "Port (%d) promiscuous mode not enabled",
3872 test_params->bonded_port_id);
3874 for (i = 0; i < test_params->bonded_slave_count; i++) {
3875 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3876 test_params->slave_port_ids[i]), 1,
3877 "Port (%d) promiscuous mode not enabled",
3878 test_params->slave_port_ids[i]);
3881 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3882 TEST_ASSERT_SUCCESS(ret,
3883 "Failed to disable promiscuous mode for port %d: %s",
3884 test_params->bonded_port_id, rte_strerror(-ret));
3886 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3887 "Port (%d) promiscuous mode not disabled",
3888 test_params->bonded_port_id);
3890 for (i = 0; i < test_params->bonded_slave_count; i++) {
3891 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3892 test_params->slave_port_ids[i]), 0,
3893 "Port (%d) promiscuous mode not disabled",
3894 test_params->slave_port_ids[i]);
3897 /* Clean up and remove slaves from bonded device */
3898 return remove_slaves_and_stop_bonded_device();
3902 test_broadcast_verify_mac_assignment(void)
3904 struct rte_ether_addr read_mac_addr;
3905 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3909 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3910 "Failed to get mac address (port %d)",
3911 test_params->slave_port_ids[0]);
3912 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1),
3913 "Failed to get mac address (port %d)",
3914 test_params->slave_port_ids[2]);
3916 /* Initialize bonded device with 4 slaves in round robin mode */
3917 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3918 BONDING_MODE_BROADCAST, 0, 4, 1),
3919 "Failed to initialise bonded device");
3921 /* Verify that all MACs are the same as first slave added to bonded
3923 for (i = 0; i < test_params->bonded_slave_count; i++) {
3924 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3925 "Failed to get mac address (port %d)",
3926 test_params->slave_port_ids[i]);
3927 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3928 sizeof(read_mac_addr)),
3929 "slave port (%d) mac address not set to that of primary port",
3930 test_params->slave_port_ids[i]);
3933 /* change primary and verify that MAC addresses haven't changed */
3934 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3935 test_params->slave_port_ids[2]),
3936 "Failed to set bonded port (%d) primary port to (%d)",
3937 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3939 for (i = 0; i < test_params->bonded_slave_count; i++) {
3940 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3941 "Failed to get mac address (port %d)",
3942 test_params->slave_port_ids[i]);
3943 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3944 sizeof(read_mac_addr)),
3945 "slave port (%d) mac address has changed to that of primary "
3946 "port without stop/start toggle of bonded device",
3947 test_params->slave_port_ids[i]);
3950 /* stop / start bonded device and verify that primary MAC address is
3951 * propagated to bonded device and slaves */
3953 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
3954 "Failed to stop bonded port %u",
3955 test_params->bonded_port_id);
3957 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3958 "Failed to start bonded device");
3960 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3961 "Failed to get mac address (port %d)",
3962 test_params->bonded_port_id);
3963 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3964 sizeof(read_mac_addr)),
3965 "bonded port (%d) mac address not set to that of new primary port",
3966 test_params->slave_port_ids[i]);
3968 for (i = 0; i < test_params->bonded_slave_count; i++) {
3969 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3970 "Failed to get mac address (port %d)",
3971 test_params->slave_port_ids[i]);
3972 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3973 sizeof(read_mac_addr)),
3974 "slave port (%d) mac address not set to that of new primary "
3975 "port", test_params->slave_port_ids[i]);
3978 /* Set explicit MAC address */
3979 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3980 test_params->bonded_port_id,
3981 (struct rte_ether_addr *)bonded_mac),
3982 "Failed to set MAC address");
3984 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3985 "Failed to get mac address (port %d)",
3986 test_params->bonded_port_id);
3987 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3988 sizeof(read_mac_addr)),
3989 "bonded port (%d) mac address not set to that of new primary port",
3990 test_params->slave_port_ids[i]);
3993 for (i = 0; i < test_params->bonded_slave_count; i++) {
3994 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3995 "Failed to get mac address (port %d)",
3996 test_params->slave_port_ids[i]);
3997 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3998 sizeof(read_mac_addr)),
3999 "slave port (%d) mac address not set to that of new primary "
4000 "port", test_params->slave_port_ids[i]);
4003 /* Clean up and remove slaves from bonded device */
4004 return remove_slaves_and_stop_bonded_device();
4007 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
4009 test_broadcast_verify_slave_link_status_change_behaviour(void)
4011 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
4012 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4013 struct rte_eth_stats port_stats;
4015 uint16_t slaves[RTE_MAX_ETHPORTS];
4017 int i, burst_size, slave_count;
4019 memset(pkt_burst, 0, sizeof(pkt_burst));
4021 /* Initialize bonded device with 4 slaves in round robin mode */
4022 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4023 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
4024 1), "Failed to initialise bonded device");
4026 /* Verify Current Slaves Count /Active Slave Count is */
4027 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4029 TEST_ASSERT_EQUAL(slave_count, 4,
4030 "Number of slaves (%d) is not as expected (%d).",
4033 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4034 slaves, RTE_MAX_ETHPORTS);
4035 TEST_ASSERT_EQUAL(slave_count, 4,
4036 "Number of active slaves (%d) is not as expected (%d).",
4039 /* Set 2 slaves link status to down */
4040 virtual_ethdev_simulate_link_status_interrupt(
4041 test_params->slave_port_ids[1], 0);
4042 virtual_ethdev_simulate_link_status_interrupt(
4043 test_params->slave_port_ids[3], 0);
4045 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4046 slaves, RTE_MAX_ETHPORTS);
4047 TEST_ASSERT_EQUAL(slave_count, 2,
4048 "Number of active slaves (%d) is not as expected (%d).",
4051 for (i = 0; i < test_params->bonded_slave_count; i++)
4052 rte_eth_stats_reset(test_params->slave_port_ids[i]);
4054 /* Verify that pkts are not sent on slaves with link status down */
4057 TEST_ASSERT_EQUAL(generate_test_burst(
4058 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
4059 "generate_test_burst failed");
4061 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
4062 &pkt_burst[0][0], burst_size), burst_size,
4063 "rte_eth_tx_burst failed\n");
4065 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4066 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
4067 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
4068 test_params->bonded_port_id, (int)port_stats.opackets,
4069 burst_size * slave_count);
4071 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4072 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4073 "(%d) port_stats.opackets not as expected",
4074 test_params->slave_port_ids[0]);
4076 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4077 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4078 "(%d) port_stats.opackets not as expected",
4079 test_params->slave_port_ids[1]);
4081 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4082 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4083 "(%d) port_stats.opackets not as expected",
4084 test_params->slave_port_ids[2]);
4087 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4088 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4089 "(%d) port_stats.opackets not as expected",
4090 test_params->slave_port_ids[3]);
4093 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4094 TEST_ASSERT_EQUAL(generate_test_burst(
4095 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
4096 burst_size, "failed to generate packet burst");
4098 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4099 &pkt_burst[i][0], burst_size);
4102 /* Verify that pkts are not received on slaves with link status down */
4103 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
4104 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
4105 burst_size + burst_size, "rte_eth_rx_burst failed");
4108 /* Verify bonded device rx count */
4109 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4110 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
4111 "(%d) port_stats.ipackets not as expected\n",
4112 test_params->bonded_port_id);
4114 /* Clean up and remove slaves from bonded device */
4115 return remove_slaves_and_stop_bonded_device();
4119 test_reconfigure_bonded_device(void)
4121 test_params->nb_rx_q = 4;
4122 test_params->nb_tx_q = 4;
4124 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4125 "failed to reconfigure bonded device");
4127 test_params->nb_rx_q = 2;
4128 test_params->nb_tx_q = 2;
4130 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4131 "failed to reconfigure bonded device with less rx/tx queues");
4138 test_close_bonded_device(void)
4140 rte_eth_dev_close(test_params->bonded_port_id);
4145 testsuite_teardown(void)
4147 free(test_params->pkt_eth_hdr);
4148 test_params->pkt_eth_hdr = NULL;
4150 /* Clean up and remove slaves from bonded device */
4151 remove_slaves_and_stop_bonded_device();
4155 free_virtualpmd_tx_queue(void)
4157 int i, slave_port, to_free_cnt;
4158 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4160 /* Free tx queue of virtual pmd */
4161 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4163 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4164 test_params->slave_port_ids[slave_port],
4165 pkts_to_free, MAX_PKT_BURST);
4166 for (i = 0; i < to_free_cnt; i++)
4167 rte_pktmbuf_free(pkts_to_free[i]);
4172 test_tlb_tx_burst(void)
4174 int i, burst_size, nb_tx;
4175 uint64_t nb_tx2 = 0;
4176 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4177 struct rte_eth_stats port_stats[32];
4178 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4181 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4182 (BONDING_MODE_TLB, 1, 3, 1),
4183 "Failed to initialise bonded device");
4185 burst_size = 20 * test_params->bonded_slave_count;
4187 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4188 "Burst size specified is greater than supported.\n");
4191 /* Generate bursts of packets */
4192 for (i = 0; i < 400000; i++) {
4193 /*test two types of mac src own(bonding) and others */
4195 initialize_eth_header(test_params->pkt_eth_hdr,
4196 (struct rte_ether_addr *)src_mac,
4197 (struct rte_ether_addr *)dst_mac_0,
4198 RTE_ETHER_TYPE_IPV4, 0, 0);
4200 initialize_eth_header(test_params->pkt_eth_hdr,
4201 (struct rte_ether_addr *)test_params->default_slave_mac,
4202 (struct rte_ether_addr *)dst_mac_0,
4203 RTE_ETHER_TYPE_IPV4, 0, 0);
4205 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4207 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4208 dst_addr_0, pktlen);
4209 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4210 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4211 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4212 /* Send burst on bonded port */
4213 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4217 free_virtualpmd_tx_queue();
4219 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4220 "number of packet not equal burst size");
4226 /* Verify bonded port tx stats */
4227 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4229 all_bond_opackets = port_stats[0].opackets;
4230 all_bond_obytes = port_stats[0].obytes;
4232 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4233 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4234 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4238 /* Verify slave ports tx stats */
4239 for (i = 0; i < test_params->bonded_slave_count; i++) {
4240 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4241 sum_ports_opackets += port_stats[i].opackets;
4244 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4245 "Total packets sent by slaves is not equal to packets sent by bond interface");
4247 /* checking if distribution of packets is balanced over slaves */
4248 for (i = 0; i < test_params->bonded_slave_count; i++) {
4249 TEST_ASSERT(port_stats[i].obytes > 0 &&
4250 port_stats[i].obytes < all_bond_obytes,
4251 "Packets are not balanced over slaves");
4254 /* Put all slaves down and try and transmit */
4255 for (i = 0; i < test_params->bonded_slave_count; i++) {
4256 virtual_ethdev_simulate_link_status_interrupt(
4257 test_params->slave_port_ids[i], 0);
4260 /* Send burst on bonded port */
4261 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4263 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4265 /* Clean ugit checkout masterp and remove slaves from bonded device */
4266 return remove_slaves_and_stop_bonded_device();
4269 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4272 test_tlb_rx_burst(void)
4274 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4275 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4277 struct rte_eth_stats port_stats;
4281 uint16_t i, j, nb_rx, burst_size = 17;
4283 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4284 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4286 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4287 "Failed to initialize bonded device");
4290 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4291 TEST_ASSERT(primary_port >= 0,
4292 "failed to get primary slave for bonded port (%d)",
4293 test_params->bonded_port_id);
4295 for (i = 0; i < test_params->bonded_slave_count; i++) {
4296 /* Generate test bursts of packets to transmit */
4297 TEST_ASSERT_EQUAL(generate_test_burst(
4298 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4299 "burst generation failed");
4301 /* Add rx data to slave */
4302 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4303 &gen_pkt_burst[0], burst_size);
4305 /* Call rx burst on bonded device */
4306 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4307 &rx_pkt_burst[0], MAX_PKT_BURST);
4309 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4311 if (test_params->slave_port_ids[i] == primary_port) {
4312 /* Verify bonded device rx count */
4313 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4314 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4315 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4316 test_params->bonded_port_id,
4317 (unsigned int)port_stats.ipackets, burst_size);
4319 /* Verify bonded slave devices rx count */
4320 for (j = 0; j < test_params->bonded_slave_count; j++) {
4321 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4323 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4324 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4325 test_params->slave_port_ids[i],
4326 (unsigned int)port_stats.ipackets, burst_size);
4328 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4329 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4330 test_params->slave_port_ids[i],
4331 (unsigned int)port_stats.ipackets, 0);
4335 for (j = 0; j < test_params->bonded_slave_count; j++) {
4336 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4337 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4338 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4339 test_params->slave_port_ids[i],
4340 (unsigned int)port_stats.ipackets, 0);
4345 for (i = 0; i < burst_size; i++)
4346 rte_pktmbuf_free(rx_pkt_burst[i]);
4348 /* reset bonded device stats */
4349 rte_eth_stats_reset(test_params->bonded_port_id);
4352 /* Clean up and remove slaves from bonded device */
4353 return remove_slaves_and_stop_bonded_device();
4357 test_tlb_verify_promiscuous_enable_disable(void)
4359 int i, primary_port, promiscuous_en;
4362 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4363 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4364 BONDING_MODE_TLB, 0, 4, 1),
4365 "Failed to initialize bonded device");
4367 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4368 TEST_ASSERT(primary_port >= 0,
4369 "failed to get primary slave for bonded port (%d)",
4370 test_params->bonded_port_id);
4372 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
4373 TEST_ASSERT_SUCCESS(ret,
4374 "Failed to enable promiscuous mode for port %d: %s",
4375 test_params->bonded_port_id, rte_strerror(-ret));
4377 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4378 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4379 "Port (%d) promiscuous mode not enabled\n",
4380 test_params->bonded_port_id);
4381 for (i = 0; i < test_params->bonded_slave_count; i++) {
4382 promiscuous_en = rte_eth_promiscuous_get(
4383 test_params->slave_port_ids[i]);
4384 if (primary_port == test_params->slave_port_ids[i]) {
4385 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4386 "Port (%d) promiscuous mode not enabled\n",
4387 test_params->bonded_port_id);
4389 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4390 "Port (%d) promiscuous mode enabled\n",
4391 test_params->bonded_port_id);
4396 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
4397 TEST_ASSERT_SUCCESS(ret,
4398 "Failed to disable promiscuous mode for port %d: %s\n",
4399 test_params->bonded_port_id, rte_strerror(-ret));
4401 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4402 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4403 "Port (%d) promiscuous mode not disabled\n",
4404 test_params->bonded_port_id);
4406 for (i = 0; i < test_params->bonded_slave_count; i++) {
4407 promiscuous_en = rte_eth_promiscuous_get(
4408 test_params->slave_port_ids[i]);
4409 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4410 "slave port (%d) promiscuous mode not disabled\n",
4411 test_params->slave_port_ids[i]);
4414 /* Clean up and remove slaves from bonded device */
4415 return remove_slaves_and_stop_bonded_device();
4419 test_tlb_verify_mac_assignment(void)
4421 struct rte_ether_addr read_mac_addr;
4422 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
4424 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
4425 "Failed to get mac address (port %d)",
4426 test_params->slave_port_ids[0]);
4427 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
4428 "Failed to get mac address (port %d)",
4429 test_params->slave_port_ids[1]);
4431 /* Initialize bonded device with 2 slaves in active backup mode */
4432 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4433 BONDING_MODE_TLB, 0, 2, 1),
4434 "Failed to initialize bonded device");
4436 /* Verify that bonded MACs is that of first slave and that the other slave
4437 * MAC hasn't been changed */
4438 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4439 "Failed to get mac address (port %d)",
4440 test_params->bonded_port_id);
4441 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4442 sizeof(read_mac_addr)),
4443 "bonded port (%d) mac address not set to that of primary port",
4444 test_params->bonded_port_id);
4446 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4447 "Failed to get mac address (port %d)",
4448 test_params->slave_port_ids[0]);
4449 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4450 sizeof(read_mac_addr)),
4451 "slave port (%d) mac address not set to that of primary port",
4452 test_params->slave_port_ids[0]);
4454 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4455 "Failed to get mac address (port %d)",
4456 test_params->slave_port_ids[1]);
4457 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4458 sizeof(read_mac_addr)),
4459 "slave port (%d) mac address not as expected",
4460 test_params->slave_port_ids[1]);
4462 /* change primary and verify that MAC addresses haven't changed */
4463 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4464 test_params->slave_port_ids[1]), 0,
4465 "Failed to set bonded port (%d) primary port to (%d)",
4466 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4468 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4469 "Failed to get mac address (port %d)",
4470 test_params->bonded_port_id);
4471 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4472 sizeof(read_mac_addr)),
4473 "bonded port (%d) mac address not set to that of primary port",
4474 test_params->bonded_port_id);
4476 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4477 "Failed to get mac address (port %d)",
4478 test_params->slave_port_ids[0]);
4479 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4480 sizeof(read_mac_addr)),
4481 "slave port (%d) mac address not set to that of primary port",
4482 test_params->slave_port_ids[0]);
4484 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4485 "Failed to get mac address (port %d)",
4486 test_params->slave_port_ids[1]);
4487 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4488 sizeof(read_mac_addr)),
4489 "slave port (%d) mac address not as expected",
4490 test_params->slave_port_ids[1]);
4492 /* stop / start bonded device and verify that primary MAC address is
4493 * propagated to bonded device and slaves */
4495 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
4496 "Failed to stop bonded port %u",
4497 test_params->bonded_port_id);
4499 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4500 "Failed to start device");
4502 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4503 "Failed to get mac address (port %d)",
4504 test_params->bonded_port_id);
4505 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4506 sizeof(read_mac_addr)),
4507 "bonded port (%d) mac address not set to that of primary port",
4508 test_params->bonded_port_id);
4510 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4511 "Failed to get mac address (port %d)",
4512 test_params->slave_port_ids[0]);
4513 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4514 sizeof(read_mac_addr)),
4515 "slave port (%d) mac address not as expected",
4516 test_params->slave_port_ids[0]);
4518 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4519 "Failed to get mac address (port %d)",
4520 test_params->slave_port_ids[1]);
4521 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4522 sizeof(read_mac_addr)),
4523 "slave port (%d) mac address not set to that of primary port",
4524 test_params->slave_port_ids[1]);
4527 /* Set explicit MAC address */
4528 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4529 test_params->bonded_port_id,
4530 (struct rte_ether_addr *)bonded_mac),
4531 "failed to set MAC address");
4533 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4534 "Failed to get mac address (port %d)",
4535 test_params->bonded_port_id);
4536 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4537 sizeof(read_mac_addr)),
4538 "bonded port (%d) mac address not set to that of bonded port",
4539 test_params->bonded_port_id);
4541 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4542 "Failed to get mac address (port %d)",
4543 test_params->slave_port_ids[0]);
4544 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4545 sizeof(read_mac_addr)),
4546 "slave port (%d) mac address not as expected",
4547 test_params->slave_port_ids[0]);
4549 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4550 "Failed to get mac address (port %d)",
4551 test_params->slave_port_ids[1]);
4552 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4553 sizeof(read_mac_addr)),
4554 "slave port (%d) mac address not set to that of bonded port",
4555 test_params->slave_port_ids[1]);
4557 /* Clean up and remove slaves from bonded device */
4558 return remove_slaves_and_stop_bonded_device();
4562 test_tlb_verify_slave_link_status_change_failover(void)
4564 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4565 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4566 struct rte_eth_stats port_stats;
4568 uint16_t slaves[RTE_MAX_ETHPORTS];
4570 int i, burst_size, slave_count, primary_port;
4574 memset(pkt_burst, 0, sizeof(pkt_burst));
4578 /* Initialize bonded device with 4 slaves in round robin mode */
4579 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4580 BONDING_MODE_TLB, 0,
4581 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4582 "Failed to initialize bonded device with slaves");
4584 /* Verify Current Slaves Count /Active Slave Count is */
4585 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4587 TEST_ASSERT_EQUAL(slave_count, 4,
4588 "Number of slaves (%d) is not as expected (%d).\n",
4591 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4592 slaves, RTE_MAX_ETHPORTS);
4593 TEST_ASSERT_EQUAL(slave_count, (int)4,
4594 "Number of slaves (%d) is not as expected (%d).\n",
4597 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4598 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4599 "Primary port not as expected");
4601 /* Bring 2 slaves down and verify active slave count */
4602 virtual_ethdev_simulate_link_status_interrupt(
4603 test_params->slave_port_ids[1], 0);
4604 virtual_ethdev_simulate_link_status_interrupt(
4605 test_params->slave_port_ids[3], 0);
4607 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4608 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4609 "Number of active slaves (%d) is not as expected (%d).",
4612 virtual_ethdev_simulate_link_status_interrupt(
4613 test_params->slave_port_ids[1], 1);
4614 virtual_ethdev_simulate_link_status_interrupt(
4615 test_params->slave_port_ids[3], 1);
4618 /* Bring primary port down, verify that active slave count is 3 and primary
4620 virtual_ethdev_simulate_link_status_interrupt(
4621 test_params->slave_port_ids[0], 0);
4623 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4624 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4625 "Number of active slaves (%d) is not as expected (%d).",
4628 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4629 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4630 "Primary port not as expected");
4631 rte_delay_us(500000);
4632 /* Verify that pkts are sent on new primary slave */
4633 for (i = 0; i < 4; i++) {
4634 TEST_ASSERT_EQUAL(generate_test_burst(
4635 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4636 "generate_test_burst failed\n");
4637 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4638 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4639 "rte_eth_tx_burst failed\n");
4640 rte_delay_us(11000);
4643 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4644 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4645 "(%d) port_stats.opackets not as expected\n",
4646 test_params->slave_port_ids[0]);
4648 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4649 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4650 "(%d) port_stats.opackets not as expected\n",
4651 test_params->slave_port_ids[1]);
4653 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4654 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4655 "(%d) port_stats.opackets not as expected\n",
4656 test_params->slave_port_ids[2]);
4658 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4659 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4660 "(%d) port_stats.opackets not as expected\n",
4661 test_params->slave_port_ids[3]);
4664 /* Generate packet burst for testing */
4666 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4667 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4671 virtual_ethdev_add_mbufs_to_rx_queue(
4672 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4675 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4676 MAX_PKT_BURST) != burst_size) {
4677 printf("rte_eth_rx_burst\n");
4682 /* Verify bonded device rx count */
4683 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4684 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4685 "(%d) port_stats.ipackets not as expected\n",
4686 test_params->bonded_port_id);
4688 /* Clean up and remove slaves from bonded device */
4689 return remove_slaves_and_stop_bonded_device();
4692 #define TEST_ALB_SLAVE_COUNT 2
4694 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4695 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4696 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4697 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4699 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4700 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4701 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4702 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4703 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4706 test_alb_change_mac_in_reply_sent(void)
4708 struct rte_mbuf *pkt;
4709 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4711 struct rte_ether_hdr *eth_pkt;
4712 struct rte_arp_hdr *arp_pkt;
4714 int slave_idx, nb_pkts, pkt_idx;
4717 struct rte_ether_addr bond_mac, client_mac;
4718 struct rte_ether_addr *slave_mac1, *slave_mac2;
4720 TEST_ASSERT_SUCCESS(
4721 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4722 0, TEST_ALB_SLAVE_COUNT, 1),
4723 "Failed to initialize_bonded_device_with_slaves.");
4725 /* Flush tx queue */
4726 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4727 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4729 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4730 test_params->slave_port_ids[slave_idx], pkts_sent,
4734 rte_ether_addr_copy(
4735 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4739 * Generating four packets with different mac and ip addresses and sending
4740 * them through the bonding port.
4742 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4743 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4744 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4745 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4746 RTE_ETHER_TYPE_ARP, 0, 0);
4747 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4748 sizeof(struct rte_ether_hdr));
4749 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4751 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4753 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4754 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4755 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4756 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4757 RTE_ETHER_TYPE_ARP, 0, 0);
4758 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4759 sizeof(struct rte_ether_hdr));
4760 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4762 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4764 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4765 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4766 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4767 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4768 RTE_ETHER_TYPE_ARP, 0, 0);
4769 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4770 sizeof(struct rte_ether_hdr));
4771 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4773 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4775 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4776 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4777 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4778 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4779 RTE_ETHER_TYPE_ARP, 0, 0);
4780 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4781 sizeof(struct rte_ether_hdr));
4782 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4784 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4787 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4789 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4792 * Checking if packets are properly distributed on bonding ports. Packets
4793 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4795 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4796 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4797 test_params->slave_port_ids[slave_idx], pkts_sent,
4800 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4801 eth_pkt = rte_pktmbuf_mtod(
4802 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4803 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4804 sizeof(struct rte_ether_hdr));
4806 if (slave_idx%2 == 0) {
4807 if (!rte_is_same_ether_addr(slave_mac1,
4808 &arp_pkt->arp_data.arp_sha)) {
4813 if (!rte_is_same_ether_addr(slave_mac2,
4814 &arp_pkt->arp_data.arp_sha)) {
4823 retval += remove_slaves_and_stop_bonded_device();
4828 test_alb_reply_from_client(void)
4830 struct rte_ether_hdr *eth_pkt;
4831 struct rte_arp_hdr *arp_pkt;
4833 struct rte_mbuf *pkt;
4834 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4836 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4839 struct rte_ether_addr bond_mac, client_mac;
4840 struct rte_ether_addr *slave_mac1, *slave_mac2;
4842 TEST_ASSERT_SUCCESS(
4843 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4844 0, TEST_ALB_SLAVE_COUNT, 1),
4845 "Failed to initialize_bonded_device_with_slaves.");
4847 /* Flush tx queue */
4848 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4849 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4850 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4851 test_params->slave_port_ids[slave_idx], pkts_sent,
4855 rte_ether_addr_copy(
4856 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4860 * Generating four packets with different mac and ip addresses and placing
4861 * them in the rx queue to be received by the bonding driver on rx_burst.
4863 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4864 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4865 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4866 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4867 RTE_ETHER_TYPE_ARP, 0, 0);
4868 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4869 sizeof(struct rte_ether_hdr));
4870 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4872 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4875 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4876 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4877 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4878 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4879 RTE_ETHER_TYPE_ARP, 0, 0);
4880 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4881 sizeof(struct rte_ether_hdr));
4882 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4884 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4887 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4888 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4889 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4890 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4891 RTE_ETHER_TYPE_ARP, 0, 0);
4892 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4893 sizeof(struct rte_ether_hdr));
4894 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4896 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4899 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4900 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4901 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4902 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4903 RTE_ETHER_TYPE_ARP, 0, 0);
4904 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4905 sizeof(struct rte_ether_hdr));
4906 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4908 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4912 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4913 * packets to every client in alb table.
4915 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4916 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4918 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4919 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4922 * Checking if update ARP packets were properly send on slave ports.
4924 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4925 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4926 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4927 nb_pkts_sum += nb_pkts;
4929 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4930 eth_pkt = rte_pktmbuf_mtod(
4931 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4932 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4933 sizeof(struct rte_ether_hdr));
4935 if (slave_idx%2 == 0) {
4936 if (!rte_is_same_ether_addr(slave_mac1,
4937 &arp_pkt->arp_data.arp_sha)) {
4942 if (!rte_is_same_ether_addr(slave_mac2,
4943 &arp_pkt->arp_data.arp_sha)) {
4951 /* Check if proper number of packets was send */
4952 if (nb_pkts_sum < 4) {
4958 retval += remove_slaves_and_stop_bonded_device();
4963 test_alb_receive_vlan_reply(void)
4965 struct rte_ether_hdr *eth_pkt;
4966 struct rte_vlan_hdr *vlan_pkt;
4967 struct rte_arp_hdr *arp_pkt;
4969 struct rte_mbuf *pkt;
4970 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4972 int slave_idx, nb_pkts, pkt_idx;
4975 struct rte_ether_addr bond_mac, client_mac;
4977 TEST_ASSERT_SUCCESS(
4978 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4979 0, TEST_ALB_SLAVE_COUNT, 1),
4980 "Failed to initialize_bonded_device_with_slaves.");
4982 /* Flush tx queue */
4983 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4984 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4985 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4986 test_params->slave_port_ids[slave_idx], pkts_sent,
4990 rte_ether_addr_copy(
4991 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4995 * Generating packet with double VLAN header and placing it in the rx queue.
4997 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4998 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4999 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
5000 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
5001 RTE_ETHER_TYPE_VLAN, 0, 0);
5002 vlan_pkt = (struct rte_vlan_hdr *)((char *)(eth_pkt + 1));
5003 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
5004 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
5005 vlan_pkt = vlan_pkt+1;
5006 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
5007 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
5008 arp_pkt = (struct rte_arp_hdr *)((char *)(vlan_pkt + 1));
5009 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
5011 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
5014 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
5015 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
5018 * Checking if VLAN headers in generated ARP Update packet are correct.
5020 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
5021 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
5022 test_params->slave_port_ids[slave_idx], pkts_sent,
5025 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
5026 eth_pkt = rte_pktmbuf_mtod(
5027 pkts_sent[pkt_idx], struct rte_ether_hdr *);
5028 vlan_pkt = (struct rte_vlan_hdr *)(
5029 (char *)(eth_pkt + 1));
5030 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
5034 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5035 RTE_ETHER_TYPE_VLAN)) {
5039 vlan_pkt = vlan_pkt+1;
5040 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
5044 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5045 RTE_ETHER_TYPE_ARP)) {
5053 retval += remove_slaves_and_stop_bonded_device();
5058 test_alb_ipv4_tx(void)
5060 int burst_size, retval, pkts_send;
5061 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
5065 TEST_ASSERT_SUCCESS(
5066 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
5067 0, TEST_ALB_SLAVE_COUNT, 1),
5068 "Failed to initialize_bonded_device_with_slaves.");
5072 /* Generate test bursts of packets to transmit */
5073 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
5079 * Checking if ipv4 traffic is transmitted via TLB policy.
5081 pkts_send = rte_eth_tx_burst(
5082 test_params->bonded_port_id, 0, pkt_burst, burst_size);
5083 if (pkts_send != burst_size) {
5089 retval += remove_slaves_and_stop_bonded_device();
5093 static struct unit_test_suite link_bonding_test_suite = {
5094 .suite_name = "Link Bonding Unit Test Suite",
5095 .setup = test_setup,
5096 .teardown = testsuite_teardown,
5097 .unit_test_cases = {
5098 TEST_CASE(test_create_bonded_device),
5099 TEST_CASE(test_create_bonded_device_with_invalid_params),
5100 TEST_CASE(test_add_slave_to_bonded_device),
5101 TEST_CASE(test_add_slave_to_invalid_bonded_device),
5102 TEST_CASE(test_remove_slave_from_bonded_device),
5103 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
5104 TEST_CASE(test_get_slaves_from_bonded_device),
5105 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
5106 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
5107 TEST_CASE(test_start_bonded_device),
5108 TEST_CASE(test_stop_bonded_device),
5109 TEST_CASE(test_set_bonding_mode),
5110 TEST_CASE(test_set_primary_slave),
5111 TEST_CASE(test_set_explicit_bonded_mac),
5112 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
5113 TEST_CASE(test_status_interrupt),
5114 TEST_CASE(test_adding_slave_after_bonded_device_started),
5115 TEST_CASE(test_roundrobin_tx_burst),
5116 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
5117 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
5118 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
5119 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
5120 TEST_CASE(test_roundrobin_verify_mac_assignment),
5121 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
5122 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
5123 TEST_CASE(test_activebackup_tx_burst),
5124 TEST_CASE(test_activebackup_rx_burst),
5125 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
5126 TEST_CASE(test_activebackup_verify_mac_assignment),
5127 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
5128 TEST_CASE(test_balance_xmit_policy_configuration),
5129 TEST_CASE(test_balance_l2_tx_burst),
5130 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
5131 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
5132 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
5133 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
5134 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
5135 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
5136 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
5137 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
5138 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
5139 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
5140 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
5141 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
5142 TEST_CASE(test_balance_rx_burst),
5143 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
5144 TEST_CASE(test_balance_verify_mac_assignment),
5145 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
5146 TEST_CASE(test_tlb_tx_burst),
5147 TEST_CASE(test_tlb_rx_burst),
5148 TEST_CASE(test_tlb_verify_mac_assignment),
5149 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
5150 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
5151 TEST_CASE(test_alb_change_mac_in_reply_sent),
5152 TEST_CASE(test_alb_reply_from_client),
5153 TEST_CASE(test_alb_receive_vlan_reply),
5154 TEST_CASE(test_alb_ipv4_tx),
5155 TEST_CASE(test_broadcast_tx_burst),
5156 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
5157 TEST_CASE(test_broadcast_rx_burst),
5158 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
5159 TEST_CASE(test_broadcast_verify_mac_assignment),
5160 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
5161 TEST_CASE(test_reconfigure_bonded_device),
5162 TEST_CASE(test_close_bonded_device),
5164 TEST_CASES_END() /**< NULL terminate unit test array */
5170 test_link_bonding(void)
5172 return unit_test_suite_runner(&link_bonding_test_suite);
5175 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);