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 = ETH_MQ_RX_NONE,
141 .mq_mode = 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 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
185 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
186 rte_eth_dev_socket_id(port_id), &rx_conf_default,
187 test_params->mbuf_pool) ,
188 "rte_eth_rx_queue_setup for port %d failed", port_id);
190 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
191 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
192 rte_eth_dev_socket_id(port_id), &tx_conf_default),
193 "rte_eth_tx_queue_setup for port %d failed", port_id);
196 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
197 "rte_eth_dev_start for port %d failed", port_id);
202 static int slaves_initialized;
203 static int mac_slaves_initialized;
205 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
206 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
212 int i, nb_mbuf_per_pool;
213 struct rte_ether_addr *mac_addr = (struct rte_ether_addr *)slave_mac;
215 /* Allocate ethernet packet header with space for VLAN header */
216 if (test_params->pkt_eth_hdr == NULL) {
217 test_params->pkt_eth_hdr = malloc(sizeof(struct rte_ether_hdr) +
218 sizeof(struct rte_vlan_hdr));
220 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
221 "Ethernet header struct allocation failed!");
224 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
225 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
226 if (test_params->mbuf_pool == NULL) {
227 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
228 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
229 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
230 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
231 "rte_mempool_create failed");
234 /* Create / Initialize virtual eth devs */
235 if (!slaves_initialized) {
236 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
237 char pmd_name[RTE_ETH_NAME_MAX_LEN];
239 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
241 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
243 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
244 mac_addr, rte_socket_id(), 1);
245 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
246 "Failed to create virtual virtual ethdev %s", pmd_name);
248 TEST_ASSERT_SUCCESS(configure_ethdev(
249 test_params->slave_port_ids[i], 1, 0),
250 "Failed to configure virtual ethdev %s", pmd_name);
252 slaves_initialized = 1;
259 test_create_bonded_device(void)
261 int current_slave_count;
263 uint16_t slaves[RTE_MAX_ETHPORTS];
265 /* Don't try to recreate bonded device if re-running test suite*/
266 if (test_params->bonded_port_id == -1) {
267 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
268 test_params->bonding_mode, rte_socket_id());
270 TEST_ASSERT(test_params->bonded_port_id >= 0,
271 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
273 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
274 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
277 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
278 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
279 test_params->bonded_port_id, test_params->bonding_mode);
281 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
282 slaves, RTE_MAX_ETHPORTS);
284 TEST_ASSERT_EQUAL(current_slave_count, 0,
285 "Number of slaves %d is great than expected %d.",
286 current_slave_count, 0);
288 current_slave_count = rte_eth_bond_active_slaves_get(
289 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
291 TEST_ASSERT_EQUAL(current_slave_count, 0,
292 "Number of active slaves %d is great than expected %d.",
293 current_slave_count, 0);
300 test_create_bonded_device_with_invalid_params(void)
304 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
307 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
309 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
311 test_params->bonding_mode = INVALID_BONDING_MODE;
313 /* Invalid bonding mode */
314 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
316 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
318 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
320 /* Invalid socket id */
321 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
323 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
329 test_add_slave_to_bonded_device(void)
331 int current_slave_count;
333 uint16_t slaves[RTE_MAX_ETHPORTS];
335 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
336 test_params->slave_port_ids[test_params->bonded_slave_count]),
337 "Failed to add slave (%d) to bonded port (%d).",
338 test_params->slave_port_ids[test_params->bonded_slave_count],
339 test_params->bonded_port_id);
341 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
342 slaves, RTE_MAX_ETHPORTS);
343 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
344 "Number of slaves (%d) is greater than expected (%d).",
345 current_slave_count, test_params->bonded_slave_count + 1);
347 current_slave_count = rte_eth_bond_active_slaves_get(
348 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
349 TEST_ASSERT_EQUAL(current_slave_count, 0,
350 "Number of active slaves (%d) is not as expected (%d).\n",
351 current_slave_count, 0);
353 test_params->bonded_slave_count++;
359 test_add_slave_to_invalid_bonded_device(void)
361 /* Invalid port ID */
362 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
363 test_params->slave_port_ids[test_params->bonded_slave_count]),
364 "Expected call to failed as invalid port specified.");
366 /* Non bonded device */
367 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
368 test_params->slave_port_ids[test_params->bonded_slave_count]),
369 "Expected call to failed as invalid port specified.");
376 test_remove_slave_from_bonded_device(void)
378 int current_slave_count;
379 struct rte_ether_addr read_mac_addr, *mac_addr;
380 uint16_t slaves[RTE_MAX_ETHPORTS];
382 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
383 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
384 "Failed to remove slave %d from bonded port (%d).",
385 test_params->slave_port_ids[test_params->bonded_slave_count-1],
386 test_params->bonded_port_id);
389 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
390 slaves, RTE_MAX_ETHPORTS);
392 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
393 "Number of slaves (%d) is great than expected (%d).\n",
394 current_slave_count, test_params->bonded_slave_count - 1);
397 mac_addr = (struct rte_ether_addr *)slave_mac;
398 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] =
399 test_params->bonded_slave_count-1;
401 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(
402 test_params->slave_port_ids[test_params->bonded_slave_count-1],
404 "Failed to get mac address (port %d)",
405 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
406 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
407 "bonded port mac address not set to that of primary port\n");
410 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
412 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
415 test_params->bonded_slave_count--;
421 test_remove_slave_from_invalid_bonded_device(void)
423 /* Invalid port ID */
424 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
425 test_params->bonded_port_id + 5,
426 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
427 "Expected call to failed as invalid port specified.");
429 /* Non bonded device */
430 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
431 test_params->slave_port_ids[0],
432 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
433 "Expected call to failed as invalid port specified.");
438 static int bonded_id = 2;
441 test_add_already_bonded_slave_to_bonded_device(void)
443 int port_id, current_slave_count;
444 uint16_t slaves[RTE_MAX_ETHPORTS];
445 char pmd_name[RTE_ETH_NAME_MAX_LEN];
447 test_add_slave_to_bonded_device();
449 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
450 slaves, RTE_MAX_ETHPORTS);
451 TEST_ASSERT_EQUAL(current_slave_count, 1,
452 "Number of slaves (%d) is not that expected (%d).",
453 current_slave_count, 1);
455 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
457 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
459 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
461 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
462 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
464 "Added slave (%d) to bonded port (%d) unexpectedly.",
465 test_params->slave_port_ids[test_params->bonded_slave_count-1],
468 return test_remove_slave_from_bonded_device();
473 test_get_slaves_from_bonded_device(void)
475 int current_slave_count;
476 uint16_t slaves[RTE_MAX_ETHPORTS];
478 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
479 "Failed to add slave to bonded device");
481 /* Invalid port id */
482 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
484 TEST_ASSERT(current_slave_count < 0,
485 "Invalid port id unexpectedly succeeded");
487 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
488 slaves, RTE_MAX_ETHPORTS);
489 TEST_ASSERT(current_slave_count < 0,
490 "Invalid port id unexpectedly succeeded");
492 /* Invalid slaves pointer */
493 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
494 NULL, RTE_MAX_ETHPORTS);
495 TEST_ASSERT(current_slave_count < 0,
496 "Invalid slave array unexpectedly succeeded");
498 current_slave_count = rte_eth_bond_active_slaves_get(
499 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
500 TEST_ASSERT(current_slave_count < 0,
501 "Invalid slave array unexpectedly succeeded");
503 /* non bonded device*/
504 current_slave_count = rte_eth_bond_slaves_get(
505 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
506 TEST_ASSERT(current_slave_count < 0,
507 "Invalid port id unexpectedly succeeded");
509 current_slave_count = rte_eth_bond_active_slaves_get(
510 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
511 TEST_ASSERT(current_slave_count < 0,
512 "Invalid port id unexpectedly succeeded");
514 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
515 "Failed to remove slaves from bonded device");
522 test_add_remove_multiple_slaves_to_from_bonded_device(void)
526 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
527 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
528 "Failed to add slave to bonded device");
530 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
531 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
532 "Failed to remove slaves from bonded device");
538 enable_bonded_slaves(void)
542 for (i = 0; i < test_params->bonded_slave_count; i++) {
543 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
546 virtual_ethdev_simulate_link_status_interrupt(
547 test_params->slave_port_ids[i], 1);
552 test_start_bonded_device(void)
554 struct rte_eth_link link_status;
556 int current_slave_count, current_bonding_mode, primary_port;
557 uint16_t slaves[RTE_MAX_ETHPORTS];
560 /* Add slave to bonded device*/
561 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
562 "Failed to add slave to bonded device");
564 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
565 "Failed to start bonded pmd eth device %d.",
566 test_params->bonded_port_id);
568 /* Change link status of virtual pmd so it will be added to the active
569 * slave list of the bonded device*/
570 virtual_ethdev_simulate_link_status_interrupt(
571 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
573 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
574 slaves, RTE_MAX_ETHPORTS);
575 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
576 "Number of slaves (%d) is not expected value (%d).",
577 current_slave_count, test_params->bonded_slave_count);
579 current_slave_count = rte_eth_bond_active_slaves_get(
580 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
581 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
582 "Number of active slaves (%d) is not expected value (%d).",
583 current_slave_count, test_params->bonded_slave_count);
585 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
586 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
587 "Bonded device mode (%d) is not expected value (%d).\n",
588 current_bonding_mode, test_params->bonding_mode);
590 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
591 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
592 "Primary port (%d) is not expected value (%d).",
593 primary_port, test_params->slave_port_ids[0]);
595 retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
596 TEST_ASSERT(retval >= 0,
597 "Bonded port (%d) link get failed: %s\n",
598 test_params->bonded_port_id, rte_strerror(-retval));
599 TEST_ASSERT_EQUAL(link_status.link_status, 1,
600 "Bonded port (%d) status (%d) is not expected value (%d).\n",
601 test_params->bonded_port_id, link_status.link_status, 1);
607 test_stop_bonded_device(void)
609 int current_slave_count;
610 uint16_t slaves[RTE_MAX_ETHPORTS];
612 struct rte_eth_link link_status;
615 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
616 "Failed to stop bonded port %u",
617 test_params->bonded_port_id);
619 retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
620 TEST_ASSERT(retval >= 0,
621 "Bonded port (%d) link get failed: %s\n",
622 test_params->bonded_port_id, rte_strerror(-retval));
623 TEST_ASSERT_EQUAL(link_status.link_status, 0,
624 "Bonded port (%d) status (%d) is not expected value (%d).",
625 test_params->bonded_port_id, link_status.link_status, 0);
627 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
628 slaves, RTE_MAX_ETHPORTS);
629 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
630 "Number of slaves (%d) is not expected value (%d).",
631 current_slave_count, test_params->bonded_slave_count);
633 current_slave_count = rte_eth_bond_active_slaves_get(
634 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
635 TEST_ASSERT_EQUAL(current_slave_count, 0,
636 "Number of active slaves (%d) is not expected value (%d).",
637 current_slave_count, 0);
643 remove_slaves_and_stop_bonded_device(void)
645 /* Clean up and remove slaves from bonded device */
646 free_virtualpmd_tx_queue();
647 while (test_params->bonded_slave_count > 0)
648 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
649 "test_remove_slave_from_bonded_device failed");
651 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
652 "Failed to stop bonded port %u",
653 test_params->bonded_port_id);
655 rte_eth_stats_reset(test_params->bonded_port_id);
656 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
662 test_set_bonding_mode(void)
666 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
667 BONDING_MODE_ACTIVE_BACKUP,
668 BONDING_MODE_BALANCE,
669 BONDING_MODE_BROADCAST
672 /* Test supported link bonding modes */
673 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
674 /* Invalid port ID */
675 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
677 "Expected call to failed as invalid port (%d) specified.",
680 /* Non bonded device */
681 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
683 "Expected call to failed as invalid port (%d) specified.",
684 test_params->slave_port_ids[0]);
686 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
688 "Failed to set link bonding mode on port (%d) to (%d).",
689 test_params->bonded_port_id, bonding_modes[i]);
691 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
692 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
693 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
694 bonding_mode, test_params->bonded_port_id,
697 /* Invalid port ID */
698 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
699 TEST_ASSERT(bonding_mode < 0,
700 "Expected call to failed as invalid port (%d) specified.",
703 /* Non bonded device */
704 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
705 TEST_ASSERT(bonding_mode < 0,
706 "Expected call to failed as invalid port (%d) specified.",
707 test_params->slave_port_ids[0]);
710 return remove_slaves_and_stop_bonded_device();
714 test_set_primary_slave(void)
717 struct rte_ether_addr read_mac_addr;
718 struct rte_ether_addr *expected_mac_addr;
720 /* Add 4 slaves to bonded device */
721 for (i = test_params->bonded_slave_count; i < 4; i++)
722 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
723 "Failed to add slave to bonded device.");
725 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
726 BONDING_MODE_ROUND_ROBIN),
727 "Failed to set link bonding mode on port (%d) to (%d).",
728 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
730 /* Invalid port ID */
731 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
732 test_params->slave_port_ids[i]),
733 "Expected call to failed as invalid port specified.");
735 /* Non bonded device */
736 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
737 test_params->slave_port_ids[i]),
738 "Expected call to failed as invalid port specified.");
740 /* Set slave as primary
741 * Verify slave it is now primary slave
742 * Verify that MAC address of bonded device is that of primary slave
743 * Verify that MAC address of all bonded slaves are that of primary slave
745 for (i = 0; i < 4; i++) {
746 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
747 test_params->slave_port_ids[i]),
748 "Failed to set bonded port (%d) primary port to (%d)",
749 test_params->bonded_port_id, test_params->slave_port_ids[i]);
751 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
752 TEST_ASSERT(retval >= 0,
753 "Failed to read primary port from bonded port (%d)\n",
754 test_params->bonded_port_id);
756 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
757 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
758 test_params->bonded_port_id, retval,
759 test_params->slave_port_ids[i]);
761 /* stop/start bonded eth dev to apply new MAC */
762 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
763 "Failed to stop bonded port %u",
764 test_params->bonded_port_id);
766 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
767 "Failed to start bonded port %d",
768 test_params->bonded_port_id);
770 expected_mac_addr = (struct rte_ether_addr *)&slave_mac;
771 expected_mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
773 /* Check primary slave MAC */
774 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
775 "Failed to get mac address (port %d)",
776 test_params->slave_port_ids[i]);
777 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
778 sizeof(read_mac_addr)),
779 "bonded port mac address not set to that of primary port\n");
781 /* Check bonded MAC */
782 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
783 "Failed to get mac address (port %d)",
784 test_params->bonded_port_id);
785 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
786 sizeof(read_mac_addr)),
787 "bonded port mac address not set to that of primary port\n");
789 /* Check other slaves MACs */
790 for (j = 0; j < 4; j++) {
792 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[j],
794 "Failed to get mac address (port %d)",
795 test_params->slave_port_ids[j]);
796 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
797 sizeof(read_mac_addr)),
798 "slave port mac address not set to that of primary "
805 /* Test with none existent port */
806 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
807 "read primary port from expectedly");
809 /* Test with slave port */
810 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
811 "read primary port from expectedly\n");
813 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
814 "Failed to stop and remove slaves from bonded device");
817 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
818 "read primary port from expectedly\n");
824 test_set_explicit_bonded_mac(void)
827 struct rte_ether_addr read_mac_addr;
828 struct rte_ether_addr *mac_addr;
830 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
832 mac_addr = (struct rte_ether_addr *)explicit_bonded_mac;
834 /* Invalid port ID */
835 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
836 "Expected call to failed as invalid port specified.");
838 /* Non bonded device */
839 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
840 test_params->slave_port_ids[0], mac_addr),
841 "Expected call to failed as invalid port specified.");
843 /* NULL MAC address */
844 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
845 test_params->bonded_port_id, NULL),
846 "Expected call to failed as NULL MAC specified");
848 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
849 test_params->bonded_port_id, mac_addr),
850 "Failed to set MAC address on bonded port (%d)",
851 test_params->bonded_port_id);
853 /* Add 4 slaves to bonded device */
854 for (i = test_params->bonded_slave_count; i < 4; i++) {
855 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
856 "Failed to add slave to bonded device.\n");
859 /* Check bonded MAC */
860 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
861 "Failed to get mac address (port %d)",
862 test_params->bonded_port_id);
863 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
864 "bonded port mac address not set to that of primary port");
866 /* Check other slaves MACs */
867 for (i = 0; i < 4; i++) {
868 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
869 "Failed to get mac address (port %d)",
870 test_params->slave_port_ids[i]);
871 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
872 sizeof(read_mac_addr)),
873 "slave port mac address not set to that of primary port");
876 /* test resetting mac address on bonded device */
878 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
879 "Failed to reset MAC address on bonded port (%d)",
880 test_params->bonded_port_id);
883 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
884 "Reset MAC address on bonded port (%d) unexpectedly",
885 test_params->slave_port_ids[1]);
887 /* test resetting mac address on bonded device with no slaves */
888 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
889 "Failed to remove slaves and stop bonded device");
891 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
892 "Failed to reset MAC address on bonded port (%d)",
893 test_params->bonded_port_id);
898 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
901 test_set_bonded_port_initialization_mac_assignment(void)
905 uint16_t slaves[RTE_MAX_ETHPORTS];
906 static int bonded_port_id = -1;
907 static int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
909 struct rte_ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
911 /* Initialize default values for MAC addresses */
912 memcpy(&slave_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
913 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
916 * 1. a - Create / configure bonded / slave ethdevs
918 if (bonded_port_id == -1) {
919 bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
920 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
921 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
923 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
924 "Failed to configure bonded ethdev");
927 if (!mac_slaves_initialized) {
928 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
929 char pmd_name[RTE_ETH_NAME_MAX_LEN];
931 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] =
934 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN,
937 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
938 &slave_mac_addr, rte_socket_id(), 1);
940 TEST_ASSERT(slave_port_ids[i] >= 0,
941 "Failed to create slave ethdev %s",
944 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
945 "Failed to configure virtual ethdev %s",
948 mac_slaves_initialized = 1;
953 * 2. Add slave ethdevs to bonded device
955 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
956 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
958 "Failed to add slave (%d) to bonded port (%d).",
959 slave_port_ids[i], bonded_port_id);
962 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
964 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
965 "Number of slaves (%d) is not as expected (%d)",
966 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
970 * 3. Set explicit MAC address on bonded ethdev
972 bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-2] = 0xFF;
973 bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0xAA;
975 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
976 bonded_port_id, &bonded_mac_addr),
977 "Failed to set MAC address on bonded port (%d)",
981 /* 4. a - Start bonded ethdev
982 * b - Enable slave devices
983 * c - Verify bonded/slaves ethdev MAC addresses
985 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
986 "Failed to start bonded pmd eth device %d.",
989 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
990 virtual_ethdev_simulate_link_status_interrupt(
991 slave_port_ids[i], 1);
994 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(bonded_port_id, &read_mac_addr),
995 "Failed to get mac address (port %d)",
997 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
998 sizeof(read_mac_addr)),
999 "bonded port mac address not as expected");
1001 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1002 "Failed to get mac address (port %d)",
1004 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1005 sizeof(read_mac_addr)),
1006 "slave port 0 mac address not as expected");
1008 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1009 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1010 "Failed to get mac address (port %d)",
1012 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1013 sizeof(read_mac_addr)),
1014 "slave port 1 mac address not as expected");
1016 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1017 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1018 "Failed to get mac address (port %d)",
1020 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1021 sizeof(read_mac_addr)),
1022 "slave port 2 mac address not as expected");
1025 /* 7. a - Change primary port
1026 * b - Stop / Start bonded port
1027 * d - Verify slave ethdev MAC addresses
1029 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1031 "failed to set primary port on bonded device.");
1033 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(bonded_port_id),
1034 "Failed to stop bonded port %u",
1037 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1038 "Failed to start bonded pmd eth device %d.",
1041 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(bonded_port_id, &read_mac_addr),
1042 "Failed to get mac address (port %d)",
1044 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1045 sizeof(read_mac_addr)),
1046 "bonded port mac address not as expected");
1048 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1049 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1050 "Failed to get mac address (port %d)",
1052 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1053 sizeof(read_mac_addr)),
1054 "slave port 0 mac address not as expected");
1056 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1057 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1058 "Failed to get mac address (port %d)",
1060 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1061 sizeof(read_mac_addr)),
1062 "slave port 1 mac address not as expected");
1064 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1065 "Failed to get mac address (port %d)",
1067 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1068 sizeof(read_mac_addr)),
1069 "slave port 2 mac address not as expected");
1071 /* 6. a - Stop bonded ethdev
1072 * b - remove slave ethdevs
1073 * c - Verify slave ethdevs MACs are restored
1075 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(bonded_port_id),
1076 "Failed to stop bonded port %u",
1079 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1080 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1082 "Failed to remove slave %d from bonded port (%d).",
1083 slave_port_ids[i], bonded_port_id);
1086 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1089 TEST_ASSERT_EQUAL(slave_count, 0,
1090 "Number of slaves (%d) is great than expected (%d).",
1093 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1094 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1095 "Failed to get mac address (port %d)",
1097 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1098 sizeof(read_mac_addr)),
1099 "slave port 0 mac address not as expected");
1101 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1102 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1103 "Failed to get mac address (port %d)",
1105 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1106 sizeof(read_mac_addr)),
1107 "slave port 1 mac address not as expected");
1109 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1110 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1111 "Failed to get mac address (port %d)",
1113 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1114 sizeof(read_mac_addr)),
1115 "slave port 2 mac address not as expected");
1122 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1123 uint16_t number_of_slaves, uint8_t enable_slave)
1125 /* Configure bonded device */
1126 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1127 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1128 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1131 /* Add slaves to bonded device */
1132 while (number_of_slaves > test_params->bonded_slave_count)
1133 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1134 "Failed to add slave (%d to bonding port (%d).",
1135 test_params->bonded_slave_count - 1,
1136 test_params->bonded_port_id);
1138 /* Set link bonding mode */
1139 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1141 "Failed to set link bonding mode on port (%d) to (%d).",
1142 test_params->bonded_port_id, bonding_mode);
1144 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1145 "Failed to start bonded pmd eth device %d.",
1146 test_params->bonded_port_id);
1149 enable_bonded_slaves();
1155 test_adding_slave_after_bonded_device_started(void)
1159 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1160 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1161 "Failed to add slaves to bonded device");
1163 /* Enabled slave devices */
1164 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1165 virtual_ethdev_simulate_link_status_interrupt(
1166 test_params->slave_port_ids[i], 1);
1169 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1170 test_params->slave_port_ids[test_params->bonded_slave_count]),
1171 "Failed to add slave to bonded port.\n");
1173 rte_eth_stats_reset(
1174 test_params->slave_port_ids[test_params->bonded_slave_count]);
1176 test_params->bonded_slave_count++;
1178 return remove_slaves_and_stop_bonded_device();
1181 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1182 #define TEST_LSC_WAIT_TIMEOUT_US 500000
1184 int test_lsc_interrupt_count;
1188 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1189 enum rte_eth_event_type type __rte_unused,
1190 void *param __rte_unused,
1191 void *ret_param __rte_unused)
1193 pthread_mutex_lock(&mutex);
1194 test_lsc_interrupt_count++;
1196 pthread_cond_signal(&cvar);
1197 pthread_mutex_unlock(&mutex);
1203 lsc_timeout(int wait_us)
1210 gettimeofday(&tp, NULL);
1212 /* Convert from timeval to timespec */
1213 ts.tv_sec = tp.tv_sec;
1214 ts.tv_nsec = tp.tv_usec * 1000;
1215 ts.tv_nsec += wait_us * 1000;
1216 /* Normalize tv_nsec to [0,999999999L] */
1217 while (ts.tv_nsec > 1000000000L) {
1218 ts.tv_nsec -= 1000000000L;
1222 pthread_mutex_lock(&mutex);
1223 if (test_lsc_interrupt_count < 1)
1224 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1226 pthread_mutex_unlock(&mutex);
1228 if (retval == 0 && test_lsc_interrupt_count < 1)
1235 test_status_interrupt(void)
1238 uint16_t slaves[RTE_MAX_ETHPORTS];
1240 /* initialized bonding device with T slaves */
1241 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1242 BONDING_MODE_ROUND_ROBIN, 1,
1243 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1244 "Failed to initialise bonded device");
1246 test_lsc_interrupt_count = 0;
1248 /* register link status change interrupt callback */
1249 rte_eth_dev_callback_register(test_params->bonded_port_id,
1250 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1251 &test_params->bonded_port_id);
1253 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1254 slaves, RTE_MAX_ETHPORTS);
1256 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1257 "Number of active slaves (%d) is not as expected (%d)",
1258 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1260 /* Bring all 4 slaves link status to down and test that we have received a
1262 virtual_ethdev_simulate_link_status_interrupt(
1263 test_params->slave_port_ids[0], 0);
1264 virtual_ethdev_simulate_link_status_interrupt(
1265 test_params->slave_port_ids[1], 0);
1266 virtual_ethdev_simulate_link_status_interrupt(
1267 test_params->slave_port_ids[2], 0);
1269 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1270 "Received a link status change interrupt unexpectedly");
1272 virtual_ethdev_simulate_link_status_interrupt(
1273 test_params->slave_port_ids[3], 0);
1275 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) == 0,
1276 "timed out waiting for interrupt");
1278 TEST_ASSERT(test_lsc_interrupt_count > 0,
1279 "Did not receive link status change interrupt");
1281 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1282 slaves, RTE_MAX_ETHPORTS);
1284 TEST_ASSERT_EQUAL(slave_count, 0,
1285 "Number of active slaves (%d) is not as expected (%d)",
1288 /* bring one slave port up so link status will change */
1289 test_lsc_interrupt_count = 0;
1291 virtual_ethdev_simulate_link_status_interrupt(
1292 test_params->slave_port_ids[0], 1);
1294 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) == 0,
1295 "timed out waiting for interrupt");
1297 /* test that we have received another lsc interrupt */
1298 TEST_ASSERT(test_lsc_interrupt_count > 0,
1299 "Did not receive link status change interrupt");
1301 /* Verify that calling the same slave lsc interrupt doesn't cause another
1302 * lsc interrupt from bonded device */
1303 test_lsc_interrupt_count = 0;
1305 virtual_ethdev_simulate_link_status_interrupt(
1306 test_params->slave_port_ids[0], 1);
1308 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) != 0,
1309 "received unexpected interrupt");
1311 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1312 "Did not receive link status change interrupt");
1315 /* unregister lsc callback before exiting */
1316 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1317 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1318 &test_params->bonded_port_id);
1320 /* Clean up and remove slaves from bonded device */
1321 return remove_slaves_and_stop_bonded_device();
1325 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1326 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1327 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1329 uint16_t pktlen, generated_burst_size, ether_type;
1333 ether_type = RTE_ETHER_TYPE_IPV4;
1335 ether_type = RTE_ETHER_TYPE_IPV6;
1338 initialize_eth_header(test_params->pkt_eth_hdr,
1339 (struct rte_ether_addr *)src_mac,
1340 (struct rte_ether_addr *)dst_mac_1,
1341 ether_type, vlan, vlan_id);
1343 initialize_eth_header(test_params->pkt_eth_hdr,
1344 (struct rte_ether_addr *)src_mac,
1345 (struct rte_ether_addr *)dst_mac_0,
1346 ether_type, vlan, vlan_id);
1349 if (toggle_udp_port)
1350 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1353 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1358 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1359 dst_addr_1, pktlen);
1361 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1362 dst_addr_0, pktlen);
1364 ip_hdr = test_params->pkt_ipv4_hdr;
1367 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1368 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1371 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1372 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1375 ip_hdr = test_params->pkt_ipv6_hdr;
1378 /* Generate burst of packets to transmit */
1379 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1380 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1381 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1383 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1384 "Failed to generate packet burst");
1386 return generated_burst_size;
1389 /** Round Robin Mode Tests */
1392 test_roundrobin_tx_burst(void)
1395 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1396 struct rte_eth_stats port_stats;
1398 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1399 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1400 "Failed to initialise bonded device");
1402 burst_size = 20 * test_params->bonded_slave_count;
1404 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1405 "Burst size specified is greater than supported.");
1407 /* Generate test bursts of packets to transmit */
1408 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1409 burst_size, "failed to generate test burst");
1411 /* Send burst on bonded port */
1412 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1413 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1416 /* Verify bonded port tx stats */
1417 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1418 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1419 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1420 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1423 /* Verify slave ports tx stats */
1424 for (i = 0; i < test_params->bonded_slave_count; i++) {
1425 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1426 TEST_ASSERT_EQUAL(port_stats.opackets,
1427 (uint64_t)burst_size / test_params->bonded_slave_count,
1428 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1429 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1430 burst_size / test_params->bonded_slave_count);
1433 /* Put all slaves down and try and transmit */
1434 for (i = 0; i < test_params->bonded_slave_count; i++) {
1435 virtual_ethdev_simulate_link_status_interrupt(
1436 test_params->slave_port_ids[i], 0);
1439 /* Send burst on bonded port */
1440 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1441 pkt_burst, burst_size), 0,
1442 "tx burst return unexpected value");
1444 /* Clean up and remove slaves from bonded device */
1445 return remove_slaves_and_stop_bonded_device();
1449 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1453 for (i = 0; i < nb_mbufs; i++) {
1454 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1455 TEST_ASSERT_EQUAL(refcnt, val,
1456 "mbuf ref count (%d)is not the expected value (%d)",
1463 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1467 for (i = 0; i < nb_mbufs; i++)
1468 rte_pktmbuf_free(mbufs[i]);
1471 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1472 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1473 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1474 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1477 test_roundrobin_tx_burst_slave_tx_fail(void)
1479 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1480 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1482 struct rte_eth_stats port_stats;
1484 int i, first_fail_idx, tx_count;
1486 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1487 BONDING_MODE_ROUND_ROBIN, 0,
1488 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1489 "Failed to initialise bonded device");
1491 /* Generate test bursts of packets to transmit */
1492 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1493 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1494 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1495 "Failed to generate test packet burst");
1497 /* Copy references to packets which we expect not to be transmitted */
1498 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1499 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1500 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1501 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1503 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1504 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1505 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1508 /* Set virtual slave to only fail transmission of
1509 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1510 virtual_ethdev_tx_burst_fn_set_success(
1511 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1514 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1515 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1516 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1518 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1519 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1521 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1522 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1523 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1524 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1525 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1527 /* Verify that failed packet are expected failed packets */
1528 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1529 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1530 "expected mbuf (%d) pointer %p not expected pointer %p",
1531 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1534 /* Verify bonded port tx stats */
1535 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1537 TEST_ASSERT_EQUAL(port_stats.opackets,
1538 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1539 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1540 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1541 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1542 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1543 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1545 /* Verify slave ports tx stats */
1546 for (i = 0; i < test_params->bonded_slave_count; i++) {
1547 int slave_expected_tx_count;
1549 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1551 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1552 test_params->bonded_slave_count;
1554 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1555 slave_expected_tx_count = slave_expected_tx_count -
1556 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1558 TEST_ASSERT_EQUAL(port_stats.opackets,
1559 (uint64_t)slave_expected_tx_count,
1560 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1561 test_params->slave_port_ids[i],
1562 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1565 /* Verify that all mbufs have a ref value of zero */
1566 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1567 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1568 "mbufs refcnts not as expected");
1569 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1571 /* Clean up and remove slaves from bonded device */
1572 return remove_slaves_and_stop_bonded_device();
1576 test_roundrobin_rx_burst_on_single_slave(void)
1578 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1579 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1581 struct rte_eth_stats port_stats;
1583 int i, j, burst_size = 25;
1585 /* Initialize bonded device with 4 slaves in round robin mode */
1586 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1587 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1588 "Failed to initialize bonded device with slaves");
1590 /* Generate test bursts of packets to transmit */
1591 TEST_ASSERT_EQUAL(generate_test_burst(
1592 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1593 "burst generation failed");
1595 for (i = 0; i < test_params->bonded_slave_count; i++) {
1596 /* Add rx data to slave */
1597 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1598 &gen_pkt_burst[0], burst_size);
1600 /* Call rx burst on bonded device */
1601 /* Send burst on bonded port */
1602 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1603 test_params->bonded_port_id, 0, rx_pkt_burst,
1604 MAX_PKT_BURST), burst_size,
1605 "round-robin rx burst failed");
1607 /* Verify bonded device rx count */
1608 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1609 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1610 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1611 test_params->bonded_port_id,
1612 (unsigned int)port_stats.ipackets, burst_size);
1616 /* Verify bonded slave devices rx count */
1617 /* Verify slave ports tx stats */
1618 for (j = 0; j < test_params->bonded_slave_count; j++) {
1619 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1622 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1623 "Slave Port (%d) ipackets value (%u) not as expected"
1624 " (%d)", test_params->slave_port_ids[i],
1625 (unsigned int)port_stats.ipackets, burst_size);
1627 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1628 "Slave Port (%d) ipackets value (%u) not as expected"
1629 " (%d)", test_params->slave_port_ids[i],
1630 (unsigned int)port_stats.ipackets, 0);
1633 /* Reset bonded slaves stats */
1634 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1636 /* reset bonded device stats */
1637 rte_eth_stats_reset(test_params->bonded_port_id);
1641 for (i = 0; i < MAX_PKT_BURST; i++) {
1642 if (rx_pkt_burst[i] != NULL)
1643 rte_pktmbuf_free(rx_pkt_burst[i]);
1647 /* Clean up and remove slaves from bonded device */
1648 return remove_slaves_and_stop_bonded_device();
1651 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1654 test_roundrobin_rx_burst_on_multiple_slaves(void)
1656 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1658 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1659 struct rte_eth_stats port_stats;
1661 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1664 /* Initialize bonded device with 4 slaves in round robin mode */
1665 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1666 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1667 "Failed to initialize bonded device with slaves");
1669 /* Generate test bursts of packets to transmit */
1670 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1671 TEST_ASSERT_EQUAL(generate_test_burst(
1672 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1673 burst_size[i], "burst generation failed");
1676 /* Add rx data to slaves */
1677 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1678 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1679 &gen_pkt_burst[i][0], burst_size[i]);
1682 /* Call rx burst on bonded device */
1683 /* Send burst on bonded port */
1684 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1686 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1687 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1688 burst_size[0] + burst_size[1] + burst_size[2]);
1690 /* Verify bonded device rx count */
1691 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1692 TEST_ASSERT_EQUAL(port_stats.ipackets,
1693 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1694 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1695 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1696 burst_size[0] + burst_size[1] + burst_size[2]);
1698 /* Verify bonded slave devices rx counts */
1699 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1700 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1701 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1702 test_params->slave_port_ids[0],
1703 (unsigned int)port_stats.ipackets, burst_size[0]);
1705 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1706 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1707 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1708 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1711 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1712 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1713 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1714 test_params->slave_port_ids[2],
1715 (unsigned int)port_stats.ipackets, burst_size[2]);
1717 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1718 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1719 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1720 test_params->slave_port_ids[3],
1721 (unsigned int)port_stats.ipackets, 0);
1724 for (i = 0; i < MAX_PKT_BURST; i++) {
1725 if (rx_pkt_burst[i] != NULL)
1726 rte_pktmbuf_free(rx_pkt_burst[i]);
1729 /* Clean up and remove slaves from bonded device */
1730 return remove_slaves_and_stop_bonded_device();
1734 test_roundrobin_verify_mac_assignment(void)
1736 struct rte_ether_addr read_mac_addr;
1737 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_2;
1741 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
1742 "Failed to get mac address (port %d)",
1743 test_params->slave_port_ids[0]);
1744 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2),
1745 "Failed to get mac address (port %d)",
1746 test_params->slave_port_ids[2]);
1748 /* Initialize bonded device with 4 slaves in round robin mode */
1749 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1750 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1751 "Failed to initialize bonded device with slaves");
1753 /* Verify that all MACs are the same as first slave added to bonded dev */
1754 for (i = 0; i < test_params->bonded_slave_count; i++) {
1755 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1756 "Failed to get mac address (port %d)",
1757 test_params->slave_port_ids[i]);
1758 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1759 sizeof(read_mac_addr)),
1760 "slave port (%d) mac address not set to that of primary port",
1761 test_params->slave_port_ids[i]);
1764 /* change primary and verify that MAC addresses haven't changed */
1765 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1766 test_params->slave_port_ids[2]),
1767 "Failed to set bonded port (%d) primary port to (%d)",
1768 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1770 for (i = 0; i < test_params->bonded_slave_count; i++) {
1771 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1772 "Failed to get mac address (port %d)",
1773 test_params->slave_port_ids[i]);
1774 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1775 sizeof(read_mac_addr)),
1776 "slave port (%d) mac address has changed to that of primary"
1777 " port without stop/start toggle of bonded device",
1778 test_params->slave_port_ids[i]);
1781 /* stop / start bonded device and verify that primary MAC address is
1782 * propagate to bonded device and slaves */
1783 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
1784 "Failed to stop bonded port %u",
1785 test_params->bonded_port_id);
1787 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1788 "Failed to start bonded device");
1790 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1791 "Failed to get mac address (port %d)",
1792 test_params->bonded_port_id);
1793 TEST_ASSERT_SUCCESS(
1794 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1795 "bonded port (%d) mac address not set to that of new primary port",
1796 test_params->slave_port_ids[i]);
1798 for (i = 0; i < test_params->bonded_slave_count; i++) {
1799 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1800 "Failed to get mac address (port %d)",
1801 test_params->slave_port_ids[i]);
1802 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1803 sizeof(read_mac_addr)),
1804 "slave port (%d) mac address not set to that of new primary"
1805 " port", test_params->slave_port_ids[i]);
1808 /* Set explicit MAC address */
1809 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1810 test_params->bonded_port_id,
1811 (struct rte_ether_addr *)bonded_mac),
1812 "Failed to set MAC");
1814 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1815 "Failed to get mac address (port %d)",
1816 test_params->bonded_port_id);
1817 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1818 sizeof(read_mac_addr)),
1819 "bonded port (%d) mac address not set to that of new primary port",
1820 test_params->slave_port_ids[i]);
1822 for (i = 0; i < test_params->bonded_slave_count; i++) {
1823 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1824 "Failed to get mac address (port %d)",
1825 test_params->slave_port_ids[i]);
1826 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1827 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1828 " that of new primary port\n", test_params->slave_port_ids[i]);
1831 /* Clean up and remove slaves from bonded device */
1832 return remove_slaves_and_stop_bonded_device();
1836 test_roundrobin_verify_promiscuous_enable_disable(void)
1838 int i, promiscuous_en;
1841 /* Initialize bonded device with 4 slaves in round robin mode */
1842 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1843 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1844 "Failed to initialize bonded device with slaves");
1846 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
1847 TEST_ASSERT_SUCCESS(ret,
1848 "Failed to enable promiscuous mode for port %d: %s",
1849 test_params->bonded_port_id, rte_strerror(-ret));
1851 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1852 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1853 "Port (%d) promiscuous mode not enabled",
1854 test_params->bonded_port_id);
1856 for (i = 0; i < test_params->bonded_slave_count; i++) {
1857 promiscuous_en = rte_eth_promiscuous_get(
1858 test_params->slave_port_ids[i]);
1859 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1860 "slave port (%d) promiscuous mode not enabled",
1861 test_params->slave_port_ids[i]);
1864 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
1865 TEST_ASSERT_SUCCESS(ret,
1866 "Failed to disable promiscuous mode for port %d: %s",
1867 test_params->bonded_port_id, rte_strerror(-ret));
1869 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1870 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1871 "Port (%d) promiscuous mode not disabled\n",
1872 test_params->bonded_port_id);
1874 for (i = 0; i < test_params->bonded_slave_count; i++) {
1875 promiscuous_en = rte_eth_promiscuous_get(
1876 test_params->slave_port_ids[i]);
1877 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1878 "Port (%d) promiscuous mode not disabled\n",
1879 test_params->slave_port_ids[i]);
1882 /* Clean up and remove slaves from bonded device */
1883 return remove_slaves_and_stop_bonded_device();
1886 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1887 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1890 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1892 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1893 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1894 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1896 struct rte_eth_stats port_stats;
1897 uint16_t slaves[RTE_MAX_ETHPORTS];
1899 int i, burst_size, slave_count;
1901 /* NULL all pointers in array to simplify cleanup */
1902 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1904 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1905 * in round robin mode */
1906 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1907 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1908 "Failed to initialize bonded device with slaves");
1910 /* Verify Current Slaves Count /Active Slave Count is */
1911 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1913 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1914 "Number of slaves (%d) is not as expected (%d).",
1915 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1917 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1918 slaves, RTE_MAX_ETHPORTS);
1919 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1920 "Number of active slaves (%d) is not as expected (%d).",
1921 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1923 /* Set 2 slaves eth_devs link status to down */
1924 virtual_ethdev_simulate_link_status_interrupt(
1925 test_params->slave_port_ids[1], 0);
1926 virtual_ethdev_simulate_link_status_interrupt(
1927 test_params->slave_port_ids[3], 0);
1929 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1930 slaves, RTE_MAX_ETHPORTS);
1931 TEST_ASSERT_EQUAL(slave_count,
1932 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1933 "Number of active slaves (%d) is not as expected (%d).\n",
1934 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1938 /* Verify that pkts are not sent on slaves with link status down:
1940 * 1. Generate test burst of traffic
1941 * 2. Transmit burst on bonded eth_dev
1942 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1943 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1946 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1947 burst_size, "generate_test_burst failed");
1949 rte_eth_stats_reset(test_params->bonded_port_id);
1953 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1954 burst_size), burst_size, "rte_eth_tx_burst failed");
1956 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1957 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1958 "Port (%d) opackets stats (%d) not expected (%d) value",
1959 test_params->bonded_port_id, (int)port_stats.opackets,
1962 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1963 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1964 "Port (%d) opackets stats (%d) not expected (%d) value",
1965 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1967 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1968 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1969 "Port (%d) opackets stats (%d) not expected (%d) value",
1970 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1972 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1973 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1974 "Port (%d) opackets stats (%d) not expected (%d) value",
1975 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1977 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1978 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1979 "Port (%d) opackets stats (%d) not expected (%d) value",
1980 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1982 /* Verify that pkts are not sent on slaves with link status down:
1984 * 1. Generate test bursts of traffic
1985 * 2. Add bursts on to virtual eth_devs
1986 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1987 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1988 * 4. Verify stats for bonded eth_dev
1989 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1991 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1992 TEST_ASSERT_EQUAL(generate_test_burst(
1993 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1994 burst_size, "failed to generate packet burst");
1996 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1997 &gen_pkt_burst[i][0], burst_size);
2000 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2001 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2002 burst_size + burst_size,
2003 "rte_eth_rx_burst failed");
2005 /* Verify bonded device rx count */
2006 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2007 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
2008 "(%d) port_stats.ipackets not as expected\n",
2009 test_params->bonded_port_id);
2012 for (i = 0; i < MAX_PKT_BURST; i++) {
2013 if (rx_pkt_burst[i] != NULL)
2014 rte_pktmbuf_free(rx_pkt_burst[i]);
2017 /* Clean up and remove slaves from bonded device */
2018 return remove_slaves_and_stop_bonded_device();
2021 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
2023 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
2026 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2029 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2031 struct rte_ether_addr *mac_addr =
2032 (struct rte_ether_addr *)polling_slave_mac;
2033 char slave_name[RTE_ETH_NAME_MAX_LEN];
2037 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2038 /* Generate slave name / MAC address */
2039 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2040 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
2042 /* Create slave devices with no ISR Support */
2043 if (polling_test_slaves[i] == -1) {
2044 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2045 rte_socket_id(), 0);
2046 TEST_ASSERT(polling_test_slaves[i] >= 0,
2047 "Failed to create virtual virtual ethdev %s\n", slave_name);
2049 /* Configure slave */
2050 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2051 "Failed to configure virtual ethdev %s(%d)", slave_name,
2052 polling_test_slaves[i]);
2055 /* Add slave to bonded device */
2056 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2057 polling_test_slaves[i]),
2058 "Failed to add slave %s(%d) to bonded device %d",
2059 slave_name, polling_test_slaves[i],
2060 test_params->bonded_port_id);
2063 /* Initialize bonded device */
2064 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2065 "Failed to configure bonded device %d",
2066 test_params->bonded_port_id);
2069 /* Register link status change interrupt callback */
2070 rte_eth_dev_callback_register(test_params->bonded_port_id,
2071 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2072 &test_params->bonded_port_id);
2074 /* link status change callback for first slave link up */
2075 test_lsc_interrupt_count = 0;
2077 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2079 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2082 /* no link status change callback for second slave link up */
2083 test_lsc_interrupt_count = 0;
2085 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2087 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2089 /* link status change callback for both slave links down */
2090 test_lsc_interrupt_count = 0;
2092 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2093 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2095 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2097 /* Un-Register link status change interrupt callback */
2098 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2099 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2100 &test_params->bonded_port_id);
2103 /* Clean up and remove slaves from bonded device */
2104 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2106 TEST_ASSERT_SUCCESS(
2107 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2108 polling_test_slaves[i]),
2109 "Failed to remove slave %d from bonded port (%d)",
2110 polling_test_slaves[i], test_params->bonded_port_id);
2113 return remove_slaves_and_stop_bonded_device();
2117 /** Active Backup Mode Tests */
2120 test_activebackup_tx_burst(void)
2122 int i, pktlen, primary_port, burst_size;
2123 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2124 struct rte_eth_stats port_stats;
2126 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2127 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2128 "Failed to initialize bonded device with slaves");
2130 initialize_eth_header(test_params->pkt_eth_hdr,
2131 (struct rte_ether_addr *)src_mac,
2132 (struct rte_ether_addr *)dst_mac_0,
2133 RTE_ETHER_TYPE_IPV4, 0, 0);
2134 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2136 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2137 dst_addr_0, pktlen);
2139 burst_size = 20 * test_params->bonded_slave_count;
2141 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2142 "Burst size specified is greater than supported.");
2144 /* Generate a burst of packets to transmit */
2145 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2146 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2147 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2148 burst_size, "failed to generate burst correctly");
2150 /* Send burst on bonded port */
2151 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2152 burst_size), burst_size, "tx burst failed");
2154 /* Verify bonded port tx stats */
2155 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2156 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2157 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2158 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2161 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2163 /* Verify slave ports tx stats */
2164 for (i = 0; i < test_params->bonded_slave_count; i++) {
2165 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2166 if (test_params->slave_port_ids[i] == primary_port) {
2167 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2168 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2169 test_params->bonded_port_id,
2170 (unsigned int)port_stats.opackets,
2171 burst_size / test_params->bonded_slave_count);
2173 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2174 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2175 test_params->bonded_port_id,
2176 (unsigned int)port_stats.opackets, 0);
2180 /* Put all slaves down and try and transmit */
2181 for (i = 0; i < test_params->bonded_slave_count; i++) {
2182 virtual_ethdev_simulate_link_status_interrupt(
2183 test_params->slave_port_ids[i], 0);
2186 /* Send burst on bonded port */
2187 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2188 pkts_burst, burst_size), 0, "Sending empty burst failed");
2190 /* Clean up and remove slaves from bonded device */
2191 return remove_slaves_and_stop_bonded_device();
2194 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2197 test_activebackup_rx_burst(void)
2199 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2200 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2202 struct rte_eth_stats port_stats;
2206 int i, j, burst_size = 17;
2208 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2209 BONDING_MODE_ACTIVE_BACKUP, 0,
2210 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2211 "Failed to initialize bonded device with slaves");
2213 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2214 TEST_ASSERT(primary_port >= 0,
2215 "failed to get primary slave for bonded port (%d)",
2216 test_params->bonded_port_id);
2218 for (i = 0; i < test_params->bonded_slave_count; i++) {
2219 /* Generate test bursts of packets to transmit */
2220 TEST_ASSERT_EQUAL(generate_test_burst(
2221 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2222 burst_size, "burst generation failed");
2224 /* Add rx data to slave */
2225 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2226 &gen_pkt_burst[0], burst_size);
2228 /* Call rx burst on bonded device */
2229 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2230 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2231 "rte_eth_rx_burst failed");
2233 if (test_params->slave_port_ids[i] == primary_port) {
2234 /* Verify bonded device rx count */
2235 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2236 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2237 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2238 test_params->bonded_port_id,
2239 (unsigned int)port_stats.ipackets, burst_size);
2241 /* Verify bonded slave devices rx count */
2242 for (j = 0; j < test_params->bonded_slave_count; j++) {
2243 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2245 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2246 "Slave Port (%d) ipackets value (%u) not as "
2247 "expected (%d)", test_params->slave_port_ids[i],
2248 (unsigned int)port_stats.ipackets, burst_size);
2250 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2251 "Slave Port (%d) ipackets value (%u) not as "
2252 "expected (%d)\n", test_params->slave_port_ids[i],
2253 (unsigned int)port_stats.ipackets, 0);
2257 for (j = 0; j < test_params->bonded_slave_count; j++) {
2258 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2259 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2260 "Slave Port (%d) ipackets value (%u) not as expected "
2261 "(%d)", test_params->slave_port_ids[i],
2262 (unsigned int)port_stats.ipackets, 0);
2267 for (i = 0; i < MAX_PKT_BURST; i++) {
2268 if (rx_pkt_burst[i] != NULL) {
2269 rte_pktmbuf_free(rx_pkt_burst[i]);
2270 rx_pkt_burst[i] = NULL;
2274 /* reset bonded device stats */
2275 rte_eth_stats_reset(test_params->bonded_port_id);
2278 /* Clean up and remove slaves from bonded device */
2279 return remove_slaves_and_stop_bonded_device();
2283 test_activebackup_verify_promiscuous_enable_disable(void)
2285 int i, primary_port, promiscuous_en;
2288 /* Initialize bonded device with 4 slaves in round robin mode */
2289 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2290 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2291 "Failed to initialize bonded device with slaves");
2293 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2294 TEST_ASSERT(primary_port >= 0,
2295 "failed to get primary slave for bonded port (%d)",
2296 test_params->bonded_port_id);
2298 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
2299 TEST_ASSERT_SUCCESS(ret,
2300 "Failed to enable promiscuous mode for port %d: %s",
2301 test_params->bonded_port_id, rte_strerror(-ret));
2303 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2304 "Port (%d) promiscuous mode not enabled",
2305 test_params->bonded_port_id);
2307 for (i = 0; i < test_params->bonded_slave_count; i++) {
2308 promiscuous_en = rte_eth_promiscuous_get(
2309 test_params->slave_port_ids[i]);
2310 if (primary_port == test_params->slave_port_ids[i]) {
2311 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2312 "slave port (%d) promiscuous mode not enabled",
2313 test_params->slave_port_ids[i]);
2315 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2316 "slave port (%d) promiscuous mode enabled",
2317 test_params->slave_port_ids[i]);
2322 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
2323 TEST_ASSERT_SUCCESS(ret,
2324 "Failed to disable promiscuous mode for port %d: %s",
2325 test_params->bonded_port_id, rte_strerror(-ret));
2327 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2328 "Port (%d) promiscuous mode not disabled\n",
2329 test_params->bonded_port_id);
2331 for (i = 0; i < test_params->bonded_slave_count; i++) {
2332 promiscuous_en = rte_eth_promiscuous_get(
2333 test_params->slave_port_ids[i]);
2334 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2335 "slave port (%d) promiscuous mode not disabled\n",
2336 test_params->slave_port_ids[i]);
2339 /* Clean up and remove slaves from bonded device */
2340 return remove_slaves_and_stop_bonded_device();
2344 test_activebackup_verify_mac_assignment(void)
2346 struct rte_ether_addr read_mac_addr;
2347 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
2349 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
2350 "Failed to get mac address (port %d)",
2351 test_params->slave_port_ids[0]);
2352 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
2353 "Failed to get mac address (port %d)",
2354 test_params->slave_port_ids[1]);
2356 /* Initialize bonded device with 2 slaves in active backup mode */
2357 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2358 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2359 "Failed to initialize bonded device with slaves");
2361 /* Verify that bonded MACs is that of first slave and that the other slave
2362 * MAC hasn't been changed */
2363 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2364 "Failed to get mac address (port %d)",
2365 test_params->bonded_port_id);
2366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2367 sizeof(read_mac_addr)),
2368 "bonded port (%d) mac address not set to that of primary port",
2369 test_params->bonded_port_id);
2371 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2372 "Failed to get mac address (port %d)",
2373 test_params->slave_port_ids[0]);
2374 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2375 sizeof(read_mac_addr)),
2376 "slave port (%d) mac address not set to that of primary port",
2377 test_params->slave_port_ids[0]);
2379 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2380 "Failed to get mac address (port %d)",
2381 test_params->slave_port_ids[1]);
2382 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2383 sizeof(read_mac_addr)),
2384 "slave port (%d) mac address not as expected",
2385 test_params->slave_port_ids[1]);
2387 /* change primary and verify that MAC addresses haven't changed */
2388 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2389 test_params->slave_port_ids[1]), 0,
2390 "Failed to set bonded port (%d) primary port to (%d)",
2391 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2393 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2394 "Failed to get mac address (port %d)",
2395 test_params->bonded_port_id);
2396 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2397 sizeof(read_mac_addr)),
2398 "bonded port (%d) mac address not set to that of primary port",
2399 test_params->bonded_port_id);
2401 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2402 "Failed to get mac address (port %d)",
2403 test_params->slave_port_ids[0]);
2404 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2405 sizeof(read_mac_addr)),
2406 "slave port (%d) mac address not set to that of primary port",
2407 test_params->slave_port_ids[0]);
2409 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2410 "Failed to get mac address (port %d)",
2411 test_params->slave_port_ids[1]);
2412 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2413 sizeof(read_mac_addr)),
2414 "slave port (%d) mac address not as expected",
2415 test_params->slave_port_ids[1]);
2417 /* stop / start bonded device and verify that primary MAC address is
2418 * propagated to bonded device and slaves */
2420 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
2421 "Failed to stop bonded port %u",
2422 test_params->bonded_port_id);
2424 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2425 "Failed to start device");
2427 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2428 "Failed to get mac address (port %d)",
2429 test_params->bonded_port_id);
2430 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2431 sizeof(read_mac_addr)),
2432 "bonded port (%d) mac address not set to that of primary port",
2433 test_params->bonded_port_id);
2435 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2436 "Failed to get mac address (port %d)",
2437 test_params->slave_port_ids[0]);
2438 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2439 sizeof(read_mac_addr)),
2440 "slave port (%d) mac address not as expected",
2441 test_params->slave_port_ids[0]);
2443 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2444 "Failed to get mac address (port %d)",
2445 test_params->slave_port_ids[1]);
2446 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2447 sizeof(read_mac_addr)),
2448 "slave port (%d) mac address not set to that of primary port",
2449 test_params->slave_port_ids[1]);
2451 /* Set explicit MAC address */
2452 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2453 test_params->bonded_port_id,
2454 (struct rte_ether_addr *)bonded_mac),
2455 "failed to set MAC address");
2457 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2458 "Failed to get mac address (port %d)",
2459 test_params->bonded_port_id);
2460 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2461 sizeof(read_mac_addr)),
2462 "bonded port (%d) mac address not set to that of bonded port",
2463 test_params->bonded_port_id);
2465 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2466 "Failed to get mac address (port %d)",
2467 test_params->slave_port_ids[0]);
2468 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2469 sizeof(read_mac_addr)),
2470 "slave port (%d) mac address not as expected",
2471 test_params->slave_port_ids[0]);
2473 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2474 "Failed to get mac address (port %d)",
2475 test_params->slave_port_ids[1]);
2476 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2477 sizeof(read_mac_addr)),
2478 "slave port (%d) mac address not set to that of bonded port",
2479 test_params->slave_port_ids[1]);
2481 /* Clean up and remove slaves from bonded device */
2482 return remove_slaves_and_stop_bonded_device();
2486 test_activebackup_verify_slave_link_status_change_failover(void)
2488 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2489 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2490 struct rte_eth_stats port_stats;
2492 uint16_t slaves[RTE_MAX_ETHPORTS];
2494 int i, burst_size, slave_count, primary_port;
2498 memset(pkt_burst, 0, sizeof(pkt_burst));
2500 /* Generate packet burst for testing */
2501 TEST_ASSERT_EQUAL(generate_test_burst(
2502 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2503 "generate_test_burst failed");
2505 /* Initialize bonded device with 4 slaves in round robin mode */
2506 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2507 BONDING_MODE_ACTIVE_BACKUP, 0,
2508 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2509 "Failed to initialize bonded device with slaves");
2511 /* Verify Current Slaves Count /Active Slave Count is */
2512 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2514 TEST_ASSERT_EQUAL(slave_count, 4,
2515 "Number of slaves (%d) is not as expected (%d).",
2518 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2519 slaves, RTE_MAX_ETHPORTS);
2520 TEST_ASSERT_EQUAL(slave_count, 4,
2521 "Number of active slaves (%d) is not as expected (%d).",
2524 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2525 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2526 "Primary port not as expected");
2528 /* Bring 2 slaves down and verify active slave count */
2529 virtual_ethdev_simulate_link_status_interrupt(
2530 test_params->slave_port_ids[1], 0);
2531 virtual_ethdev_simulate_link_status_interrupt(
2532 test_params->slave_port_ids[3], 0);
2534 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2535 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2536 "Number of active slaves (%d) is not as expected (%d).",
2539 virtual_ethdev_simulate_link_status_interrupt(
2540 test_params->slave_port_ids[1], 1);
2541 virtual_ethdev_simulate_link_status_interrupt(
2542 test_params->slave_port_ids[3], 1);
2545 /* Bring primary port down, verify that active slave count is 3 and primary
2547 virtual_ethdev_simulate_link_status_interrupt(
2548 test_params->slave_port_ids[0], 0);
2550 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2551 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2553 "Number of active slaves (%d) is not as expected (%d).",
2556 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2557 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2558 "Primary port not as expected");
2560 /* Verify that pkts are sent on new primary slave */
2562 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2563 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2564 burst_size), burst_size, "rte_eth_tx_burst failed");
2566 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2567 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2568 "(%d) port_stats.opackets not as expected",
2569 test_params->slave_port_ids[2]);
2571 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2572 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2573 "(%d) port_stats.opackets not as expected\n",
2574 test_params->slave_port_ids[0]);
2576 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2577 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2578 "(%d) port_stats.opackets not as expected\n",
2579 test_params->slave_port_ids[1]);
2581 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2582 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2583 "(%d) port_stats.opackets not as expected\n",
2584 test_params->slave_port_ids[3]);
2586 /* Generate packet burst for testing */
2588 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2589 TEST_ASSERT_EQUAL(generate_test_burst(
2590 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2591 "generate_test_burst failed");
2593 virtual_ethdev_add_mbufs_to_rx_queue(
2594 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2597 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2598 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2599 burst_size, "rte_eth_rx_burst\n");
2601 /* Verify bonded device rx count */
2602 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2603 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2604 "(%d) port_stats.ipackets not as expected",
2605 test_params->bonded_port_id);
2607 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2608 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2609 "(%d) port_stats.opackets not as expected",
2610 test_params->slave_port_ids[2]);
2612 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2613 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2614 "(%d) port_stats.opackets not as expected",
2615 test_params->slave_port_ids[0]);
2617 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2618 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2619 "(%d) port_stats.opackets not as expected",
2620 test_params->slave_port_ids[1]);
2622 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2623 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2624 "(%d) port_stats.opackets not as expected",
2625 test_params->slave_port_ids[3]);
2627 /* Clean up and remove slaves from bonded device */
2628 return remove_slaves_and_stop_bonded_device();
2631 /** Balance Mode Tests */
2634 test_balance_xmit_policy_configuration(void)
2636 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2637 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2638 "Failed to initialize_bonded_device_with_slaves.");
2640 /* Invalid port id */
2641 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2642 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2643 "Expected call to failed as invalid port specified.");
2645 /* Set xmit policy on non bonded device */
2646 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2647 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2648 "Expected call to failed as invalid port specified.");
2651 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2652 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2653 "Failed to set balance xmit policy.");
2655 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2656 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2659 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2660 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2661 "Failed to set balance xmit policy.");
2663 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2664 BALANCE_XMIT_POLICY_LAYER23,
2665 "balance xmit policy not as expected.");
2668 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2669 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2670 "Failed to set balance xmit policy.");
2672 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2673 BALANCE_XMIT_POLICY_LAYER34,
2674 "balance xmit policy not as expected.");
2676 /* Invalid port id */
2677 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2678 "Expected call to failed as invalid port specified.");
2680 /* Clean up and remove slaves from bonded device */
2681 return remove_slaves_and_stop_bonded_device();
2684 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2687 test_balance_l2_tx_burst(void)
2689 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2690 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2694 struct rte_eth_stats port_stats;
2696 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2697 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2698 "Failed to initialize_bonded_device_with_slaves.");
2700 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2701 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2702 "Failed to set balance xmit policy.");
2704 initialize_eth_header(test_params->pkt_eth_hdr,
2705 (struct rte_ether_addr *)src_mac,
2706 (struct rte_ether_addr *)dst_mac_0,
2707 RTE_ETHER_TYPE_IPV4, 0, 0);
2708 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2710 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2711 dst_addr_0, pktlen);
2713 /* Generate a burst 1 of packets to transmit */
2714 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2715 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2716 test_params->pkt_udp_hdr, burst_size[0],
2717 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2718 "failed to generate packet burst");
2720 initialize_eth_header(test_params->pkt_eth_hdr,
2721 (struct rte_ether_addr *)src_mac,
2722 (struct rte_ether_addr *)dst_mac_1,
2723 RTE_ETHER_TYPE_IPV4, 0, 0);
2725 /* Generate a burst 2 of packets to transmit */
2726 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2727 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2728 test_params->pkt_udp_hdr, burst_size[1],
2729 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2730 "failed to generate packet burst");
2732 /* Send burst 1 on bonded port */
2733 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2734 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2735 &pkts_burst[i][0], burst_size[i]),
2736 burst_size[i], "Failed to transmit packet burst");
2739 /* Verify bonded port tx stats */
2740 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2741 TEST_ASSERT_EQUAL(port_stats.opackets,
2742 (uint64_t)(burst_size[0] + burst_size[1]),
2743 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2744 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2745 burst_size[0] + burst_size[1]);
2748 /* Verify slave ports tx stats */
2749 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2750 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2751 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2752 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2755 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2756 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2757 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2758 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2761 /* Put all slaves down and try and transmit */
2762 for (i = 0; i < test_params->bonded_slave_count; i++) {
2764 virtual_ethdev_simulate_link_status_interrupt(
2765 test_params->slave_port_ids[i], 0);
2768 /* Send burst on bonded port */
2769 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2770 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2771 0, "Expected zero packet");
2773 /* Clean up and remove slaves from bonded device */
2774 return remove_slaves_and_stop_bonded_device();
2778 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2779 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2781 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2783 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2784 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2786 struct rte_eth_stats port_stats;
2788 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2789 BONDING_MODE_BALANCE, 0, 2, 1),
2790 "Failed to initialize_bonded_device_with_slaves.");
2792 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2793 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2794 "Failed to set balance xmit policy.");
2799 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2800 "Burst size specified is greater than supported.");
2802 /* Generate test bursts of packets to transmit */
2803 TEST_ASSERT_EQUAL(generate_test_burst(
2804 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2805 burst_size_1, "failed to generate packet burst");
2807 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2808 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2809 "failed to generate packet burst");
2811 /* Send burst 1 on bonded port */
2812 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2814 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2816 /* Send burst 2 on bonded port */
2817 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2819 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2821 /* Verify bonded port tx stats */
2822 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2823 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2824 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2825 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2828 /* Verify slave ports tx stats */
2829 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2830 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2831 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2832 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2835 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2836 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2837 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2838 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2841 /* Put all slaves down and try and transmit */
2842 for (i = 0; i < test_params->bonded_slave_count; i++) {
2844 virtual_ethdev_simulate_link_status_interrupt(
2845 test_params->slave_port_ids[i], 0);
2848 /* Send burst on bonded port */
2849 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2850 test_params->bonded_port_id, 0, pkts_burst_1,
2851 burst_size_1), 0, "Expected zero packet");
2854 /* Clean up and remove slaves from bonded device */
2855 return remove_slaves_and_stop_bonded_device();
2859 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2861 return balance_l23_tx_burst(0, 1, 0, 1);
2865 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2867 return balance_l23_tx_burst(1, 1, 0, 1);
2871 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2873 return balance_l23_tx_burst(0, 0, 0, 1);
2877 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2879 return balance_l23_tx_burst(1, 0, 0, 1);
2883 test_balance_l23_tx_burst_toggle_mac_addr(void)
2885 return balance_l23_tx_burst(0, 0, 1, 0);
2889 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2890 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2891 uint8_t toggle_udp_port)
2893 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2895 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2896 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2898 struct rte_eth_stats port_stats;
2900 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2901 BONDING_MODE_BALANCE, 0, 2, 1),
2902 "Failed to initialize_bonded_device_with_slaves.");
2904 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2905 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2906 "Failed to set balance xmit policy.");
2911 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2912 "Burst size specified is greater than supported.");
2914 /* Generate test bursts of packets to transmit */
2915 TEST_ASSERT_EQUAL(generate_test_burst(
2916 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2917 burst_size_1, "failed to generate burst");
2919 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2920 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2921 toggle_udp_port), burst_size_2, "failed to generate burst");
2923 /* Send burst 1 on bonded port */
2924 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2926 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2928 /* Send burst 2 on bonded port */
2929 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2931 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2934 /* Verify bonded port tx stats */
2935 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2936 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2937 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2938 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2941 /* Verify slave ports tx stats */
2942 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2943 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2944 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2945 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2948 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2949 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2950 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2951 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2954 /* Put all slaves down and try and transmit */
2955 for (i = 0; i < test_params->bonded_slave_count; i++) {
2957 virtual_ethdev_simulate_link_status_interrupt(
2958 test_params->slave_port_ids[i], 0);
2961 /* Send burst on bonded port */
2962 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2963 test_params->bonded_port_id, 0, pkts_burst_1,
2964 burst_size_1), 0, "Expected zero packet");
2966 /* Clean up and remove slaves from bonded device */
2967 return remove_slaves_and_stop_bonded_device();
2971 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2973 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2977 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2979 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2983 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2985 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2989 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2991 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2995 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2997 return balance_l34_tx_burst(1, 0, 0, 1, 0);
3001 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
3003 return balance_l34_tx_burst(0, 0, 0, 0, 1);
3006 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
3007 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
3008 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
3009 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
3010 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
3013 test_balance_tx_burst_slave_tx_fail(void)
3015 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
3016 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
3018 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
3020 struct rte_eth_stats port_stats;
3022 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
3024 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3025 BONDING_MODE_BALANCE, 0,
3026 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3027 "Failed to initialise bonded device");
3029 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3030 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3031 "Failed to set balance xmit policy.");
3034 /* Generate test bursts for transmission */
3035 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
3036 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
3037 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
3038 "Failed to generate test packet burst 1");
3040 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3041 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
3043 /* copy mbuf referneces for expected transmission failures */
3044 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
3045 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
3047 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
3048 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
3049 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3050 "Failed to generate test packet burst 2");
3053 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3054 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3055 virtual_ethdev_tx_burst_fn_set_success(
3056 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3059 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3060 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3061 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3064 /* Transmit burst 1 */
3065 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3066 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3068 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3069 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3070 "Transmitted (%d) packets, expected to transmit (%d) packets",
3071 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3072 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3074 /* Verify that failed packet are expected failed packets */
3075 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3076 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3077 "expected mbuf (%d) pointer %p not expected pointer %p",
3078 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3081 /* Transmit burst 2 */
3082 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3083 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3085 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3086 "Transmitted (%d) packets, expected to transmit (%d) packets",
3087 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3090 /* Verify bonded port tx stats */
3091 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3093 TEST_ASSERT_EQUAL(port_stats.opackets,
3094 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3095 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3096 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3097 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3098 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3099 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3100 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3101 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3103 /* Verify slave ports tx stats */
3105 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3107 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3108 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3109 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3110 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3111 test_params->slave_port_ids[0],
3112 (unsigned int)port_stats.opackets,
3113 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3114 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3119 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3121 TEST_ASSERT_EQUAL(port_stats.opackets,
3122 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3123 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3124 test_params->slave_port_ids[1],
3125 (unsigned int)port_stats.opackets,
3126 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3128 /* Verify that all mbufs have a ref value of zero */
3129 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3130 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3131 "mbufs refcnts not as expected");
3133 free_mbufs(&pkts_burst_1[tx_count_1],
3134 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3136 /* Clean up and remove slaves from bonded device */
3137 return remove_slaves_and_stop_bonded_device();
3140 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3143 test_balance_rx_burst(void)
3145 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3147 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3148 struct rte_eth_stats port_stats;
3150 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3153 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3155 /* Initialize bonded device with 4 slaves in round robin mode */
3156 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3157 BONDING_MODE_BALANCE, 0, 3, 1),
3158 "Failed to initialise bonded device");
3160 /* Generate test bursts of packets to transmit */
3161 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3162 TEST_ASSERT_EQUAL(generate_test_burst(
3163 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3164 0, 0), burst_size[i],
3165 "failed to generate packet burst");
3168 /* Add rx data to slaves */
3169 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3170 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3171 &gen_pkt_burst[i][0], burst_size[i]);
3174 /* Call rx burst on bonded device */
3175 /* Send burst on bonded port */
3176 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3177 rx_pkt_burst, MAX_PKT_BURST),
3178 burst_size[0] + burst_size[1] + burst_size[2],
3179 "balance rx burst failed\n");
3181 /* Verify bonded device rx count */
3182 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3183 TEST_ASSERT_EQUAL(port_stats.ipackets,
3184 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3185 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3186 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3187 burst_size[0] + burst_size[1] + burst_size[2]);
3190 /* Verify bonded slave devices rx counts */
3191 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3192 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3193 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3194 test_params->slave_port_ids[0],
3195 (unsigned int)port_stats.ipackets, burst_size[0]);
3197 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3198 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3199 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3200 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3203 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3204 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3205 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3206 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3209 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3210 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3211 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3212 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3216 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3217 for (j = 0; j < MAX_PKT_BURST; j++) {
3218 if (gen_pkt_burst[i][j] != NULL) {
3219 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3220 gen_pkt_burst[i][j] = NULL;
3225 /* Clean up and remove slaves from bonded device */
3226 return remove_slaves_and_stop_bonded_device();
3230 test_balance_verify_promiscuous_enable_disable(void)
3235 /* Initialize bonded device with 4 slaves in round robin mode */
3236 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3237 BONDING_MODE_BALANCE, 0, 4, 1),
3238 "Failed to initialise bonded device");
3240 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3241 TEST_ASSERT_SUCCESS(ret,
3242 "Failed to enable promiscuous mode for port %d: %s",
3243 test_params->bonded_port_id, rte_strerror(-ret));
3245 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3246 "Port (%d) promiscuous mode not enabled",
3247 test_params->bonded_port_id);
3249 for (i = 0; i < test_params->bonded_slave_count; i++) {
3250 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3251 test_params->slave_port_ids[i]), 1,
3252 "Port (%d) promiscuous mode not enabled",
3253 test_params->slave_port_ids[i]);
3256 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3257 TEST_ASSERT_SUCCESS(ret,
3258 "Failed to disable promiscuous mode for port %d: %s",
3259 test_params->bonded_port_id, rte_strerror(-ret));
3261 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3262 "Port (%d) promiscuous mode not disabled",
3263 test_params->bonded_port_id);
3265 for (i = 0; i < test_params->bonded_slave_count; i++) {
3266 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3267 test_params->slave_port_ids[i]), 0,
3268 "Port (%d) promiscuous mode not disabled",
3269 test_params->slave_port_ids[i]);
3272 /* Clean up and remove slaves from bonded device */
3273 return remove_slaves_and_stop_bonded_device();
3277 test_balance_verify_mac_assignment(void)
3279 struct rte_ether_addr read_mac_addr;
3280 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3282 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3283 "Failed to get mac address (port %d)",
3284 test_params->slave_port_ids[0]);
3285 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
3286 "Failed to get mac address (port %d)",
3287 test_params->slave_port_ids[1]);
3289 /* Initialize bonded device with 2 slaves in active backup mode */
3290 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3291 BONDING_MODE_BALANCE, 0, 2, 1),
3292 "Failed to initialise bonded device");
3294 /* Verify that bonded MACs is that of first slave and that the other slave
3295 * MAC hasn't been changed */
3296 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3297 "Failed to get mac address (port %d)",
3298 test_params->bonded_port_id);
3299 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3300 sizeof(read_mac_addr)),
3301 "bonded port (%d) mac address not set to that of primary port",
3302 test_params->bonded_port_id);
3304 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3305 "Failed to get mac address (port %d)",
3306 test_params->slave_port_ids[0]);
3307 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3308 sizeof(read_mac_addr)),
3309 "slave port (%d) mac address not set to that of primary port",
3310 test_params->slave_port_ids[0]);
3312 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3313 "Failed to get mac address (port %d)",
3314 test_params->slave_port_ids[1]);
3315 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3316 sizeof(read_mac_addr)),
3317 "slave port (%d) mac address not set to that of primary port",
3318 test_params->slave_port_ids[1]);
3320 /* change primary and verify that MAC addresses haven't changed */
3321 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3322 test_params->slave_port_ids[1]),
3323 "Failed to set bonded port (%d) primary port to (%d)\n",
3324 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3326 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3327 "Failed to get mac address (port %d)",
3328 test_params->bonded_port_id);
3329 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3330 sizeof(read_mac_addr)),
3331 "bonded port (%d) mac address not set to that of primary port",
3332 test_params->bonded_port_id);
3334 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3335 "Failed to get mac address (port %d)",
3336 test_params->slave_port_ids[0]);
3337 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3338 sizeof(read_mac_addr)),
3339 "slave port (%d) mac address not set to that of primary port",
3340 test_params->slave_port_ids[0]);
3342 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3343 "Failed to get mac address (port %d)",
3344 test_params->slave_port_ids[1]);
3345 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3346 sizeof(read_mac_addr)),
3347 "slave port (%d) mac address not set to that of primary port",
3348 test_params->slave_port_ids[1]);
3350 /* stop / start bonded device and verify that primary MAC address is
3351 * propagated to bonded device and slaves */
3353 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
3354 "Failed to stop bonded port %u",
3355 test_params->bonded_port_id);
3357 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3358 "Failed to start bonded device");
3360 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3361 "Failed to get mac address (port %d)",
3362 test_params->bonded_port_id);
3363 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3364 sizeof(read_mac_addr)),
3365 "bonded port (%d) mac address not set to that of primary port",
3366 test_params->bonded_port_id);
3368 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3369 "Failed to get mac address (port %d)",
3370 test_params->slave_port_ids[0]);
3371 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3372 sizeof(read_mac_addr)),
3373 "slave port (%d) mac address not set to that of primary port",
3374 test_params->slave_port_ids[0]);
3376 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3377 "Failed to get mac address (port %d)",
3378 test_params->slave_port_ids[1]);
3379 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3380 sizeof(read_mac_addr)),
3381 "slave port (%d) mac address not set to that of primary port",
3382 test_params->slave_port_ids[1]);
3384 /* Set explicit MAC address */
3385 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3386 test_params->bonded_port_id,
3387 (struct rte_ether_addr *)bonded_mac),
3388 "failed to set MAC");
3390 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3391 "Failed to get mac address (port %d)",
3392 test_params->bonded_port_id);
3393 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3394 sizeof(read_mac_addr)),
3395 "bonded port (%d) mac address not set to that of bonded port",
3396 test_params->bonded_port_id);
3398 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3399 "Failed to get mac address (port %d)",
3400 test_params->slave_port_ids[0]);
3401 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3402 sizeof(read_mac_addr)),
3403 "slave port (%d) mac address not as expected\n",
3404 test_params->slave_port_ids[0]);
3406 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3407 "Failed to get mac address (port %d)",
3408 test_params->slave_port_ids[1]);
3409 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3410 sizeof(read_mac_addr)),
3411 "slave port (%d) mac address not set to that of bonded port",
3412 test_params->slave_port_ids[1]);
3414 /* Clean up and remove slaves from bonded device */
3415 return remove_slaves_and_stop_bonded_device();
3418 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3421 test_balance_verify_slave_link_status_change_behaviour(void)
3423 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3424 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3425 struct rte_eth_stats port_stats;
3427 uint16_t slaves[RTE_MAX_ETHPORTS];
3429 int i, burst_size, slave_count;
3431 memset(pkt_burst, 0, sizeof(pkt_burst));
3433 /* Initialize bonded device with 4 slaves in round robin mode */
3434 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3435 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3436 "Failed to initialise bonded device");
3438 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3439 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3440 "Failed to set balance xmit policy.");
3443 /* Verify Current Slaves Count /Active Slave Count is */
3444 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3446 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3447 "Number of slaves (%d) is not as expected (%d).",
3448 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3450 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3451 slaves, RTE_MAX_ETHPORTS);
3452 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3453 "Number of active slaves (%d) is not as expected (%d).",
3454 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3456 /* Set 2 slaves link status to down */
3457 virtual_ethdev_simulate_link_status_interrupt(
3458 test_params->slave_port_ids[1], 0);
3459 virtual_ethdev_simulate_link_status_interrupt(
3460 test_params->slave_port_ids[3], 0);
3462 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3463 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3464 "Number of active slaves (%d) is not as expected (%d).",
3467 /* Send to sets of packet burst and verify that they are balanced across
3471 TEST_ASSERT_EQUAL(generate_test_burst(
3472 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3473 "generate_test_burst failed");
3475 TEST_ASSERT_EQUAL(generate_test_burst(
3476 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3477 "generate_test_burst failed");
3479 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3480 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3481 burst_size, "rte_eth_tx_burst failed");
3483 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3484 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3485 burst_size, "rte_eth_tx_burst failed");
3488 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3489 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3490 "(%d) port_stats.opackets (%d) not as expected (%d).",
3491 test_params->bonded_port_id, (int)port_stats.opackets,
3492 burst_size + burst_size);
3494 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3495 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3496 "(%d) port_stats.opackets (%d) not as expected (%d).",
3497 test_params->slave_port_ids[0], (int)port_stats.opackets,
3500 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3501 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3502 "(%d) port_stats.opackets (%d) not as expected (%d).",
3503 test_params->slave_port_ids[2], (int)port_stats.opackets,
3506 /* verify that all packets get send on primary slave when no other slaves
3508 virtual_ethdev_simulate_link_status_interrupt(
3509 test_params->slave_port_ids[2], 0);
3511 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3512 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3513 "Number of active slaves (%d) is not as expected (%d).",
3516 TEST_ASSERT_EQUAL(generate_test_burst(
3517 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3518 "generate_test_burst failed");
3520 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3521 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3522 burst_size, "rte_eth_tx_burst failed");
3524 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3525 TEST_ASSERT_EQUAL(port_stats.opackets,
3526 (uint64_t)(burst_size + burst_size + burst_size),
3527 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3528 test_params->bonded_port_id, (int)port_stats.opackets,
3529 burst_size + burst_size + burst_size);
3531 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3532 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3533 "(%d) port_stats.opackets (%d) not as expected (%d).",
3534 test_params->slave_port_ids[0], (int)port_stats.opackets,
3535 burst_size + burst_size);
3537 virtual_ethdev_simulate_link_status_interrupt(
3538 test_params->slave_port_ids[0], 0);
3539 virtual_ethdev_simulate_link_status_interrupt(
3540 test_params->slave_port_ids[1], 1);
3541 virtual_ethdev_simulate_link_status_interrupt(
3542 test_params->slave_port_ids[2], 1);
3543 virtual_ethdev_simulate_link_status_interrupt(
3544 test_params->slave_port_ids[3], 1);
3546 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3547 TEST_ASSERT_EQUAL(generate_test_burst(
3548 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3549 "Failed to generate packet burst");
3551 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3552 &pkt_burst[i][0], burst_size);
3555 /* Verify that pkts are not received on slaves with link status down */
3557 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3560 /* Verify bonded device rx count */
3561 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3562 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3563 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3564 test_params->bonded_port_id, (int)port_stats.ipackets,
3567 /* Clean up and remove slaves from bonded device */
3568 return remove_slaves_and_stop_bonded_device();
3572 test_broadcast_tx_burst(void)
3574 int i, pktlen, burst_size;
3575 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3577 struct rte_eth_stats port_stats;
3579 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3580 BONDING_MODE_BROADCAST, 0, 2, 1),
3581 "Failed to initialise bonded device");
3583 initialize_eth_header(test_params->pkt_eth_hdr,
3584 (struct rte_ether_addr *)src_mac,
3585 (struct rte_ether_addr *)dst_mac_0,
3586 RTE_ETHER_TYPE_IPV4, 0, 0);
3588 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3590 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3591 dst_addr_0, pktlen);
3593 burst_size = 20 * test_params->bonded_slave_count;
3595 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3596 "Burst size specified is greater than supported.");
3598 /* Generate a burst of packets to transmit */
3599 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3600 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3601 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3602 1), burst_size, "Failed to generate packet burst");
3604 /* Send burst on bonded port */
3605 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3606 pkts_burst, burst_size), burst_size,
3607 "Bonded Port (%d) rx burst failed, packets transmitted value "
3608 "not as expected (%d)",
3609 test_params->bonded_port_id, burst_size);
3611 /* Verify bonded port tx stats */
3612 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3613 TEST_ASSERT_EQUAL(port_stats.opackets,
3614 (uint64_t)burst_size * test_params->bonded_slave_count,
3615 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3616 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3619 /* Verify slave ports tx stats */
3620 for (i = 0; i < test_params->bonded_slave_count; i++) {
3621 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3622 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3623 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3624 test_params->bonded_port_id,
3625 (unsigned int)port_stats.opackets, burst_size);
3628 /* Put all slaves down and try and transmit */
3629 for (i = 0; i < test_params->bonded_slave_count; i++) {
3631 virtual_ethdev_simulate_link_status_interrupt(
3632 test_params->slave_port_ids[i], 0);
3635 /* Send burst on bonded port */
3636 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3637 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3638 "transmitted an unexpected number of packets");
3640 /* Clean up and remove slaves from bonded device */
3641 return remove_slaves_and_stop_bonded_device();
3645 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3646 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3647 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3648 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3651 test_broadcast_tx_burst_slave_tx_fail(void)
3653 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3654 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3656 struct rte_eth_stats port_stats;
3660 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3661 BONDING_MODE_BROADCAST, 0,
3662 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3663 "Failed to initialise bonded device");
3665 /* Generate test bursts for transmission */
3666 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3667 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3668 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3669 "Failed to generate test packet burst");
3671 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3672 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3673 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3676 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3677 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3678 virtual_ethdev_tx_burst_fn_set_success(
3679 test_params->slave_port_ids[0],
3681 virtual_ethdev_tx_burst_fn_set_success(
3682 test_params->slave_port_ids[1],
3684 virtual_ethdev_tx_burst_fn_set_success(
3685 test_params->slave_port_ids[2],
3688 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3689 test_params->slave_port_ids[0],
3690 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3692 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3693 test_params->slave_port_ids[1],
3694 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3696 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3697 test_params->slave_port_ids[2],
3698 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3700 /* Transmit burst */
3701 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3702 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3704 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3705 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3706 "Transmitted (%d) packets, expected to transmit (%d) packets",
3707 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3708 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3710 /* Verify that failed packet are expected failed packets */
3711 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3712 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3713 "expected mbuf (%d) pointer %p not expected pointer %p",
3714 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3717 /* Verify slave ports tx stats */
3719 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3721 TEST_ASSERT_EQUAL(port_stats.opackets,
3722 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3723 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3724 "Port (%d) opackets value (%u) not as expected (%d)",
3725 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3726 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3727 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3730 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3732 TEST_ASSERT_EQUAL(port_stats.opackets,
3733 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3734 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3735 "Port (%d) opackets value (%u) not as expected (%d)",
3736 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3737 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3738 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3740 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3742 TEST_ASSERT_EQUAL(port_stats.opackets,
3743 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3744 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3745 "Port (%d) opackets value (%u) not as expected (%d)",
3746 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3747 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3748 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3751 /* Verify that all mbufs who transmission failed have a ref value of one */
3752 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3753 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3754 "mbufs refcnts not as expected");
3756 free_mbufs(&pkts_burst[tx_count],
3757 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3759 /* Clean up and remove slaves from bonded device */
3760 return remove_slaves_and_stop_bonded_device();
3763 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3766 test_broadcast_rx_burst(void)
3768 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3770 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3771 struct rte_eth_stats port_stats;
3773 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3776 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3778 /* Initialize bonded device with 4 slaves in round robin mode */
3779 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3780 BONDING_MODE_BROADCAST, 0, 3, 1),
3781 "Failed to initialise bonded device");
3783 /* Generate test bursts of packets to transmit */
3784 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3785 TEST_ASSERT_EQUAL(generate_test_burst(
3786 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3787 burst_size[i], "failed to generate packet burst");
3790 /* Add rx data to slave 0 */
3791 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3792 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3793 &gen_pkt_burst[i][0], burst_size[i]);
3797 /* Call rx burst on bonded device */
3798 /* Send burst on bonded port */
3799 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3800 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3801 burst_size[0] + burst_size[1] + burst_size[2],
3804 /* Verify bonded device rx count */
3805 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3806 TEST_ASSERT_EQUAL(port_stats.ipackets,
3807 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3808 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3809 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3810 burst_size[0] + burst_size[1] + burst_size[2]);
3813 /* Verify bonded slave devices rx counts */
3814 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3815 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3816 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3817 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3820 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3821 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3822 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3823 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3826 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3827 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3828 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3829 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3832 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3833 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3834 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3835 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3838 /* free mbufs allocate for rx testing */
3839 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3840 for (j = 0; j < MAX_PKT_BURST; j++) {
3841 if (gen_pkt_burst[i][j] != NULL) {
3842 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3843 gen_pkt_burst[i][j] = NULL;
3848 /* Clean up and remove slaves from bonded device */
3849 return remove_slaves_and_stop_bonded_device();
3853 test_broadcast_verify_promiscuous_enable_disable(void)
3858 /* Initialize bonded device with 4 slaves in round robin mode */
3859 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3860 BONDING_MODE_BROADCAST, 0, 4, 1),
3861 "Failed to initialise bonded device");
3863 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3864 TEST_ASSERT_SUCCESS(ret,
3865 "Failed to enable promiscuous mode for port %d: %s",
3866 test_params->bonded_port_id, rte_strerror(-ret));
3869 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3870 "Port (%d) promiscuous mode not enabled",
3871 test_params->bonded_port_id);
3873 for (i = 0; i < test_params->bonded_slave_count; i++) {
3874 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3875 test_params->slave_port_ids[i]), 1,
3876 "Port (%d) promiscuous mode not enabled",
3877 test_params->slave_port_ids[i]);
3880 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3881 TEST_ASSERT_SUCCESS(ret,
3882 "Failed to disable promiscuous mode for port %d: %s",
3883 test_params->bonded_port_id, rte_strerror(-ret));
3885 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3886 "Port (%d) promiscuous mode not disabled",
3887 test_params->bonded_port_id);
3889 for (i = 0; i < test_params->bonded_slave_count; i++) {
3890 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3891 test_params->slave_port_ids[i]), 0,
3892 "Port (%d) promiscuous mode not disabled",
3893 test_params->slave_port_ids[i]);
3896 /* Clean up and remove slaves from bonded device */
3897 return remove_slaves_and_stop_bonded_device();
3901 test_broadcast_verify_mac_assignment(void)
3903 struct rte_ether_addr read_mac_addr;
3904 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3908 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3909 "Failed to get mac address (port %d)",
3910 test_params->slave_port_ids[0]);
3911 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1),
3912 "Failed to get mac address (port %d)",
3913 test_params->slave_port_ids[2]);
3915 /* Initialize bonded device with 4 slaves in round robin mode */
3916 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3917 BONDING_MODE_BROADCAST, 0, 4, 1),
3918 "Failed to initialise bonded device");
3920 /* Verify that all MACs are the same as first slave added to bonded
3922 for (i = 0; i < test_params->bonded_slave_count; i++) {
3923 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3924 "Failed to get mac address (port %d)",
3925 test_params->slave_port_ids[i]);
3926 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3927 sizeof(read_mac_addr)),
3928 "slave port (%d) mac address not set to that of primary port",
3929 test_params->slave_port_ids[i]);
3932 /* change primary and verify that MAC addresses haven't changed */
3933 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3934 test_params->slave_port_ids[2]),
3935 "Failed to set bonded port (%d) primary port to (%d)",
3936 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3938 for (i = 0; i < test_params->bonded_slave_count; i++) {
3939 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3940 "Failed to get mac address (port %d)",
3941 test_params->slave_port_ids[i]);
3942 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3943 sizeof(read_mac_addr)),
3944 "slave port (%d) mac address has changed to that of primary "
3945 "port without stop/start toggle of bonded device",
3946 test_params->slave_port_ids[i]);
3949 /* stop / start bonded device and verify that primary MAC address is
3950 * propagated to bonded device and slaves */
3952 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
3953 "Failed to stop bonded port %u",
3954 test_params->bonded_port_id);
3956 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3957 "Failed to start bonded device");
3959 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3960 "Failed to get mac address (port %d)",
3961 test_params->bonded_port_id);
3962 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3963 sizeof(read_mac_addr)),
3964 "bonded port (%d) mac address not set to that of new primary port",
3965 test_params->slave_port_ids[i]);
3967 for (i = 0; i < test_params->bonded_slave_count; i++) {
3968 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3969 "Failed to get mac address (port %d)",
3970 test_params->slave_port_ids[i]);
3971 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3972 sizeof(read_mac_addr)),
3973 "slave port (%d) mac address not set to that of new primary "
3974 "port", test_params->slave_port_ids[i]);
3977 /* Set explicit MAC address */
3978 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3979 test_params->bonded_port_id,
3980 (struct rte_ether_addr *)bonded_mac),
3981 "Failed to set MAC address");
3983 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3984 "Failed to get mac address (port %d)",
3985 test_params->bonded_port_id);
3986 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3987 sizeof(read_mac_addr)),
3988 "bonded port (%d) mac address not set to that of new primary port",
3989 test_params->slave_port_ids[i]);
3992 for (i = 0; i < test_params->bonded_slave_count; i++) {
3993 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3994 "Failed to get mac address (port %d)",
3995 test_params->slave_port_ids[i]);
3996 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3997 sizeof(read_mac_addr)),
3998 "slave port (%d) mac address not set to that of new primary "
3999 "port", test_params->slave_port_ids[i]);
4002 /* Clean up and remove slaves from bonded device */
4003 return remove_slaves_and_stop_bonded_device();
4006 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
4008 test_broadcast_verify_slave_link_status_change_behaviour(void)
4010 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
4011 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4012 struct rte_eth_stats port_stats;
4014 uint16_t slaves[RTE_MAX_ETHPORTS];
4016 int i, burst_size, slave_count;
4018 memset(pkt_burst, 0, sizeof(pkt_burst));
4020 /* Initialize bonded device with 4 slaves in round robin mode */
4021 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4022 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
4023 1), "Failed to initialise bonded device");
4025 /* Verify Current Slaves Count /Active Slave Count is */
4026 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4028 TEST_ASSERT_EQUAL(slave_count, 4,
4029 "Number of slaves (%d) is not as expected (%d).",
4032 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4033 slaves, RTE_MAX_ETHPORTS);
4034 TEST_ASSERT_EQUAL(slave_count, 4,
4035 "Number of active slaves (%d) is not as expected (%d).",
4038 /* Set 2 slaves link status to down */
4039 virtual_ethdev_simulate_link_status_interrupt(
4040 test_params->slave_port_ids[1], 0);
4041 virtual_ethdev_simulate_link_status_interrupt(
4042 test_params->slave_port_ids[3], 0);
4044 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4045 slaves, RTE_MAX_ETHPORTS);
4046 TEST_ASSERT_EQUAL(slave_count, 2,
4047 "Number of active slaves (%d) is not as expected (%d).",
4050 for (i = 0; i < test_params->bonded_slave_count; i++)
4051 rte_eth_stats_reset(test_params->slave_port_ids[i]);
4053 /* Verify that pkts are not sent on slaves with link status down */
4056 TEST_ASSERT_EQUAL(generate_test_burst(
4057 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
4058 "generate_test_burst failed");
4060 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
4061 &pkt_burst[0][0], burst_size), burst_size,
4062 "rte_eth_tx_burst failed\n");
4064 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4065 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
4066 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
4067 test_params->bonded_port_id, (int)port_stats.opackets,
4068 burst_size * slave_count);
4070 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4071 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4072 "(%d) port_stats.opackets not as expected",
4073 test_params->slave_port_ids[0]);
4075 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4076 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4077 "(%d) port_stats.opackets not as expected",
4078 test_params->slave_port_ids[1]);
4080 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4081 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4082 "(%d) port_stats.opackets not as expected",
4083 test_params->slave_port_ids[2]);
4086 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4087 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4088 "(%d) port_stats.opackets not as expected",
4089 test_params->slave_port_ids[3]);
4092 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4093 TEST_ASSERT_EQUAL(generate_test_burst(
4094 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
4095 burst_size, "failed to generate packet burst");
4097 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4098 &pkt_burst[i][0], burst_size);
4101 /* Verify that pkts are not received on slaves with link status down */
4102 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
4103 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
4104 burst_size + burst_size, "rte_eth_rx_burst failed");
4107 /* Verify bonded device rx count */
4108 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4109 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
4110 "(%d) port_stats.ipackets not as expected\n",
4111 test_params->bonded_port_id);
4113 /* Clean up and remove slaves from bonded device */
4114 return remove_slaves_and_stop_bonded_device();
4118 test_reconfigure_bonded_device(void)
4120 test_params->nb_rx_q = 4;
4121 test_params->nb_tx_q = 4;
4123 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4124 "failed to reconfigure bonded device");
4126 test_params->nb_rx_q = 2;
4127 test_params->nb_tx_q = 2;
4129 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4130 "failed to reconfigure bonded device with less rx/tx queues");
4137 test_close_bonded_device(void)
4139 rte_eth_dev_close(test_params->bonded_port_id);
4144 testsuite_teardown(void)
4146 free(test_params->pkt_eth_hdr);
4147 test_params->pkt_eth_hdr = NULL;
4149 /* Clean up and remove slaves from bonded device */
4150 remove_slaves_and_stop_bonded_device();
4154 free_virtualpmd_tx_queue(void)
4156 int i, slave_port, to_free_cnt;
4157 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4159 /* Free tx queue of virtual pmd */
4160 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4162 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4163 test_params->slave_port_ids[slave_port],
4164 pkts_to_free, MAX_PKT_BURST);
4165 for (i = 0; i < to_free_cnt; i++)
4166 rte_pktmbuf_free(pkts_to_free[i]);
4171 test_tlb_tx_burst(void)
4173 int i, burst_size, nb_tx;
4174 uint64_t nb_tx2 = 0;
4175 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4176 struct rte_eth_stats port_stats[32];
4177 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4180 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4181 (BONDING_MODE_TLB, 1, 3, 1),
4182 "Failed to initialise bonded device");
4184 burst_size = 20 * test_params->bonded_slave_count;
4186 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4187 "Burst size specified is greater than supported.\n");
4190 /* Generate bursts of packets */
4191 for (i = 0; i < 400000; i++) {
4192 /*test two types of mac src own(bonding) and others */
4194 initialize_eth_header(test_params->pkt_eth_hdr,
4195 (struct rte_ether_addr *)src_mac,
4196 (struct rte_ether_addr *)dst_mac_0,
4197 RTE_ETHER_TYPE_IPV4, 0, 0);
4199 initialize_eth_header(test_params->pkt_eth_hdr,
4200 (struct rte_ether_addr *)test_params->default_slave_mac,
4201 (struct rte_ether_addr *)dst_mac_0,
4202 RTE_ETHER_TYPE_IPV4, 0, 0);
4204 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4206 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4207 dst_addr_0, pktlen);
4208 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4209 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4210 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4211 /* Send burst on bonded port */
4212 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4216 free_virtualpmd_tx_queue();
4218 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4219 "number of packet not equal burst size");
4225 /* Verify bonded port tx stats */
4226 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4228 all_bond_opackets = port_stats[0].opackets;
4229 all_bond_obytes = port_stats[0].obytes;
4231 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4232 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4233 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4237 /* Verify slave ports tx stats */
4238 for (i = 0; i < test_params->bonded_slave_count; i++) {
4239 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4240 sum_ports_opackets += port_stats[i].opackets;
4243 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4244 "Total packets sent by slaves is not equal to packets sent by bond interface");
4246 /* checking if distribution of packets is balanced over slaves */
4247 for (i = 0; i < test_params->bonded_slave_count; i++) {
4248 TEST_ASSERT(port_stats[i].obytes > 0 &&
4249 port_stats[i].obytes < all_bond_obytes,
4250 "Packets are not balanced over slaves");
4253 /* Put all slaves down and try and transmit */
4254 for (i = 0; i < test_params->bonded_slave_count; i++) {
4255 virtual_ethdev_simulate_link_status_interrupt(
4256 test_params->slave_port_ids[i], 0);
4259 /* Send burst on bonded port */
4260 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4262 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4264 /* Clean ugit checkout masterp and remove slaves from bonded device */
4265 return remove_slaves_and_stop_bonded_device();
4268 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4271 test_tlb_rx_burst(void)
4273 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4274 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4276 struct rte_eth_stats port_stats;
4280 uint16_t i, j, nb_rx, burst_size = 17;
4282 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4283 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4285 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4286 "Failed to initialize bonded device");
4289 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4290 TEST_ASSERT(primary_port >= 0,
4291 "failed to get primary slave for bonded port (%d)",
4292 test_params->bonded_port_id);
4294 for (i = 0; i < test_params->bonded_slave_count; i++) {
4295 /* Generate test bursts of packets to transmit */
4296 TEST_ASSERT_EQUAL(generate_test_burst(
4297 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4298 "burst generation failed");
4300 /* Add rx data to slave */
4301 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4302 &gen_pkt_burst[0], burst_size);
4304 /* Call rx burst on bonded device */
4305 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4306 &rx_pkt_burst[0], MAX_PKT_BURST);
4308 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4310 if (test_params->slave_port_ids[i] == primary_port) {
4311 /* Verify bonded device rx count */
4312 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4313 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4314 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4315 test_params->bonded_port_id,
4316 (unsigned int)port_stats.ipackets, burst_size);
4318 /* Verify bonded slave devices rx count */
4319 for (j = 0; j < test_params->bonded_slave_count; j++) {
4320 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4322 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4323 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4324 test_params->slave_port_ids[i],
4325 (unsigned int)port_stats.ipackets, burst_size);
4327 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4328 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4329 test_params->slave_port_ids[i],
4330 (unsigned int)port_stats.ipackets, 0);
4334 for (j = 0; j < test_params->bonded_slave_count; j++) {
4335 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4336 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4337 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4338 test_params->slave_port_ids[i],
4339 (unsigned int)port_stats.ipackets, 0);
4344 for (i = 0; i < burst_size; i++)
4345 rte_pktmbuf_free(rx_pkt_burst[i]);
4347 /* reset bonded device stats */
4348 rte_eth_stats_reset(test_params->bonded_port_id);
4351 /* Clean up and remove slaves from bonded device */
4352 return remove_slaves_and_stop_bonded_device();
4356 test_tlb_verify_promiscuous_enable_disable(void)
4358 int i, primary_port, promiscuous_en;
4361 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4362 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4363 BONDING_MODE_TLB, 0, 4, 1),
4364 "Failed to initialize bonded device");
4366 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4367 TEST_ASSERT(primary_port >= 0,
4368 "failed to get primary slave for bonded port (%d)",
4369 test_params->bonded_port_id);
4371 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
4372 TEST_ASSERT_SUCCESS(ret,
4373 "Failed to enable promiscuous mode for port %d: %s",
4374 test_params->bonded_port_id, rte_strerror(-ret));
4376 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4377 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4378 "Port (%d) promiscuous mode not enabled\n",
4379 test_params->bonded_port_id);
4380 for (i = 0; i < test_params->bonded_slave_count; i++) {
4381 promiscuous_en = rte_eth_promiscuous_get(
4382 test_params->slave_port_ids[i]);
4383 if (primary_port == test_params->slave_port_ids[i]) {
4384 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4385 "Port (%d) promiscuous mode not enabled\n",
4386 test_params->bonded_port_id);
4388 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4389 "Port (%d) promiscuous mode enabled\n",
4390 test_params->bonded_port_id);
4395 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
4396 TEST_ASSERT_SUCCESS(ret,
4397 "Failed to disable promiscuous mode for port %d: %s\n",
4398 test_params->bonded_port_id, rte_strerror(-ret));
4400 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4401 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4402 "Port (%d) promiscuous mode not disabled\n",
4403 test_params->bonded_port_id);
4405 for (i = 0; i < test_params->bonded_slave_count; i++) {
4406 promiscuous_en = rte_eth_promiscuous_get(
4407 test_params->slave_port_ids[i]);
4408 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4409 "slave port (%d) promiscuous mode not disabled\n",
4410 test_params->slave_port_ids[i]);
4413 /* Clean up and remove slaves from bonded device */
4414 return remove_slaves_and_stop_bonded_device();
4418 test_tlb_verify_mac_assignment(void)
4420 struct rte_ether_addr read_mac_addr;
4421 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
4423 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
4424 "Failed to get mac address (port %d)",
4425 test_params->slave_port_ids[0]);
4426 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
4427 "Failed to get mac address (port %d)",
4428 test_params->slave_port_ids[1]);
4430 /* Initialize bonded device with 2 slaves in active backup mode */
4431 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4432 BONDING_MODE_TLB, 0, 2, 1),
4433 "Failed to initialize bonded device");
4435 /* Verify that bonded MACs is that of first slave and that the other slave
4436 * MAC hasn't been changed */
4437 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4438 "Failed to get mac address (port %d)",
4439 test_params->bonded_port_id);
4440 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4441 sizeof(read_mac_addr)),
4442 "bonded port (%d) mac address not set to that of primary port",
4443 test_params->bonded_port_id);
4445 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4446 "Failed to get mac address (port %d)",
4447 test_params->slave_port_ids[0]);
4448 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4449 sizeof(read_mac_addr)),
4450 "slave port (%d) mac address not set to that of primary port",
4451 test_params->slave_port_ids[0]);
4453 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4454 "Failed to get mac address (port %d)",
4455 test_params->slave_port_ids[1]);
4456 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4457 sizeof(read_mac_addr)),
4458 "slave port (%d) mac address not as expected",
4459 test_params->slave_port_ids[1]);
4461 /* change primary and verify that MAC addresses haven't changed */
4462 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4463 test_params->slave_port_ids[1]), 0,
4464 "Failed to set bonded port (%d) primary port to (%d)",
4465 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4467 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4468 "Failed to get mac address (port %d)",
4469 test_params->bonded_port_id);
4470 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4471 sizeof(read_mac_addr)),
4472 "bonded port (%d) mac address not set to that of primary port",
4473 test_params->bonded_port_id);
4475 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4476 "Failed to get mac address (port %d)",
4477 test_params->slave_port_ids[0]);
4478 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4479 sizeof(read_mac_addr)),
4480 "slave port (%d) mac address not set to that of primary port",
4481 test_params->slave_port_ids[0]);
4483 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4484 "Failed to get mac address (port %d)",
4485 test_params->slave_port_ids[1]);
4486 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4487 sizeof(read_mac_addr)),
4488 "slave port (%d) mac address not as expected",
4489 test_params->slave_port_ids[1]);
4491 /* stop / start bonded device and verify that primary MAC address is
4492 * propagated to bonded device and slaves */
4494 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id),
4495 "Failed to stop bonded port %u",
4496 test_params->bonded_port_id);
4498 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4499 "Failed to start device");
4501 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4502 "Failed to get mac address (port %d)",
4503 test_params->bonded_port_id);
4504 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4505 sizeof(read_mac_addr)),
4506 "bonded port (%d) mac address not set to that of primary port",
4507 test_params->bonded_port_id);
4509 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4510 "Failed to get mac address (port %d)",
4511 test_params->slave_port_ids[0]);
4512 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4513 sizeof(read_mac_addr)),
4514 "slave port (%d) mac address not as expected",
4515 test_params->slave_port_ids[0]);
4517 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4518 "Failed to get mac address (port %d)",
4519 test_params->slave_port_ids[1]);
4520 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4521 sizeof(read_mac_addr)),
4522 "slave port (%d) mac address not set to that of primary port",
4523 test_params->slave_port_ids[1]);
4526 /* Set explicit MAC address */
4527 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4528 test_params->bonded_port_id,
4529 (struct rte_ether_addr *)bonded_mac),
4530 "failed to set MAC address");
4532 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4533 "Failed to get mac address (port %d)",
4534 test_params->bonded_port_id);
4535 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4536 sizeof(read_mac_addr)),
4537 "bonded port (%d) mac address not set to that of bonded port",
4538 test_params->bonded_port_id);
4540 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4541 "Failed to get mac address (port %d)",
4542 test_params->slave_port_ids[0]);
4543 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4544 sizeof(read_mac_addr)),
4545 "slave port (%d) mac address not as expected",
4546 test_params->slave_port_ids[0]);
4548 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4549 "Failed to get mac address (port %d)",
4550 test_params->slave_port_ids[1]);
4551 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4552 sizeof(read_mac_addr)),
4553 "slave port (%d) mac address not set to that of bonded port",
4554 test_params->slave_port_ids[1]);
4556 /* Clean up and remove slaves from bonded device */
4557 return remove_slaves_and_stop_bonded_device();
4561 test_tlb_verify_slave_link_status_change_failover(void)
4563 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4564 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4565 struct rte_eth_stats port_stats;
4567 uint16_t slaves[RTE_MAX_ETHPORTS];
4569 int i, burst_size, slave_count, primary_port;
4573 memset(pkt_burst, 0, sizeof(pkt_burst));
4577 /* Initialize bonded device with 4 slaves in round robin mode */
4578 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4579 BONDING_MODE_TLB, 0,
4580 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4581 "Failed to initialize bonded device with slaves");
4583 /* Verify Current Slaves Count /Active Slave Count is */
4584 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4586 TEST_ASSERT_EQUAL(slave_count, 4,
4587 "Number of slaves (%d) is not as expected (%d).\n",
4590 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4591 slaves, RTE_MAX_ETHPORTS);
4592 TEST_ASSERT_EQUAL(slave_count, (int)4,
4593 "Number of slaves (%d) is not as expected (%d).\n",
4596 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4597 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4598 "Primary port not as expected");
4600 /* Bring 2 slaves down and verify active slave count */
4601 virtual_ethdev_simulate_link_status_interrupt(
4602 test_params->slave_port_ids[1], 0);
4603 virtual_ethdev_simulate_link_status_interrupt(
4604 test_params->slave_port_ids[3], 0);
4606 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4607 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4608 "Number of active slaves (%d) is not as expected (%d).",
4611 virtual_ethdev_simulate_link_status_interrupt(
4612 test_params->slave_port_ids[1], 1);
4613 virtual_ethdev_simulate_link_status_interrupt(
4614 test_params->slave_port_ids[3], 1);
4617 /* Bring primary port down, verify that active slave count is 3 and primary
4619 virtual_ethdev_simulate_link_status_interrupt(
4620 test_params->slave_port_ids[0], 0);
4622 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4623 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4624 "Number of active slaves (%d) is not as expected (%d).",
4627 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4628 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4629 "Primary port not as expected");
4630 rte_delay_us(500000);
4631 /* Verify that pkts are sent on new primary slave */
4632 for (i = 0; i < 4; i++) {
4633 TEST_ASSERT_EQUAL(generate_test_burst(
4634 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4635 "generate_test_burst failed\n");
4636 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4637 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4638 "rte_eth_tx_burst failed\n");
4639 rte_delay_us(11000);
4642 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4643 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4644 "(%d) port_stats.opackets not as expected\n",
4645 test_params->slave_port_ids[0]);
4647 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4648 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4649 "(%d) port_stats.opackets not as expected\n",
4650 test_params->slave_port_ids[1]);
4652 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4653 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4654 "(%d) port_stats.opackets not as expected\n",
4655 test_params->slave_port_ids[2]);
4657 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4658 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4659 "(%d) port_stats.opackets not as expected\n",
4660 test_params->slave_port_ids[3]);
4663 /* Generate packet burst for testing */
4665 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4666 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4670 virtual_ethdev_add_mbufs_to_rx_queue(
4671 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4674 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4675 MAX_PKT_BURST) != burst_size) {
4676 printf("rte_eth_rx_burst\n");
4681 /* Verify bonded device rx count */
4682 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4683 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4684 "(%d) port_stats.ipackets not as expected\n",
4685 test_params->bonded_port_id);
4687 /* Clean up and remove slaves from bonded device */
4688 return remove_slaves_and_stop_bonded_device();
4691 #define TEST_ALB_SLAVE_COUNT 2
4693 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4694 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4695 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4696 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4698 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4699 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4700 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4701 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4702 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4705 test_alb_change_mac_in_reply_sent(void)
4707 struct rte_mbuf *pkt;
4708 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4710 struct rte_ether_hdr *eth_pkt;
4711 struct rte_arp_hdr *arp_pkt;
4713 int slave_idx, nb_pkts, pkt_idx;
4716 struct rte_ether_addr bond_mac, client_mac;
4717 struct rte_ether_addr *slave_mac1, *slave_mac2;
4719 TEST_ASSERT_SUCCESS(
4720 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4721 0, TEST_ALB_SLAVE_COUNT, 1),
4722 "Failed to initialize_bonded_device_with_slaves.");
4724 /* Flush tx queue */
4725 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4726 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4728 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4729 test_params->slave_port_ids[slave_idx], pkts_sent,
4733 rte_ether_addr_copy(
4734 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4738 * Generating four packets with different mac and ip addresses and sending
4739 * them through the bonding port.
4741 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4742 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4743 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4744 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4745 RTE_ETHER_TYPE_ARP, 0, 0);
4746 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4747 sizeof(struct rte_ether_hdr));
4748 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4750 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4752 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4753 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4754 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4755 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4756 RTE_ETHER_TYPE_ARP, 0, 0);
4757 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4758 sizeof(struct rte_ether_hdr));
4759 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4761 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4763 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4764 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4765 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4766 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4767 RTE_ETHER_TYPE_ARP, 0, 0);
4768 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4769 sizeof(struct rte_ether_hdr));
4770 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4772 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4774 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4775 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4776 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4777 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4778 RTE_ETHER_TYPE_ARP, 0, 0);
4779 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4780 sizeof(struct rte_ether_hdr));
4781 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4783 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4786 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4788 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4791 * Checking if packets are properly distributed on bonding ports. Packets
4792 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4794 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4795 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4796 test_params->slave_port_ids[slave_idx], pkts_sent,
4799 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4800 eth_pkt = rte_pktmbuf_mtod(
4801 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4802 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4803 sizeof(struct rte_ether_hdr));
4805 if (slave_idx%2 == 0) {
4806 if (!rte_is_same_ether_addr(slave_mac1,
4807 &arp_pkt->arp_data.arp_sha)) {
4812 if (!rte_is_same_ether_addr(slave_mac2,
4813 &arp_pkt->arp_data.arp_sha)) {
4822 retval += remove_slaves_and_stop_bonded_device();
4827 test_alb_reply_from_client(void)
4829 struct rte_ether_hdr *eth_pkt;
4830 struct rte_arp_hdr *arp_pkt;
4832 struct rte_mbuf *pkt;
4833 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4835 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4838 struct rte_ether_addr bond_mac, client_mac;
4839 struct rte_ether_addr *slave_mac1, *slave_mac2;
4841 TEST_ASSERT_SUCCESS(
4842 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4843 0, TEST_ALB_SLAVE_COUNT, 1),
4844 "Failed to initialize_bonded_device_with_slaves.");
4846 /* Flush tx queue */
4847 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4848 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4849 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4850 test_params->slave_port_ids[slave_idx], pkts_sent,
4854 rte_ether_addr_copy(
4855 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4859 * Generating four packets with different mac and ip addresses and placing
4860 * them in the rx queue to be received by the bonding driver on rx_burst.
4862 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4863 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4864 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4865 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4866 RTE_ETHER_TYPE_ARP, 0, 0);
4867 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4868 sizeof(struct rte_ether_hdr));
4869 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4871 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4874 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4875 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4876 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4877 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4878 RTE_ETHER_TYPE_ARP, 0, 0);
4879 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4880 sizeof(struct rte_ether_hdr));
4881 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4883 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4886 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4887 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4888 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4889 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4890 RTE_ETHER_TYPE_ARP, 0, 0);
4891 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4892 sizeof(struct rte_ether_hdr));
4893 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4895 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4898 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4899 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4900 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4901 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4902 RTE_ETHER_TYPE_ARP, 0, 0);
4903 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4904 sizeof(struct rte_ether_hdr));
4905 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4907 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4911 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4912 * packets to every client in alb table.
4914 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4915 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4917 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4918 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4921 * Checking if update ARP packets were properly send on slave ports.
4923 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4924 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4925 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4926 nb_pkts_sum += nb_pkts;
4928 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4929 eth_pkt = rte_pktmbuf_mtod(
4930 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4931 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4932 sizeof(struct rte_ether_hdr));
4934 if (slave_idx%2 == 0) {
4935 if (!rte_is_same_ether_addr(slave_mac1,
4936 &arp_pkt->arp_data.arp_sha)) {
4941 if (!rte_is_same_ether_addr(slave_mac2,
4942 &arp_pkt->arp_data.arp_sha)) {
4950 /* Check if proper number of packets was send */
4951 if (nb_pkts_sum < 4) {
4957 retval += remove_slaves_and_stop_bonded_device();
4962 test_alb_receive_vlan_reply(void)
4964 struct rte_ether_hdr *eth_pkt;
4965 struct rte_vlan_hdr *vlan_pkt;
4966 struct rte_arp_hdr *arp_pkt;
4968 struct rte_mbuf *pkt;
4969 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4971 int slave_idx, nb_pkts, pkt_idx;
4974 struct rte_ether_addr bond_mac, client_mac;
4976 TEST_ASSERT_SUCCESS(
4977 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4978 0, TEST_ALB_SLAVE_COUNT, 1),
4979 "Failed to initialize_bonded_device_with_slaves.");
4981 /* Flush tx queue */
4982 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4983 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4984 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4985 test_params->slave_port_ids[slave_idx], pkts_sent,
4989 rte_ether_addr_copy(
4990 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4994 * Generating packet with double VLAN header and placing it in the rx queue.
4996 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4997 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4998 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4999 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
5000 RTE_ETHER_TYPE_VLAN, 0, 0);
5001 vlan_pkt = (struct rte_vlan_hdr *)((char *)(eth_pkt + 1));
5002 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
5003 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
5004 vlan_pkt = vlan_pkt+1;
5005 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
5006 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
5007 arp_pkt = (struct rte_arp_hdr *)((char *)(vlan_pkt + 1));
5008 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
5010 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
5013 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
5014 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
5017 * Checking if VLAN headers in generated ARP Update packet are correct.
5019 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
5020 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
5021 test_params->slave_port_ids[slave_idx], pkts_sent,
5024 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
5025 eth_pkt = rte_pktmbuf_mtod(
5026 pkts_sent[pkt_idx], struct rte_ether_hdr *);
5027 vlan_pkt = (struct rte_vlan_hdr *)(
5028 (char *)(eth_pkt + 1));
5029 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
5033 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5034 RTE_ETHER_TYPE_VLAN)) {
5038 vlan_pkt = vlan_pkt+1;
5039 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
5043 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5044 RTE_ETHER_TYPE_ARP)) {
5052 retval += remove_slaves_and_stop_bonded_device();
5057 test_alb_ipv4_tx(void)
5059 int burst_size, retval, pkts_send;
5060 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
5064 TEST_ASSERT_SUCCESS(
5065 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
5066 0, TEST_ALB_SLAVE_COUNT, 1),
5067 "Failed to initialize_bonded_device_with_slaves.");
5071 /* Generate test bursts of packets to transmit */
5072 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
5078 * Checking if ipv4 traffic is transmitted via TLB policy.
5080 pkts_send = rte_eth_tx_burst(
5081 test_params->bonded_port_id, 0, pkt_burst, burst_size);
5082 if (pkts_send != burst_size) {
5088 retval += remove_slaves_and_stop_bonded_device();
5092 static struct unit_test_suite link_bonding_test_suite = {
5093 .suite_name = "Link Bonding Unit Test Suite",
5094 .setup = test_setup,
5095 .teardown = testsuite_teardown,
5096 .unit_test_cases = {
5097 TEST_CASE(test_create_bonded_device),
5098 TEST_CASE(test_create_bonded_device_with_invalid_params),
5099 TEST_CASE(test_add_slave_to_bonded_device),
5100 TEST_CASE(test_add_slave_to_invalid_bonded_device),
5101 TEST_CASE(test_remove_slave_from_bonded_device),
5102 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
5103 TEST_CASE(test_get_slaves_from_bonded_device),
5104 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
5105 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
5106 TEST_CASE(test_start_bonded_device),
5107 TEST_CASE(test_stop_bonded_device),
5108 TEST_CASE(test_set_bonding_mode),
5109 TEST_CASE(test_set_primary_slave),
5110 TEST_CASE(test_set_explicit_bonded_mac),
5111 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
5112 TEST_CASE(test_status_interrupt),
5113 TEST_CASE(test_adding_slave_after_bonded_device_started),
5114 TEST_CASE(test_roundrobin_tx_burst),
5115 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
5116 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
5117 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
5118 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
5119 TEST_CASE(test_roundrobin_verify_mac_assignment),
5120 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
5121 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
5122 TEST_CASE(test_activebackup_tx_burst),
5123 TEST_CASE(test_activebackup_rx_burst),
5124 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
5125 TEST_CASE(test_activebackup_verify_mac_assignment),
5126 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
5127 TEST_CASE(test_balance_xmit_policy_configuration),
5128 TEST_CASE(test_balance_l2_tx_burst),
5129 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
5130 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
5131 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
5132 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
5133 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
5134 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
5135 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
5136 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
5137 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
5138 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
5139 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
5140 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
5141 TEST_CASE(test_balance_rx_burst),
5142 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
5143 TEST_CASE(test_balance_verify_mac_assignment),
5144 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
5145 TEST_CASE(test_tlb_tx_burst),
5146 TEST_CASE(test_tlb_rx_burst),
5147 TEST_CASE(test_tlb_verify_mac_assignment),
5148 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
5149 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
5150 TEST_CASE(test_alb_change_mac_in_reply_sent),
5151 TEST_CASE(test_alb_reply_from_client),
5152 TEST_CASE(test_alb_receive_vlan_reply),
5153 TEST_CASE(test_alb_ipv4_tx),
5154 TEST_CASE(test_broadcast_tx_burst),
5155 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
5156 TEST_CASE(test_broadcast_rx_burst),
5157 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
5158 TEST_CASE(test_broadcast_verify_mac_assignment),
5159 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
5160 TEST_CASE(test_reconfigure_bonded_device),
5161 TEST_CASE(test_close_bonded_device),
5163 TEST_CASES_END() /**< NULL terminate unit test array */
5169 test_link_bonding(void)
5171 return unit_test_suite_runner(&link_bonding_test_suite);
5174 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);