1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
13 #include <sys/queue.h>
15 #include <rte_cycles.h>
16 #include <rte_byteorder.h>
17 #include <rte_common.h>
18 #include <rte_debug.h>
19 #include <rte_ethdev.h>
20 #include <rte_ethdev_driver.h>
22 #include <rte_lcore.h>
23 #include <rte_memory.h>
24 #include <rte_string_fns.h>
25 #include <rte_eth_bond.h>
27 #include "virtual_pmd.h"
28 #include "packet_burst_generator.h"
32 #define TEST_MAX_NUMBER_OF_PORTS (6)
34 #define RX_RING_SIZE 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,
139 .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
142 .mq_mode = ETH_MQ_TX_NONE,
147 static const struct rte_eth_rxconf rx_conf_default = {
149 .pthresh = RX_PTHRESH,
150 .hthresh = RX_HTHRESH,
151 .wthresh = RX_WTHRESH,
153 .rx_free_thresh = RX_FREE_THRESH,
157 static struct rte_eth_txconf tx_conf_default = {
159 .pthresh = TX_PTHRESH,
160 .hthresh = TX_HTHRESH,
161 .wthresh = TX_WTHRESH,
163 .tx_free_thresh = TX_FREE_THRESH,
164 .tx_rs_thresh = TX_RSBIT_THRESH,
167 static void free_virtualpmd_tx_queue(void);
172 configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
177 default_pmd_conf.intr_conf.lsc = 1;
179 default_pmd_conf.intr_conf.lsc = 0;
181 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
182 test_params->nb_tx_q, &default_pmd_conf),
183 "rte_eth_dev_configure for port %d failed", port_id);
185 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
186 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
187 rte_eth_dev_socket_id(port_id), &rx_conf_default,
188 test_params->mbuf_pool) ,
189 "rte_eth_rx_queue_setup for port %d failed", port_id);
191 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
192 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
193 rte_eth_dev_socket_id(port_id), &tx_conf_default),
194 "rte_eth_tx_queue_setup for port %d failed", port_id);
197 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
198 "rte_eth_dev_start for port %d failed", port_id);
203 static int slaves_initialized;
204 static int mac_slaves_initialized;
206 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
207 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
213 int i, nb_mbuf_per_pool;
214 struct rte_ether_addr *mac_addr = (struct rte_ether_addr *)slave_mac;
216 /* Allocate ethernet packet header with space for VLAN header */
217 if (test_params->pkt_eth_hdr == NULL) {
218 test_params->pkt_eth_hdr = malloc(sizeof(struct rte_ether_hdr) +
219 sizeof(struct rte_vlan_hdr));
221 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
222 "Ethernet header struct allocation failed!");
225 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
226 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
227 if (test_params->mbuf_pool == NULL) {
228 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
229 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
230 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
231 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
232 "rte_mempool_create failed");
235 /* Create / Initialize virtual eth devs */
236 if (!slaves_initialized) {
237 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
238 char pmd_name[RTE_ETH_NAME_MAX_LEN];
240 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
242 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
244 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
245 mac_addr, rte_socket_id(), 1);
246 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
247 "Failed to create virtual virtual ethdev %s", pmd_name);
249 TEST_ASSERT_SUCCESS(configure_ethdev(
250 test_params->slave_port_ids[i], 1, 0),
251 "Failed to configure virtual ethdev %s", pmd_name);
253 slaves_initialized = 1;
260 test_create_bonded_device(void)
262 int current_slave_count;
264 uint16_t slaves[RTE_MAX_ETHPORTS];
266 /* Don't try to recreate bonded device if re-running test suite*/
267 if (test_params->bonded_port_id == -1) {
268 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
269 test_params->bonding_mode, rte_socket_id());
271 TEST_ASSERT(test_params->bonded_port_id >= 0,
272 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
274 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
275 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
278 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
279 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
280 test_params->bonded_port_id, test_params->bonding_mode);
282 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
283 slaves, RTE_MAX_ETHPORTS);
285 TEST_ASSERT_EQUAL(current_slave_count, 0,
286 "Number of slaves %d is great than expected %d.",
287 current_slave_count, 0);
289 current_slave_count = rte_eth_bond_active_slaves_get(
290 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
292 TEST_ASSERT_EQUAL(current_slave_count, 0,
293 "Number of active slaves %d is great than expected %d.",
294 current_slave_count, 0);
301 test_create_bonded_device_with_invalid_params(void)
305 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
308 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
310 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
312 test_params->bonding_mode = INVALID_BONDING_MODE;
314 /* Invalid bonding mode */
315 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
317 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
319 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
321 /* Invalid socket id */
322 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
324 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
330 test_add_slave_to_bonded_device(void)
332 int current_slave_count;
334 uint16_t slaves[RTE_MAX_ETHPORTS];
336 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
337 test_params->slave_port_ids[test_params->bonded_slave_count]),
338 "Failed to add slave (%d) to bonded port (%d).",
339 test_params->slave_port_ids[test_params->bonded_slave_count],
340 test_params->bonded_port_id);
342 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
343 slaves, RTE_MAX_ETHPORTS);
344 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
345 "Number of slaves (%d) is greater than expected (%d).",
346 current_slave_count, test_params->bonded_slave_count + 1);
348 current_slave_count = rte_eth_bond_active_slaves_get(
349 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
350 TEST_ASSERT_EQUAL(current_slave_count, 0,
351 "Number of active slaves (%d) is not as expected (%d).\n",
352 current_slave_count, 0);
354 test_params->bonded_slave_count++;
360 test_add_slave_to_invalid_bonded_device(void)
362 /* Invalid port ID */
363 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
364 test_params->slave_port_ids[test_params->bonded_slave_count]),
365 "Expected call to failed as invalid port specified.");
367 /* Non bonded device */
368 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
369 test_params->slave_port_ids[test_params->bonded_slave_count]),
370 "Expected call to failed as invalid port specified.");
377 test_remove_slave_from_bonded_device(void)
379 int current_slave_count;
380 struct rte_ether_addr read_mac_addr, *mac_addr;
381 uint16_t slaves[RTE_MAX_ETHPORTS];
383 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
384 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
385 "Failed to remove slave %d from bonded port (%d).",
386 test_params->slave_port_ids[test_params->bonded_slave_count-1],
387 test_params->bonded_port_id);
390 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
391 slaves, RTE_MAX_ETHPORTS);
393 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
394 "Number of slaves (%d) is great than expected (%d).\n",
395 current_slave_count, test_params->bonded_slave_count - 1);
398 mac_addr = (struct rte_ether_addr *)slave_mac;
399 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] =
400 test_params->bonded_slave_count-1;
402 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(
403 test_params->slave_port_ids[test_params->bonded_slave_count-1],
405 "Failed to get mac address (port %d)",
406 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
407 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
408 "bonded port mac address not set to that of primary port\n");
411 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
413 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
416 test_params->bonded_slave_count--;
422 test_remove_slave_from_invalid_bonded_device(void)
424 /* Invalid port ID */
425 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
426 test_params->bonded_port_id + 5,
427 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
428 "Expected call to failed as invalid port specified.");
430 /* Non bonded device */
431 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
432 test_params->slave_port_ids[0],
433 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
434 "Expected call to failed as invalid port specified.");
439 static int bonded_id = 2;
442 test_add_already_bonded_slave_to_bonded_device(void)
444 int port_id, current_slave_count;
445 uint16_t slaves[RTE_MAX_ETHPORTS];
446 char pmd_name[RTE_ETH_NAME_MAX_LEN];
448 test_add_slave_to_bonded_device();
450 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
451 slaves, RTE_MAX_ETHPORTS);
452 TEST_ASSERT_EQUAL(current_slave_count, 1,
453 "Number of slaves (%d) is not that expected (%d).",
454 current_slave_count, 1);
456 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
458 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
460 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
462 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
463 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
465 "Added slave (%d) to bonded port (%d) unexpectedly.",
466 test_params->slave_port_ids[test_params->bonded_slave_count-1],
469 return test_remove_slave_from_bonded_device();
474 test_get_slaves_from_bonded_device(void)
476 int current_slave_count;
477 uint16_t slaves[RTE_MAX_ETHPORTS];
479 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
480 "Failed to add slave to bonded device");
482 /* Invalid port id */
483 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
485 TEST_ASSERT(current_slave_count < 0,
486 "Invalid port id unexpectedly succeeded");
488 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
489 slaves, RTE_MAX_ETHPORTS);
490 TEST_ASSERT(current_slave_count < 0,
491 "Invalid port id unexpectedly succeeded");
493 /* Invalid slaves pointer */
494 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
495 NULL, RTE_MAX_ETHPORTS);
496 TEST_ASSERT(current_slave_count < 0,
497 "Invalid slave array unexpectedly succeeded");
499 current_slave_count = rte_eth_bond_active_slaves_get(
500 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
501 TEST_ASSERT(current_slave_count < 0,
502 "Invalid slave array unexpectedly succeeded");
504 /* non bonded device*/
505 current_slave_count = rte_eth_bond_slaves_get(
506 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
507 TEST_ASSERT(current_slave_count < 0,
508 "Invalid port id unexpectedly succeeded");
510 current_slave_count = rte_eth_bond_active_slaves_get(
511 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
512 TEST_ASSERT(current_slave_count < 0,
513 "Invalid port id unexpectedly succeeded");
515 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
516 "Failed to remove slaves from bonded device");
523 test_add_remove_multiple_slaves_to_from_bonded_device(void)
527 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
528 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
529 "Failed to add slave to bonded device");
531 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
532 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
533 "Failed to remove slaves from bonded device");
539 enable_bonded_slaves(void)
543 for (i = 0; i < test_params->bonded_slave_count; i++) {
544 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
547 virtual_ethdev_simulate_link_status_interrupt(
548 test_params->slave_port_ids[i], 1);
553 test_start_bonded_device(void)
555 struct rte_eth_link link_status;
557 int current_slave_count, current_bonding_mode, primary_port;
558 uint16_t slaves[RTE_MAX_ETHPORTS];
561 /* Add slave to bonded device*/
562 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
563 "Failed to add slave to bonded device");
565 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
566 "Failed to start bonded pmd eth device %d.",
567 test_params->bonded_port_id);
569 /* Change link status of virtual pmd so it will be added to the active
570 * slave list of the bonded device*/
571 virtual_ethdev_simulate_link_status_interrupt(
572 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
574 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
575 slaves, RTE_MAX_ETHPORTS);
576 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
577 "Number of slaves (%d) is not expected value (%d).",
578 current_slave_count, test_params->bonded_slave_count);
580 current_slave_count = rte_eth_bond_active_slaves_get(
581 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
582 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
583 "Number of active slaves (%d) is not expected value (%d).",
584 current_slave_count, test_params->bonded_slave_count);
586 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
587 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
588 "Bonded device mode (%d) is not expected value (%d).\n",
589 current_bonding_mode, test_params->bonding_mode);
591 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
592 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
593 "Primary port (%d) is not expected value (%d).",
594 primary_port, test_params->slave_port_ids[0]);
596 retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
597 TEST_ASSERT(retval >= 0,
598 "Bonded port (%d) link get failed: %s\n",
599 test_params->bonded_port_id, rte_strerror(-retval));
600 TEST_ASSERT_EQUAL(link_status.link_status, 1,
601 "Bonded port (%d) status (%d) is not expected value (%d).\n",
602 test_params->bonded_port_id, link_status.link_status, 1);
608 test_stop_bonded_device(void)
610 int current_slave_count;
611 uint16_t slaves[RTE_MAX_ETHPORTS];
613 struct rte_eth_link link_status;
616 rte_eth_dev_stop(test_params->bonded_port_id);
618 retval = rte_eth_link_get(test_params->bonded_port_id, &link_status);
619 TEST_ASSERT(retval >= 0,
620 "Bonded port (%d) link get failed: %s\n",
621 test_params->bonded_port_id, rte_strerror(-retval));
622 TEST_ASSERT_EQUAL(link_status.link_status, 0,
623 "Bonded port (%d) status (%d) is not expected value (%d).",
624 test_params->bonded_port_id, link_status.link_status, 0);
626 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
627 slaves, RTE_MAX_ETHPORTS);
628 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
629 "Number of slaves (%d) is not expected value (%d).",
630 current_slave_count, test_params->bonded_slave_count);
632 current_slave_count = rte_eth_bond_active_slaves_get(
633 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
634 TEST_ASSERT_EQUAL(current_slave_count, 0,
635 "Number of active slaves (%d) is not expected value (%d).",
636 current_slave_count, 0);
642 remove_slaves_and_stop_bonded_device(void)
644 /* Clean up and remove slaves from bonded device */
645 free_virtualpmd_tx_queue();
646 while (test_params->bonded_slave_count > 0)
647 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
648 "test_remove_slave_from_bonded_device failed");
650 rte_eth_dev_stop(test_params->bonded_port_id);
651 rte_eth_stats_reset(test_params->bonded_port_id);
652 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
658 test_set_bonding_mode(void)
662 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
663 BONDING_MODE_ACTIVE_BACKUP,
664 BONDING_MODE_BALANCE,
665 BONDING_MODE_BROADCAST
668 /* Test supported link bonding modes */
669 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
670 /* Invalid port ID */
671 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
673 "Expected call to failed as invalid port (%d) specified.",
676 /* Non bonded device */
677 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
679 "Expected call to failed as invalid port (%d) specified.",
680 test_params->slave_port_ids[0]);
682 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
684 "Failed to set link bonding mode on port (%d) to (%d).",
685 test_params->bonded_port_id, bonding_modes[i]);
687 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
688 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
689 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
690 bonding_mode, test_params->bonded_port_id,
693 /* Invalid port ID */
694 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
695 TEST_ASSERT(bonding_mode < 0,
696 "Expected call to failed as invalid port (%d) specified.",
699 /* Non bonded device */
700 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
701 TEST_ASSERT(bonding_mode < 0,
702 "Expected call to failed as invalid port (%d) specified.",
703 test_params->slave_port_ids[0]);
706 return remove_slaves_and_stop_bonded_device();
710 test_set_primary_slave(void)
713 struct rte_ether_addr read_mac_addr;
714 struct rte_ether_addr *expected_mac_addr;
716 /* Add 4 slaves to bonded device */
717 for (i = test_params->bonded_slave_count; i < 4; i++)
718 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
719 "Failed to add slave to bonded device.");
721 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
722 BONDING_MODE_ROUND_ROBIN),
723 "Failed to set link bonding mode on port (%d) to (%d).",
724 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
726 /* Invalid port ID */
727 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
728 test_params->slave_port_ids[i]),
729 "Expected call to failed as invalid port specified.");
731 /* Non bonded device */
732 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
733 test_params->slave_port_ids[i]),
734 "Expected call to failed as invalid port specified.");
736 /* Set slave as primary
737 * Verify slave it is now primary slave
738 * Verify that MAC address of bonded device is that of primary slave
739 * Verify that MAC address of all bonded slaves are that of primary slave
741 for (i = 0; i < 4; i++) {
742 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
743 test_params->slave_port_ids[i]),
744 "Failed to set bonded port (%d) primary port to (%d)",
745 test_params->bonded_port_id, test_params->slave_port_ids[i]);
747 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
748 TEST_ASSERT(retval >= 0,
749 "Failed to read primary port from bonded port (%d)\n",
750 test_params->bonded_port_id);
752 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
753 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
754 test_params->bonded_port_id, retval,
755 test_params->slave_port_ids[i]);
757 /* stop/start bonded eth dev to apply new MAC */
758 rte_eth_dev_stop(test_params->bonded_port_id);
760 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
761 "Failed to start bonded port %d",
762 test_params->bonded_port_id);
764 expected_mac_addr = (struct rte_ether_addr *)&slave_mac;
765 expected_mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
767 /* Check primary slave MAC */
768 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
769 "Failed to get mac address (port %d)",
770 test_params->slave_port_ids[i]);
771 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
772 sizeof(read_mac_addr)),
773 "bonded port mac address not set to that of primary port\n");
775 /* Check bonded MAC */
776 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
777 "Failed to get mac address (port %d)",
778 test_params->bonded_port_id);
779 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
780 sizeof(read_mac_addr)),
781 "bonded port mac address not set to that of primary port\n");
783 /* Check other slaves MACs */
784 for (j = 0; j < 4; j++) {
786 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[j],
788 "Failed to get mac address (port %d)",
789 test_params->slave_port_ids[j]);
790 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
791 sizeof(read_mac_addr)),
792 "slave port mac address not set to that of primary "
799 /* Test with none existent port */
800 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
801 "read primary port from expectedly");
803 /* Test with slave port */
804 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
805 "read primary port from expectedly\n");
807 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
808 "Failed to stop and remove slaves from bonded device");
811 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
812 "read primary port from expectedly\n");
818 test_set_explicit_bonded_mac(void)
821 struct rte_ether_addr read_mac_addr;
822 struct rte_ether_addr *mac_addr;
824 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
826 mac_addr = (struct rte_ether_addr *)explicit_bonded_mac;
828 /* Invalid port ID */
829 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
830 "Expected call to failed as invalid port specified.");
832 /* Non bonded device */
833 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
834 test_params->slave_port_ids[0], mac_addr),
835 "Expected call to failed as invalid port specified.");
837 /* NULL MAC address */
838 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
839 test_params->bonded_port_id, NULL),
840 "Expected call to failed as NULL MAC specified");
842 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
843 test_params->bonded_port_id, mac_addr),
844 "Failed to set MAC address on bonded port (%d)",
845 test_params->bonded_port_id);
847 /* Add 4 slaves to bonded device */
848 for (i = test_params->bonded_slave_count; i < 4; i++) {
849 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
850 "Failed to add slave to bonded device.\n");
853 /* Check bonded MAC */
854 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
855 "Failed to get mac address (port %d)",
856 test_params->bonded_port_id);
857 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
858 "bonded port mac address not set to that of primary port");
860 /* Check other slaves MACs */
861 for (i = 0; i < 4; i++) {
862 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
863 "Failed to get mac address (port %d)",
864 test_params->slave_port_ids[i]);
865 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
866 sizeof(read_mac_addr)),
867 "slave port mac address not set to that of primary port");
870 /* test resetting mac address on bonded device */
872 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
873 "Failed to reset MAC address on bonded port (%d)",
874 test_params->bonded_port_id);
877 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
878 "Reset MAC address on bonded port (%d) unexpectedly",
879 test_params->slave_port_ids[1]);
881 /* test resetting mac address on bonded device with no slaves */
882 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
883 "Failed to remove slaves and stop bonded device");
885 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
886 "Failed to reset MAC address on bonded port (%d)",
887 test_params->bonded_port_id);
892 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
895 test_set_bonded_port_initialization_mac_assignment(void)
899 uint16_t slaves[RTE_MAX_ETHPORTS];
900 static int bonded_port_id = -1;
901 static int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
903 struct rte_ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
905 /* Initialize default values for MAC addresses */
906 memcpy(&slave_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
907 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct rte_ether_addr));
910 * 1. a - Create / configure bonded / slave ethdevs
912 if (bonded_port_id == -1) {
913 bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
914 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
915 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
917 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
918 "Failed to configure bonded ethdev");
921 if (!mac_slaves_initialized) {
922 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
923 char pmd_name[RTE_ETH_NAME_MAX_LEN];
925 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN - 1] =
928 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN,
931 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
932 &slave_mac_addr, rte_socket_id(), 1);
934 TEST_ASSERT(slave_port_ids[i] >= 0,
935 "Failed to create slave ethdev %s",
938 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
939 "Failed to configure virtual ethdev %s",
942 mac_slaves_initialized = 1;
947 * 2. Add slave ethdevs to bonded device
949 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
950 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
952 "Failed to add slave (%d) to bonded port (%d).",
953 slave_port_ids[i], bonded_port_id);
956 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
958 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
959 "Number of slaves (%d) is not as expected (%d)",
960 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
964 * 3. Set explicit MAC address on bonded ethdev
966 bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-2] = 0xFF;
967 bonded_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0xAA;
969 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
970 bonded_port_id, &bonded_mac_addr),
971 "Failed to set MAC address on bonded port (%d)",
975 /* 4. a - Start bonded ethdev
976 * b - Enable slave devices
977 * c - Verify bonded/slaves ethdev MAC addresses
979 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
980 "Failed to start bonded pmd eth device %d.",
983 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
984 virtual_ethdev_simulate_link_status_interrupt(
985 slave_port_ids[i], 1);
988 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(bonded_port_id, &read_mac_addr),
989 "Failed to get mac address (port %d)",
991 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
992 sizeof(read_mac_addr)),
993 "bonded port mac address not as expected");
995 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
996 "Failed to get mac address (port %d)",
998 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
999 sizeof(read_mac_addr)),
1000 "slave port 0 mac address not as expected");
1002 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1003 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1004 "Failed to get mac address (port %d)",
1006 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1007 sizeof(read_mac_addr)),
1008 "slave port 1 mac address not as expected");
1010 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1011 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1012 "Failed to get mac address (port %d)",
1014 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1015 sizeof(read_mac_addr)),
1016 "slave port 2 mac address not as expected");
1019 /* 7. a - Change primary port
1020 * b - Stop / Start bonded port
1021 * d - Verify slave ethdev MAC addresses
1023 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1025 "failed to set primary port on bonded device.");
1027 rte_eth_dev_stop(bonded_port_id);
1028 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1029 "Failed to start bonded pmd eth device %d.",
1032 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(bonded_port_id, &read_mac_addr),
1033 "Failed to get mac address (port %d)",
1035 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1036 sizeof(read_mac_addr)),
1037 "bonded port mac address not as expected");
1039 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1040 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1041 "Failed to get mac address (port %d)",
1043 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1044 sizeof(read_mac_addr)),
1045 "slave port 0 mac address not as expected");
1047 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1048 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1049 "Failed to get mac address (port %d)",
1051 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1052 sizeof(read_mac_addr)),
1053 "slave port 1 mac address not as expected");
1055 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1056 "Failed to get mac address (port %d)",
1058 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1059 sizeof(read_mac_addr)),
1060 "slave port 2 mac address not as expected");
1062 /* 6. a - Stop bonded ethdev
1063 * b - remove slave ethdevs
1064 * c - Verify slave ethdevs MACs are restored
1066 rte_eth_dev_stop(bonded_port_id);
1068 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1069 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1071 "Failed to remove slave %d from bonded port (%d).",
1072 slave_port_ids[i], bonded_port_id);
1075 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1078 TEST_ASSERT_EQUAL(slave_count, 0,
1079 "Number of slaves (%d) is great than expected (%d).",
1082 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 0 + 100;
1083 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr),
1084 "Failed to get mac address (port %d)",
1086 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1087 sizeof(read_mac_addr)),
1088 "slave port 0 mac address not as expected");
1090 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 1 + 100;
1091 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr),
1092 "Failed to get mac address (port %d)",
1094 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1095 sizeof(read_mac_addr)),
1096 "slave port 1 mac address not as expected");
1098 slave_mac_addr.addr_bytes[RTE_ETHER_ADDR_LEN-1] = 2 + 100;
1099 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr),
1100 "Failed to get mac address (port %d)",
1102 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1103 sizeof(read_mac_addr)),
1104 "slave port 2 mac address not as expected");
1111 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1112 uint16_t number_of_slaves, uint8_t enable_slave)
1114 /* Configure bonded device */
1115 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1116 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1117 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1120 /* Add slaves to bonded device */
1121 while (number_of_slaves > test_params->bonded_slave_count)
1122 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1123 "Failed to add slave (%d to bonding port (%d).",
1124 test_params->bonded_slave_count - 1,
1125 test_params->bonded_port_id);
1127 /* Set link bonding mode */
1128 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1130 "Failed to set link bonding mode on port (%d) to (%d).",
1131 test_params->bonded_port_id, bonding_mode);
1133 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1134 "Failed to start bonded pmd eth device %d.",
1135 test_params->bonded_port_id);
1138 enable_bonded_slaves();
1144 test_adding_slave_after_bonded_device_started(void)
1148 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1149 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1150 "Failed to add slaves to bonded device");
1152 /* Enabled slave devices */
1153 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1154 virtual_ethdev_simulate_link_status_interrupt(
1155 test_params->slave_port_ids[i], 1);
1158 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1159 test_params->slave_port_ids[test_params->bonded_slave_count]),
1160 "Failed to add slave to bonded port.\n");
1162 rte_eth_stats_reset(
1163 test_params->slave_port_ids[test_params->bonded_slave_count]);
1165 test_params->bonded_slave_count++;
1167 return remove_slaves_and_stop_bonded_device();
1170 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1171 #define TEST_LSC_WAIT_TIMEOUT_US 500000
1173 int test_lsc_interrupt_count;
1177 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1178 enum rte_eth_event_type type __rte_unused,
1179 void *param __rte_unused,
1180 void *ret_param __rte_unused)
1182 pthread_mutex_lock(&mutex);
1183 test_lsc_interrupt_count++;
1185 pthread_cond_signal(&cvar);
1186 pthread_mutex_unlock(&mutex);
1192 lsc_timeout(int wait_us)
1199 gettimeofday(&tp, NULL);
1201 /* Convert from timeval to timespec */
1202 ts.tv_sec = tp.tv_sec;
1203 ts.tv_nsec = tp.tv_usec * 1000;
1204 ts.tv_nsec += wait_us * 1000;
1205 /* Normalize tv_nsec to [0,999999999L] */
1206 while (ts.tv_nsec > 1000000000L) {
1207 ts.tv_nsec -= 1000000000L;
1211 pthread_mutex_lock(&mutex);
1212 if (test_lsc_interrupt_count < 1)
1213 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1215 pthread_mutex_unlock(&mutex);
1217 if (retval == 0 && test_lsc_interrupt_count < 1)
1224 test_status_interrupt(void)
1227 uint16_t slaves[RTE_MAX_ETHPORTS];
1229 /* initialized bonding device with T slaves */
1230 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1231 BONDING_MODE_ROUND_ROBIN, 1,
1232 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1233 "Failed to initialise bonded device");
1235 test_lsc_interrupt_count = 0;
1237 /* register link status change interrupt callback */
1238 rte_eth_dev_callback_register(test_params->bonded_port_id,
1239 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1240 &test_params->bonded_port_id);
1242 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1243 slaves, RTE_MAX_ETHPORTS);
1245 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1246 "Number of active slaves (%d) is not as expected (%d)",
1247 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1249 /* Bring all 4 slaves link status to down and test that we have received a
1251 virtual_ethdev_simulate_link_status_interrupt(
1252 test_params->slave_port_ids[0], 0);
1253 virtual_ethdev_simulate_link_status_interrupt(
1254 test_params->slave_port_ids[1], 0);
1255 virtual_ethdev_simulate_link_status_interrupt(
1256 test_params->slave_port_ids[2], 0);
1258 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1259 "Received a link status change interrupt unexpectedly");
1261 virtual_ethdev_simulate_link_status_interrupt(
1262 test_params->slave_port_ids[3], 0);
1264 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) == 0,
1265 "timed out waiting for interrupt");
1267 TEST_ASSERT(test_lsc_interrupt_count > 0,
1268 "Did not receive link status change interrupt");
1270 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1271 slaves, RTE_MAX_ETHPORTS);
1273 TEST_ASSERT_EQUAL(slave_count, 0,
1274 "Number of active slaves (%d) is not as expected (%d)",
1277 /* bring one slave port up so link status will change */
1278 test_lsc_interrupt_count = 0;
1280 virtual_ethdev_simulate_link_status_interrupt(
1281 test_params->slave_port_ids[0], 1);
1283 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) == 0,
1284 "timed out waiting for interrupt");
1286 /* test that we have received another lsc interrupt */
1287 TEST_ASSERT(test_lsc_interrupt_count > 0,
1288 "Did not receive link status change interrupt");
1290 /* Verify that calling the same slave lsc interrupt doesn't cause another
1291 * lsc interrupt from bonded device */
1292 test_lsc_interrupt_count = 0;
1294 virtual_ethdev_simulate_link_status_interrupt(
1295 test_params->slave_port_ids[0], 1);
1297 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_US) != 0,
1298 "received unexpected interrupt");
1300 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1301 "Did not receive link status change interrupt");
1304 /* unregister lsc callback before exiting */
1305 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1306 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1307 &test_params->bonded_port_id);
1309 /* Clean up and remove slaves from bonded device */
1310 return remove_slaves_and_stop_bonded_device();
1314 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1315 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1316 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1318 uint16_t pktlen, generated_burst_size, ether_type;
1322 ether_type = RTE_ETHER_TYPE_IPV4;
1324 ether_type = RTE_ETHER_TYPE_IPV6;
1327 initialize_eth_header(test_params->pkt_eth_hdr,
1328 (struct rte_ether_addr *)src_mac,
1329 (struct rte_ether_addr *)dst_mac_1,
1330 ether_type, vlan, vlan_id);
1332 initialize_eth_header(test_params->pkt_eth_hdr,
1333 (struct rte_ether_addr *)src_mac,
1334 (struct rte_ether_addr *)dst_mac_0,
1335 ether_type, vlan, vlan_id);
1338 if (toggle_udp_port)
1339 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1342 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1347 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1348 dst_addr_1, pktlen);
1350 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1351 dst_addr_0, pktlen);
1353 ip_hdr = test_params->pkt_ipv4_hdr;
1356 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1357 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1360 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1361 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1364 ip_hdr = test_params->pkt_ipv6_hdr;
1367 /* Generate burst of packets to transmit */
1368 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1369 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1370 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1372 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1373 "Failed to generate packet burst");
1375 return generated_burst_size;
1378 /** Round Robin Mode Tests */
1381 test_roundrobin_tx_burst(void)
1384 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1385 struct rte_eth_stats port_stats;
1387 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1388 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1389 "Failed to initialise bonded device");
1391 burst_size = 20 * test_params->bonded_slave_count;
1393 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1394 "Burst size specified is greater than supported.");
1396 /* Generate test bursts of packets to transmit */
1397 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1398 burst_size, "failed to generate test burst");
1400 /* Send burst on bonded port */
1401 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1402 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1405 /* Verify bonded port tx stats */
1406 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1407 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1408 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1409 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1412 /* Verify slave ports tx stats */
1413 for (i = 0; i < test_params->bonded_slave_count; i++) {
1414 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1415 TEST_ASSERT_EQUAL(port_stats.opackets,
1416 (uint64_t)burst_size / test_params->bonded_slave_count,
1417 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1418 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1419 burst_size / test_params->bonded_slave_count);
1422 /* Put all slaves down and try and transmit */
1423 for (i = 0; i < test_params->bonded_slave_count; i++) {
1424 virtual_ethdev_simulate_link_status_interrupt(
1425 test_params->slave_port_ids[i], 0);
1428 /* Send burst on bonded port */
1429 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1430 pkt_burst, burst_size), 0,
1431 "tx burst return unexpected value");
1433 /* Clean up and remove slaves from bonded device */
1434 return remove_slaves_and_stop_bonded_device();
1438 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1442 for (i = 0; i < nb_mbufs; i++) {
1443 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1444 TEST_ASSERT_EQUAL(refcnt, val,
1445 "mbuf ref count (%d)is not the expected value (%d)",
1452 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1456 for (i = 0; i < nb_mbufs; i++)
1457 rte_pktmbuf_free(mbufs[i]);
1460 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1461 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1462 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1463 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1466 test_roundrobin_tx_burst_slave_tx_fail(void)
1468 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1469 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1471 struct rte_eth_stats port_stats;
1473 int i, first_fail_idx, tx_count;
1475 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1476 BONDING_MODE_ROUND_ROBIN, 0,
1477 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1478 "Failed to initialise bonded device");
1480 /* Generate test bursts of packets to transmit */
1481 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1482 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1483 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1484 "Failed to generate test packet burst");
1486 /* Copy references to packets which we expect not to be transmitted */
1487 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1488 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1489 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1490 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1492 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1493 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1494 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1497 /* Set virtual slave to only fail transmission of
1498 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1499 virtual_ethdev_tx_burst_fn_set_success(
1500 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1503 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1504 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1505 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1507 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1508 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1510 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1511 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1512 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1513 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1514 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1516 /* Verify that failed packet are expected failed packets */
1517 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1518 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1519 "expected mbuf (%d) pointer %p not expected pointer %p",
1520 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1523 /* Verify bonded port tx stats */
1524 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1526 TEST_ASSERT_EQUAL(port_stats.opackets,
1527 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1528 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1529 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1530 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1531 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1532 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1534 /* Verify slave ports tx stats */
1535 for (i = 0; i < test_params->bonded_slave_count; i++) {
1536 int slave_expected_tx_count;
1538 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1540 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1541 test_params->bonded_slave_count;
1543 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1544 slave_expected_tx_count = slave_expected_tx_count -
1545 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1547 TEST_ASSERT_EQUAL(port_stats.opackets,
1548 (uint64_t)slave_expected_tx_count,
1549 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1550 test_params->slave_port_ids[i],
1551 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1554 /* Verify that all mbufs have a ref value of zero */
1555 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1556 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1557 "mbufs refcnts not as expected");
1558 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1560 /* Clean up and remove slaves from bonded device */
1561 return remove_slaves_and_stop_bonded_device();
1565 test_roundrobin_rx_burst_on_single_slave(void)
1567 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1568 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1570 struct rte_eth_stats port_stats;
1572 int i, j, burst_size = 25;
1574 /* Initialize bonded device with 4 slaves in round robin mode */
1575 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1576 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1577 "Failed to initialize bonded device with slaves");
1579 /* Generate test bursts of packets to transmit */
1580 TEST_ASSERT_EQUAL(generate_test_burst(
1581 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1582 "burst generation failed");
1584 for (i = 0; i < test_params->bonded_slave_count; i++) {
1585 /* Add rx data to slave */
1586 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1587 &gen_pkt_burst[0], burst_size);
1589 /* Call rx burst on bonded device */
1590 /* Send burst on bonded port */
1591 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1592 test_params->bonded_port_id, 0, rx_pkt_burst,
1593 MAX_PKT_BURST), burst_size,
1594 "round-robin rx burst failed");
1596 /* Verify bonded device rx count */
1597 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1598 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1599 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1600 test_params->bonded_port_id,
1601 (unsigned int)port_stats.ipackets, burst_size);
1605 /* Verify bonded slave devices rx count */
1606 /* Verify slave ports tx stats */
1607 for (j = 0; j < test_params->bonded_slave_count; j++) {
1608 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1611 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1612 "Slave Port (%d) ipackets value (%u) not as expected"
1613 " (%d)", test_params->slave_port_ids[i],
1614 (unsigned int)port_stats.ipackets, burst_size);
1616 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1617 "Slave Port (%d) ipackets value (%u) not as expected"
1618 " (%d)", test_params->slave_port_ids[i],
1619 (unsigned int)port_stats.ipackets, 0);
1622 /* Reset bonded slaves stats */
1623 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1625 /* reset bonded device stats */
1626 rte_eth_stats_reset(test_params->bonded_port_id);
1630 for (i = 0; i < MAX_PKT_BURST; i++) {
1631 if (rx_pkt_burst[i] != NULL)
1632 rte_pktmbuf_free(rx_pkt_burst[i]);
1636 /* Clean up and remove slaves from bonded device */
1637 return remove_slaves_and_stop_bonded_device();
1640 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1643 test_roundrobin_rx_burst_on_multiple_slaves(void)
1645 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1647 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1648 struct rte_eth_stats port_stats;
1650 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1653 /* Initialize bonded device with 4 slaves in round robin mode */
1654 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1655 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1656 "Failed to initialize bonded device with slaves");
1658 /* Generate test bursts of packets to transmit */
1659 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1660 TEST_ASSERT_EQUAL(generate_test_burst(
1661 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1662 burst_size[i], "burst generation failed");
1665 /* Add rx data to slaves */
1666 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1667 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1668 &gen_pkt_burst[i][0], burst_size[i]);
1671 /* Call rx burst on bonded device */
1672 /* Send burst on bonded port */
1673 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1675 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1676 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1677 burst_size[0] + burst_size[1] + burst_size[2]);
1679 /* Verify bonded device rx count */
1680 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1681 TEST_ASSERT_EQUAL(port_stats.ipackets,
1682 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1683 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1684 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1685 burst_size[0] + burst_size[1] + burst_size[2]);
1687 /* Verify bonded slave devices rx counts */
1688 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1689 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1690 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1691 test_params->slave_port_ids[0],
1692 (unsigned int)port_stats.ipackets, burst_size[0]);
1694 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1695 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1696 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1697 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1700 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1701 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1702 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1703 test_params->slave_port_ids[2],
1704 (unsigned int)port_stats.ipackets, burst_size[2]);
1706 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1707 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1708 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1709 test_params->slave_port_ids[3],
1710 (unsigned int)port_stats.ipackets, 0);
1713 for (i = 0; i < MAX_PKT_BURST; i++) {
1714 if (rx_pkt_burst[i] != NULL)
1715 rte_pktmbuf_free(rx_pkt_burst[i]);
1718 /* Clean up and remove slaves from bonded device */
1719 return remove_slaves_and_stop_bonded_device();
1723 test_roundrobin_verify_mac_assignment(void)
1725 struct rte_ether_addr read_mac_addr;
1726 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_2;
1730 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
1731 "Failed to get mac address (port %d)",
1732 test_params->slave_port_ids[0]);
1733 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2),
1734 "Failed to get mac address (port %d)",
1735 test_params->slave_port_ids[2]);
1737 /* Initialize bonded device with 4 slaves in round robin mode */
1738 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1739 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1740 "Failed to initialize bonded device with slaves");
1742 /* Verify that all MACs are the same as first slave added to bonded dev */
1743 for (i = 0; i < test_params->bonded_slave_count; i++) {
1744 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1745 "Failed to get mac address (port %d)",
1746 test_params->slave_port_ids[i]);
1747 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1748 sizeof(read_mac_addr)),
1749 "slave port (%d) mac address not set to that of primary port",
1750 test_params->slave_port_ids[i]);
1753 /* change primary and verify that MAC addresses haven't changed */
1754 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1755 test_params->slave_port_ids[2]),
1756 "Failed to set bonded port (%d) primary port to (%d)",
1757 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1759 for (i = 0; i < test_params->bonded_slave_count; i++) {
1760 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1761 "Failed to get mac address (port %d)",
1762 test_params->slave_port_ids[i]);
1763 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1764 sizeof(read_mac_addr)),
1765 "slave port (%d) mac address has changed to that of primary"
1766 " port without stop/start toggle of bonded device",
1767 test_params->slave_port_ids[i]);
1770 /* stop / start bonded device and verify that primary MAC address is
1771 * propagate to bonded device and slaves */
1772 rte_eth_dev_stop(test_params->bonded_port_id);
1774 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1775 "Failed to start bonded device");
1777 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1778 "Failed to get mac address (port %d)",
1779 test_params->bonded_port_id);
1780 TEST_ASSERT_SUCCESS(
1781 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1782 "bonded port (%d) mac address not set to that of new primary port",
1783 test_params->slave_port_ids[i]);
1785 for (i = 0; i < test_params->bonded_slave_count; i++) {
1786 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1787 "Failed to get mac address (port %d)",
1788 test_params->slave_port_ids[i]);
1789 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1790 sizeof(read_mac_addr)),
1791 "slave port (%d) mac address not set to that of new primary"
1792 " port", test_params->slave_port_ids[i]);
1795 /* Set explicit MAC address */
1796 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1797 test_params->bonded_port_id,
1798 (struct rte_ether_addr *)bonded_mac),
1799 "Failed to set MAC");
1801 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1802 "Failed to get mac address (port %d)",
1803 test_params->bonded_port_id);
1804 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1805 sizeof(read_mac_addr)),
1806 "bonded port (%d) mac address not set to that of new primary port",
1807 test_params->slave_port_ids[i]);
1809 for (i = 0; i < test_params->bonded_slave_count; i++) {
1810 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1811 "Failed to get mac address (port %d)",
1812 test_params->slave_port_ids[i]);
1813 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1814 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1815 " that of new primary port\n", test_params->slave_port_ids[i]);
1818 /* Clean up and remove slaves from bonded device */
1819 return remove_slaves_and_stop_bonded_device();
1823 test_roundrobin_verify_promiscuous_enable_disable(void)
1825 int i, promiscuous_en;
1828 /* Initialize bonded device with 4 slaves in round robin mode */
1829 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1830 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1831 "Failed to initialize bonded device with slaves");
1833 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
1834 TEST_ASSERT_SUCCESS(ret,
1835 "Failed to enable promiscuous mode for port %d: %s",
1836 test_params->bonded_port_id, rte_strerror(-ret));
1838 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1839 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1840 "Port (%d) promiscuous mode not enabled",
1841 test_params->bonded_port_id);
1843 for (i = 0; i < test_params->bonded_slave_count; i++) {
1844 promiscuous_en = rte_eth_promiscuous_get(
1845 test_params->slave_port_ids[i]);
1846 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1847 "slave port (%d) promiscuous mode not enabled",
1848 test_params->slave_port_ids[i]);
1851 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
1852 TEST_ASSERT_SUCCESS(ret,
1853 "Failed to disable promiscuous mode for port %d: %s",
1854 test_params->bonded_port_id, rte_strerror(-ret));
1856 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1857 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1858 "Port (%d) promiscuous mode not disabled\n",
1859 test_params->bonded_port_id);
1861 for (i = 0; i < test_params->bonded_slave_count; i++) {
1862 promiscuous_en = rte_eth_promiscuous_get(
1863 test_params->slave_port_ids[i]);
1864 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1865 "Port (%d) promiscuous mode not disabled\n",
1866 test_params->slave_port_ids[i]);
1869 /* Clean up and remove slaves from bonded device */
1870 return remove_slaves_and_stop_bonded_device();
1873 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1874 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1877 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1879 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1880 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1881 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1883 struct rte_eth_stats port_stats;
1884 uint16_t slaves[RTE_MAX_ETHPORTS];
1886 int i, burst_size, slave_count;
1888 /* NULL all pointers in array to simplify cleanup */
1889 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1891 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1892 * in round robin mode */
1893 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1894 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1895 "Failed to initialize bonded device with slaves");
1897 /* Verify Current Slaves Count /Active Slave Count is */
1898 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1900 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1901 "Number of slaves (%d) is not as expected (%d).",
1902 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1904 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1905 slaves, RTE_MAX_ETHPORTS);
1906 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1907 "Number of active slaves (%d) is not as expected (%d).",
1908 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1910 /* Set 2 slaves eth_devs link status to down */
1911 virtual_ethdev_simulate_link_status_interrupt(
1912 test_params->slave_port_ids[1], 0);
1913 virtual_ethdev_simulate_link_status_interrupt(
1914 test_params->slave_port_ids[3], 0);
1916 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1917 slaves, RTE_MAX_ETHPORTS);
1918 TEST_ASSERT_EQUAL(slave_count,
1919 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1920 "Number of active slaves (%d) is not as expected (%d).\n",
1921 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1925 /* Verify that pkts are not sent on slaves with link status down:
1927 * 1. Generate test burst of traffic
1928 * 2. Transmit burst on bonded eth_dev
1929 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1930 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1933 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1934 burst_size, "generate_test_burst failed");
1936 rte_eth_stats_reset(test_params->bonded_port_id);
1940 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1941 burst_size), burst_size, "rte_eth_tx_burst failed");
1943 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1944 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1945 "Port (%d) opackets stats (%d) not expected (%d) value",
1946 test_params->bonded_port_id, (int)port_stats.opackets,
1949 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1950 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1951 "Port (%d) opackets stats (%d) not expected (%d) value",
1952 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1954 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1955 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1956 "Port (%d) opackets stats (%d) not expected (%d) value",
1957 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1959 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1960 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1961 "Port (%d) opackets stats (%d) not expected (%d) value",
1962 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1964 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1965 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1966 "Port (%d) opackets stats (%d) not expected (%d) value",
1967 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1969 /* Verify that pkts are not sent on slaves with link status down:
1971 * 1. Generate test bursts of traffic
1972 * 2. Add bursts on to virtual eth_devs
1973 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1974 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1975 * 4. Verify stats for bonded eth_dev
1976 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1978 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1979 TEST_ASSERT_EQUAL(generate_test_burst(
1980 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1981 burst_size, "failed to generate packet burst");
1983 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1984 &gen_pkt_burst[i][0], burst_size);
1987 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1988 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1989 burst_size + burst_size,
1990 "rte_eth_rx_burst failed");
1992 /* Verify bonded device rx count */
1993 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1994 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1995 "(%d) port_stats.ipackets not as expected\n",
1996 test_params->bonded_port_id);
1999 for (i = 0; i < MAX_PKT_BURST; i++) {
2000 if (rx_pkt_burst[i] != NULL)
2001 rte_pktmbuf_free(rx_pkt_burst[i]);
2004 /* Clean up and remove slaves from bonded device */
2005 return remove_slaves_and_stop_bonded_device();
2008 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
2010 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
2013 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2016 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2018 struct rte_ether_addr *mac_addr =
2019 (struct rte_ether_addr *)polling_slave_mac;
2020 char slave_name[RTE_ETH_NAME_MAX_LEN];
2024 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2025 /* Generate slave name / MAC address */
2026 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2027 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
2029 /* Create slave devices with no ISR Support */
2030 if (polling_test_slaves[i] == -1) {
2031 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2032 rte_socket_id(), 0);
2033 TEST_ASSERT(polling_test_slaves[i] >= 0,
2034 "Failed to create virtual virtual ethdev %s\n", slave_name);
2036 /* Configure slave */
2037 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2038 "Failed to configure virtual ethdev %s(%d)", slave_name,
2039 polling_test_slaves[i]);
2042 /* Add slave to bonded device */
2043 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2044 polling_test_slaves[i]),
2045 "Failed to add slave %s(%d) to bonded device %d",
2046 slave_name, polling_test_slaves[i],
2047 test_params->bonded_port_id);
2050 /* Initialize bonded device */
2051 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2052 "Failed to configure bonded device %d",
2053 test_params->bonded_port_id);
2056 /* Register link status change interrupt callback */
2057 rte_eth_dev_callback_register(test_params->bonded_port_id,
2058 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2059 &test_params->bonded_port_id);
2061 /* link status change callback for first slave link up */
2062 test_lsc_interrupt_count = 0;
2064 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2066 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2069 /* no link status change callback for second slave link up */
2070 test_lsc_interrupt_count = 0;
2072 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2074 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2076 /* link status change callback for both slave links down */
2077 test_lsc_interrupt_count = 0;
2079 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2080 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2082 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2084 /* Un-Register link status change interrupt callback */
2085 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2086 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2087 &test_params->bonded_port_id);
2090 /* Clean up and remove slaves from bonded device */
2091 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2093 TEST_ASSERT_SUCCESS(
2094 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2095 polling_test_slaves[i]),
2096 "Failed to remove slave %d from bonded port (%d)",
2097 polling_test_slaves[i], test_params->bonded_port_id);
2100 return remove_slaves_and_stop_bonded_device();
2104 /** Active Backup Mode Tests */
2107 test_activebackup_tx_burst(void)
2109 int i, pktlen, primary_port, burst_size;
2110 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2111 struct rte_eth_stats port_stats;
2113 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2114 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2115 "Failed to initialize bonded device with slaves");
2117 initialize_eth_header(test_params->pkt_eth_hdr,
2118 (struct rte_ether_addr *)src_mac,
2119 (struct rte_ether_addr *)dst_mac_0,
2120 RTE_ETHER_TYPE_IPV4, 0, 0);
2121 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2123 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2124 dst_addr_0, pktlen);
2126 burst_size = 20 * test_params->bonded_slave_count;
2128 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2129 "Burst size specified is greater than supported.");
2131 /* Generate a burst of packets to transmit */
2132 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2133 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2134 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2135 burst_size, "failed to generate burst correctly");
2137 /* Send burst on bonded port */
2138 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2139 burst_size), burst_size, "tx burst failed");
2141 /* Verify bonded port tx stats */
2142 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2143 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2144 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2145 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2148 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2150 /* Verify slave ports tx stats */
2151 for (i = 0; i < test_params->bonded_slave_count; i++) {
2152 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2153 if (test_params->slave_port_ids[i] == primary_port) {
2154 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2155 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2156 test_params->bonded_port_id,
2157 (unsigned int)port_stats.opackets,
2158 burst_size / test_params->bonded_slave_count);
2160 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2161 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2162 test_params->bonded_port_id,
2163 (unsigned int)port_stats.opackets, 0);
2167 /* Put all slaves down and try and transmit */
2168 for (i = 0; i < test_params->bonded_slave_count; i++) {
2169 virtual_ethdev_simulate_link_status_interrupt(
2170 test_params->slave_port_ids[i], 0);
2173 /* Send burst on bonded port */
2174 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2175 pkts_burst, burst_size), 0, "Sending empty burst failed");
2177 /* Clean up and remove slaves from bonded device */
2178 return remove_slaves_and_stop_bonded_device();
2181 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2184 test_activebackup_rx_burst(void)
2186 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2187 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2189 struct rte_eth_stats port_stats;
2193 int i, j, burst_size = 17;
2195 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2196 BONDING_MODE_ACTIVE_BACKUP, 0,
2197 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2198 "Failed to initialize bonded device with slaves");
2200 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2201 TEST_ASSERT(primary_port >= 0,
2202 "failed to get primary slave for bonded port (%d)",
2203 test_params->bonded_port_id);
2205 for (i = 0; i < test_params->bonded_slave_count; i++) {
2206 /* Generate test bursts of packets to transmit */
2207 TEST_ASSERT_EQUAL(generate_test_burst(
2208 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2209 burst_size, "burst generation failed");
2211 /* Add rx data to slave */
2212 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2213 &gen_pkt_burst[0], burst_size);
2215 /* Call rx burst on bonded device */
2216 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2217 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2218 "rte_eth_rx_burst failed");
2220 if (test_params->slave_port_ids[i] == primary_port) {
2221 /* Verify bonded device rx count */
2222 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2223 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2224 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2225 test_params->bonded_port_id,
2226 (unsigned int)port_stats.ipackets, burst_size);
2228 /* Verify bonded slave devices rx count */
2229 for (j = 0; j < test_params->bonded_slave_count; j++) {
2230 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2232 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2233 "Slave Port (%d) ipackets value (%u) not as "
2234 "expected (%d)", test_params->slave_port_ids[i],
2235 (unsigned int)port_stats.ipackets, burst_size);
2237 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2238 "Slave Port (%d) ipackets value (%u) not as "
2239 "expected (%d)\n", test_params->slave_port_ids[i],
2240 (unsigned int)port_stats.ipackets, 0);
2244 for (j = 0; j < test_params->bonded_slave_count; j++) {
2245 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2246 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2247 "Slave Port (%d) ipackets value (%u) not as expected "
2248 "(%d)", test_params->slave_port_ids[i],
2249 (unsigned int)port_stats.ipackets, 0);
2254 for (i = 0; i < MAX_PKT_BURST; i++) {
2255 if (rx_pkt_burst[i] != NULL) {
2256 rte_pktmbuf_free(rx_pkt_burst[i]);
2257 rx_pkt_burst[i] = NULL;
2261 /* reset bonded device stats */
2262 rte_eth_stats_reset(test_params->bonded_port_id);
2265 /* Clean up and remove slaves from bonded device */
2266 return remove_slaves_and_stop_bonded_device();
2270 test_activebackup_verify_promiscuous_enable_disable(void)
2272 int i, primary_port, promiscuous_en;
2275 /* Initialize bonded device with 4 slaves in round robin mode */
2276 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2277 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2278 "Failed to initialize bonded device with slaves");
2280 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2281 TEST_ASSERT(primary_port >= 0,
2282 "failed to get primary slave for bonded port (%d)",
2283 test_params->bonded_port_id);
2285 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
2286 TEST_ASSERT_SUCCESS(ret,
2287 "Failed to enable promiscuous mode for port %d: %s",
2288 test_params->bonded_port_id, rte_strerror(-ret));
2290 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2291 "Port (%d) promiscuous mode not enabled",
2292 test_params->bonded_port_id);
2294 for (i = 0; i < test_params->bonded_slave_count; i++) {
2295 promiscuous_en = rte_eth_promiscuous_get(
2296 test_params->slave_port_ids[i]);
2297 if (primary_port == test_params->slave_port_ids[i]) {
2298 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2299 "slave port (%d) promiscuous mode not enabled",
2300 test_params->slave_port_ids[i]);
2302 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2303 "slave port (%d) promiscuous mode enabled",
2304 test_params->slave_port_ids[i]);
2309 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
2310 TEST_ASSERT_SUCCESS(ret,
2311 "Failed to disable promiscuous mode for port %d: %s",
2312 test_params->bonded_port_id, rte_strerror(-ret));
2314 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2315 "Port (%d) promiscuous mode not disabled\n",
2316 test_params->bonded_port_id);
2318 for (i = 0; i < test_params->bonded_slave_count; i++) {
2319 promiscuous_en = rte_eth_promiscuous_get(
2320 test_params->slave_port_ids[i]);
2321 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2322 "slave port (%d) promiscuous mode not disabled\n",
2323 test_params->slave_port_ids[i]);
2326 /* Clean up and remove slaves from bonded device */
2327 return remove_slaves_and_stop_bonded_device();
2331 test_activebackup_verify_mac_assignment(void)
2333 struct rte_ether_addr read_mac_addr;
2334 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
2336 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
2337 "Failed to get mac address (port %d)",
2338 test_params->slave_port_ids[0]);
2339 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
2340 "Failed to get mac address (port %d)",
2341 test_params->slave_port_ids[1]);
2343 /* Initialize bonded device with 2 slaves in active backup mode */
2344 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2345 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2346 "Failed to initialize bonded device with slaves");
2348 /* Verify that bonded MACs is that of first slave and that the other slave
2349 * MAC hasn't been changed */
2350 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2351 "Failed to get mac address (port %d)",
2352 test_params->bonded_port_id);
2353 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2354 sizeof(read_mac_addr)),
2355 "bonded port (%d) mac address not set to that of primary port",
2356 test_params->bonded_port_id);
2358 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2359 "Failed to get mac address (port %d)",
2360 test_params->slave_port_ids[0]);
2361 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2362 sizeof(read_mac_addr)),
2363 "slave port (%d) mac address not set to that of primary port",
2364 test_params->slave_port_ids[0]);
2366 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2367 "Failed to get mac address (port %d)",
2368 test_params->slave_port_ids[1]);
2369 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2370 sizeof(read_mac_addr)),
2371 "slave port (%d) mac address not as expected",
2372 test_params->slave_port_ids[1]);
2374 /* change primary and verify that MAC addresses haven't changed */
2375 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2376 test_params->slave_port_ids[1]), 0,
2377 "Failed to set bonded port (%d) primary port to (%d)",
2378 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2380 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2381 "Failed to get mac address (port %d)",
2382 test_params->bonded_port_id);
2383 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2384 sizeof(read_mac_addr)),
2385 "bonded port (%d) mac address not set to that of primary port",
2386 test_params->bonded_port_id);
2388 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2389 "Failed to get mac address (port %d)",
2390 test_params->slave_port_ids[0]);
2391 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2392 sizeof(read_mac_addr)),
2393 "slave port (%d) mac address not set to that of primary port",
2394 test_params->slave_port_ids[0]);
2396 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2397 "Failed to get mac address (port %d)",
2398 test_params->slave_port_ids[1]);
2399 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2400 sizeof(read_mac_addr)),
2401 "slave port (%d) mac address not as expected",
2402 test_params->slave_port_ids[1]);
2404 /* stop / start bonded device and verify that primary MAC address is
2405 * propagated to bonded device and slaves */
2407 rte_eth_dev_stop(test_params->bonded_port_id);
2409 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2410 "Failed to start device");
2412 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2413 "Failed to get mac address (port %d)",
2414 test_params->bonded_port_id);
2415 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2416 sizeof(read_mac_addr)),
2417 "bonded port (%d) mac address not set to that of primary port",
2418 test_params->bonded_port_id);
2420 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2421 "Failed to get mac address (port %d)",
2422 test_params->slave_port_ids[0]);
2423 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2424 sizeof(read_mac_addr)),
2425 "slave port (%d) mac address not as expected",
2426 test_params->slave_port_ids[0]);
2428 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2429 "Failed to get mac address (port %d)",
2430 test_params->slave_port_ids[1]);
2431 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2432 sizeof(read_mac_addr)),
2433 "slave port (%d) mac address not set to that of primary port",
2434 test_params->slave_port_ids[1]);
2436 /* Set explicit MAC address */
2437 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2438 test_params->bonded_port_id,
2439 (struct rte_ether_addr *)bonded_mac),
2440 "failed to set MAC address");
2442 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2443 "Failed to get mac address (port %d)",
2444 test_params->bonded_port_id);
2445 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2446 sizeof(read_mac_addr)),
2447 "bonded port (%d) mac address not set to that of bonded port",
2448 test_params->bonded_port_id);
2450 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2451 "Failed to get mac address (port %d)",
2452 test_params->slave_port_ids[0]);
2453 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2454 sizeof(read_mac_addr)),
2455 "slave port (%d) mac address not as expected",
2456 test_params->slave_port_ids[0]);
2458 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2459 "Failed to get mac address (port %d)",
2460 test_params->slave_port_ids[1]);
2461 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2462 sizeof(read_mac_addr)),
2463 "slave port (%d) mac address not set to that of bonded port",
2464 test_params->slave_port_ids[1]);
2466 /* Clean up and remove slaves from bonded device */
2467 return remove_slaves_and_stop_bonded_device();
2471 test_activebackup_verify_slave_link_status_change_failover(void)
2473 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2474 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2475 struct rte_eth_stats port_stats;
2477 uint16_t slaves[RTE_MAX_ETHPORTS];
2479 int i, burst_size, slave_count, primary_port;
2483 memset(pkt_burst, 0, sizeof(pkt_burst));
2485 /* Generate packet burst for testing */
2486 TEST_ASSERT_EQUAL(generate_test_burst(
2487 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2488 "generate_test_burst failed");
2490 /* Initialize bonded device with 4 slaves in round robin mode */
2491 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2492 BONDING_MODE_ACTIVE_BACKUP, 0,
2493 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2494 "Failed to initialize bonded device with slaves");
2496 /* Verify Current Slaves Count /Active Slave Count is */
2497 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2499 TEST_ASSERT_EQUAL(slave_count, 4,
2500 "Number of slaves (%d) is not as expected (%d).",
2503 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2504 slaves, RTE_MAX_ETHPORTS);
2505 TEST_ASSERT_EQUAL(slave_count, 4,
2506 "Number of active slaves (%d) is not as expected (%d).",
2509 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2510 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2511 "Primary port not as expected");
2513 /* Bring 2 slaves down and verify active slave count */
2514 virtual_ethdev_simulate_link_status_interrupt(
2515 test_params->slave_port_ids[1], 0);
2516 virtual_ethdev_simulate_link_status_interrupt(
2517 test_params->slave_port_ids[3], 0);
2519 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2520 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2521 "Number of active slaves (%d) is not as expected (%d).",
2524 virtual_ethdev_simulate_link_status_interrupt(
2525 test_params->slave_port_ids[1], 1);
2526 virtual_ethdev_simulate_link_status_interrupt(
2527 test_params->slave_port_ids[3], 1);
2530 /* Bring primary port down, verify that active slave count is 3 and primary
2532 virtual_ethdev_simulate_link_status_interrupt(
2533 test_params->slave_port_ids[0], 0);
2535 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2536 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2538 "Number of active slaves (%d) is not as expected (%d).",
2541 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2542 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2543 "Primary port not as expected");
2545 /* Verify that pkts are sent on new primary slave */
2547 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2548 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2549 burst_size), burst_size, "rte_eth_tx_burst failed");
2551 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2552 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2553 "(%d) port_stats.opackets not as expected",
2554 test_params->slave_port_ids[2]);
2556 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2557 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2558 "(%d) port_stats.opackets not as expected\n",
2559 test_params->slave_port_ids[0]);
2561 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2562 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2563 "(%d) port_stats.opackets not as expected\n",
2564 test_params->slave_port_ids[1]);
2566 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2567 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2568 "(%d) port_stats.opackets not as expected\n",
2569 test_params->slave_port_ids[3]);
2571 /* Generate packet burst for testing */
2573 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2574 TEST_ASSERT_EQUAL(generate_test_burst(
2575 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2576 "generate_test_burst failed");
2578 virtual_ethdev_add_mbufs_to_rx_queue(
2579 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2582 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2583 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2584 burst_size, "rte_eth_rx_burst\n");
2586 /* Verify bonded device rx count */
2587 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2588 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2589 "(%d) port_stats.ipackets not as expected",
2590 test_params->bonded_port_id);
2592 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2593 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2594 "(%d) port_stats.opackets not as expected",
2595 test_params->slave_port_ids[2]);
2597 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2598 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2599 "(%d) port_stats.opackets not as expected",
2600 test_params->slave_port_ids[0]);
2602 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2603 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2604 "(%d) port_stats.opackets not as expected",
2605 test_params->slave_port_ids[1]);
2607 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2608 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2609 "(%d) port_stats.opackets not as expected",
2610 test_params->slave_port_ids[3]);
2612 /* Clean up and remove slaves from bonded device */
2613 return remove_slaves_and_stop_bonded_device();
2616 /** Balance Mode Tests */
2619 test_balance_xmit_policy_configuration(void)
2621 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2622 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2623 "Failed to initialize_bonded_device_with_slaves.");
2625 /* Invalid port id */
2626 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2627 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2628 "Expected call to failed as invalid port specified.");
2630 /* Set xmit policy on non bonded device */
2631 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2632 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2633 "Expected call to failed as invalid port specified.");
2636 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2637 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2638 "Failed to set balance xmit policy.");
2640 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2641 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2644 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2645 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2646 "Failed to set balance xmit policy.");
2648 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2649 BALANCE_XMIT_POLICY_LAYER23,
2650 "balance xmit policy not as expected.");
2653 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2654 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2655 "Failed to set balance xmit policy.");
2657 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2658 BALANCE_XMIT_POLICY_LAYER34,
2659 "balance xmit policy not as expected.");
2661 /* Invalid port id */
2662 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2663 "Expected call to failed as invalid port specified.");
2665 /* Clean up and remove slaves from bonded device */
2666 return remove_slaves_and_stop_bonded_device();
2669 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2672 test_balance_l2_tx_burst(void)
2674 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2675 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2679 struct rte_eth_stats port_stats;
2681 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2682 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2683 "Failed to initialize_bonded_device_with_slaves.");
2685 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2686 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2687 "Failed to set balance xmit policy.");
2689 initialize_eth_header(test_params->pkt_eth_hdr,
2690 (struct rte_ether_addr *)src_mac,
2691 (struct rte_ether_addr *)dst_mac_0,
2692 RTE_ETHER_TYPE_IPV4, 0, 0);
2693 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2695 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2696 dst_addr_0, pktlen);
2698 /* Generate a burst 1 of packets to transmit */
2699 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2700 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2701 test_params->pkt_udp_hdr, burst_size[0],
2702 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2703 "failed to generate packet burst");
2705 initialize_eth_header(test_params->pkt_eth_hdr,
2706 (struct rte_ether_addr *)src_mac,
2707 (struct rte_ether_addr *)dst_mac_1,
2708 RTE_ETHER_TYPE_IPV4, 0, 0);
2710 /* Generate a burst 2 of packets to transmit */
2711 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2712 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2713 test_params->pkt_udp_hdr, burst_size[1],
2714 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2715 "failed to generate packet burst");
2717 /* Send burst 1 on bonded port */
2718 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2719 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2720 &pkts_burst[i][0], burst_size[i]),
2721 burst_size[i], "Failed to transmit packet burst");
2724 /* Verify bonded port tx stats */
2725 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2726 TEST_ASSERT_EQUAL(port_stats.opackets,
2727 (uint64_t)(burst_size[0] + burst_size[1]),
2728 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2729 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2730 burst_size[0] + burst_size[1]);
2733 /* Verify slave ports tx stats */
2734 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2735 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2736 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2737 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2740 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2741 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2742 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2743 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2746 /* Put all slaves down and try and transmit */
2747 for (i = 0; i < test_params->bonded_slave_count; i++) {
2749 virtual_ethdev_simulate_link_status_interrupt(
2750 test_params->slave_port_ids[i], 0);
2753 /* Send burst on bonded port */
2754 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2755 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2756 0, "Expected zero packet");
2758 /* Clean up and remove slaves from bonded device */
2759 return remove_slaves_and_stop_bonded_device();
2763 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2764 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2766 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2768 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2769 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2771 struct rte_eth_stats port_stats;
2773 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2774 BONDING_MODE_BALANCE, 0, 2, 1),
2775 "Failed to initialize_bonded_device_with_slaves.");
2777 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2778 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2779 "Failed to set balance xmit policy.");
2784 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2785 "Burst size specified is greater than supported.");
2787 /* Generate test bursts of packets to transmit */
2788 TEST_ASSERT_EQUAL(generate_test_burst(
2789 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2790 burst_size_1, "failed to generate packet burst");
2792 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2793 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2794 "failed to generate packet burst");
2796 /* Send burst 1 on bonded port */
2797 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2799 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2801 /* Send burst 2 on bonded port */
2802 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2804 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2806 /* Verify bonded port tx stats */
2807 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2808 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2809 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2810 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2813 /* Verify slave ports tx stats */
2814 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2815 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2816 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2817 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2820 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2821 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2822 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2823 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2826 /* Put all slaves down and try and transmit */
2827 for (i = 0; i < test_params->bonded_slave_count; i++) {
2829 virtual_ethdev_simulate_link_status_interrupt(
2830 test_params->slave_port_ids[i], 0);
2833 /* Send burst on bonded port */
2834 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2835 test_params->bonded_port_id, 0, pkts_burst_1,
2836 burst_size_1), 0, "Expected zero packet");
2839 /* Clean up and remove slaves from bonded device */
2840 return remove_slaves_and_stop_bonded_device();
2844 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2846 return balance_l23_tx_burst(0, 1, 0, 1);
2850 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2852 return balance_l23_tx_burst(1, 1, 0, 1);
2856 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2858 return balance_l23_tx_burst(0, 0, 0, 1);
2862 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2864 return balance_l23_tx_burst(1, 0, 0, 1);
2868 test_balance_l23_tx_burst_toggle_mac_addr(void)
2870 return balance_l23_tx_burst(0, 0, 1, 0);
2874 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2875 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2876 uint8_t toggle_udp_port)
2878 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2880 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2881 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2883 struct rte_eth_stats port_stats;
2885 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2886 BONDING_MODE_BALANCE, 0, 2, 1),
2887 "Failed to initialize_bonded_device_with_slaves.");
2889 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2890 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2891 "Failed to set balance xmit policy.");
2896 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2897 "Burst size specified is greater than supported.");
2899 /* Generate test bursts of packets to transmit */
2900 TEST_ASSERT_EQUAL(generate_test_burst(
2901 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2902 burst_size_1, "failed to generate burst");
2904 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2905 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2906 toggle_udp_port), burst_size_2, "failed to generate burst");
2908 /* Send burst 1 on bonded port */
2909 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2911 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2913 /* Send burst 2 on bonded port */
2914 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2916 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2919 /* Verify bonded port tx stats */
2920 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2921 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2922 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2923 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2926 /* Verify slave ports tx stats */
2927 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2928 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2929 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2930 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2933 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2934 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2935 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2936 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2939 /* Put all slaves down and try and transmit */
2940 for (i = 0; i < test_params->bonded_slave_count; i++) {
2942 virtual_ethdev_simulate_link_status_interrupt(
2943 test_params->slave_port_ids[i], 0);
2946 /* Send burst on bonded port */
2947 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2948 test_params->bonded_port_id, 0, pkts_burst_1,
2949 burst_size_1), 0, "Expected zero packet");
2951 /* Clean up and remove slaves from bonded device */
2952 return remove_slaves_and_stop_bonded_device();
2956 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2958 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2962 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2964 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2968 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2970 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2974 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2976 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2980 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2982 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2986 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2988 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2991 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2992 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2993 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2994 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2995 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2998 test_balance_tx_burst_slave_tx_fail(void)
3000 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
3001 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
3003 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
3005 struct rte_eth_stats port_stats;
3007 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
3009 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3010 BONDING_MODE_BALANCE, 0,
3011 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3012 "Failed to initialise bonded device");
3014 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3015 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3016 "Failed to set balance xmit policy.");
3019 /* Generate test bursts for transmission */
3020 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
3021 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
3022 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
3023 "Failed to generate test packet burst 1");
3025 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3026 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
3028 /* copy mbuf referneces for expected transmission failures */
3029 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
3030 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
3032 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
3033 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
3034 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3035 "Failed to generate test packet burst 2");
3038 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3039 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3040 virtual_ethdev_tx_burst_fn_set_success(
3041 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3044 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3045 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3046 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3049 /* Transmit burst 1 */
3050 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3051 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3053 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3054 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3055 "Transmitted (%d) packets, expected to transmit (%d) packets",
3056 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3057 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3059 /* Verify that failed packet are expected failed packets */
3060 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3061 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3062 "expected mbuf (%d) pointer %p not expected pointer %p",
3063 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3066 /* Transmit burst 2 */
3067 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3068 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3070 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3071 "Transmitted (%d) packets, expected to transmit (%d) packets",
3072 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3075 /* Verify bonded port tx stats */
3076 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3078 TEST_ASSERT_EQUAL(port_stats.opackets,
3079 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3080 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3081 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3082 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3083 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3084 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3085 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3086 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3088 /* Verify slave ports tx stats */
3090 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3092 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3093 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3094 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3095 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3096 test_params->slave_port_ids[0],
3097 (unsigned int)port_stats.opackets,
3098 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3099 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3104 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3106 TEST_ASSERT_EQUAL(port_stats.opackets,
3107 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3108 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3109 test_params->slave_port_ids[1],
3110 (unsigned int)port_stats.opackets,
3111 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3113 /* Verify that all mbufs have a ref value of zero */
3114 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3115 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3116 "mbufs refcnts not as expected");
3118 free_mbufs(&pkts_burst_1[tx_count_1],
3119 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3121 /* Clean up and remove slaves from bonded device */
3122 return remove_slaves_and_stop_bonded_device();
3125 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3128 test_balance_rx_burst(void)
3130 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3132 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3133 struct rte_eth_stats port_stats;
3135 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3138 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3140 /* Initialize bonded device with 4 slaves in round robin mode */
3141 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3142 BONDING_MODE_BALANCE, 0, 3, 1),
3143 "Failed to initialise bonded device");
3145 /* Generate test bursts of packets to transmit */
3146 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3147 TEST_ASSERT_EQUAL(generate_test_burst(
3148 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3149 0, 0), burst_size[i],
3150 "failed to generate packet burst");
3153 /* Add rx data to slaves */
3154 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3155 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3156 &gen_pkt_burst[i][0], burst_size[i]);
3159 /* Call rx burst on bonded device */
3160 /* Send burst on bonded port */
3161 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3162 rx_pkt_burst, MAX_PKT_BURST),
3163 burst_size[0] + burst_size[1] + burst_size[2],
3164 "balance rx burst failed\n");
3166 /* Verify bonded device rx count */
3167 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3168 TEST_ASSERT_EQUAL(port_stats.ipackets,
3169 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3170 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3171 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3172 burst_size[0] + burst_size[1] + burst_size[2]);
3175 /* Verify bonded slave devices rx counts */
3176 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3177 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3178 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3179 test_params->slave_port_ids[0],
3180 (unsigned int)port_stats.ipackets, burst_size[0]);
3182 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3183 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3184 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3185 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3188 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3189 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3190 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3191 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3194 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3195 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3196 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3197 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3201 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3202 for (j = 0; j < MAX_PKT_BURST; j++) {
3203 if (gen_pkt_burst[i][j] != NULL) {
3204 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3205 gen_pkt_burst[i][j] = NULL;
3210 /* Clean up and remove slaves from bonded device */
3211 return remove_slaves_and_stop_bonded_device();
3215 test_balance_verify_promiscuous_enable_disable(void)
3220 /* Initialize bonded device with 4 slaves in round robin mode */
3221 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3222 BONDING_MODE_BALANCE, 0, 4, 1),
3223 "Failed to initialise bonded device");
3225 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3226 TEST_ASSERT_SUCCESS(ret,
3227 "Failed to enable promiscuous mode for port %d: %s",
3228 test_params->bonded_port_id, rte_strerror(-ret));
3230 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3231 "Port (%d) promiscuous mode not enabled",
3232 test_params->bonded_port_id);
3234 for (i = 0; i < test_params->bonded_slave_count; i++) {
3235 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3236 test_params->slave_port_ids[i]), 1,
3237 "Port (%d) promiscuous mode not enabled",
3238 test_params->slave_port_ids[i]);
3241 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3242 TEST_ASSERT_SUCCESS(ret,
3243 "Failed to disable promiscuous mode for port %d: %s",
3244 test_params->bonded_port_id, rte_strerror(-ret));
3246 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3247 "Port (%d) promiscuous mode not disabled",
3248 test_params->bonded_port_id);
3250 for (i = 0; i < test_params->bonded_slave_count; i++) {
3251 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3252 test_params->slave_port_ids[i]), 0,
3253 "Port (%d) promiscuous mode not disabled",
3254 test_params->slave_port_ids[i]);
3257 /* Clean up and remove slaves from bonded device */
3258 return remove_slaves_and_stop_bonded_device();
3262 test_balance_verify_mac_assignment(void)
3264 struct rte_ether_addr read_mac_addr;
3265 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3267 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3268 "Failed to get mac address (port %d)",
3269 test_params->slave_port_ids[0]);
3270 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
3271 "Failed to get mac address (port %d)",
3272 test_params->slave_port_ids[1]);
3274 /* Initialize bonded device with 2 slaves in active backup mode */
3275 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3276 BONDING_MODE_BALANCE, 0, 2, 1),
3277 "Failed to initialise bonded device");
3279 /* Verify that bonded MACs is that of first slave and that the other slave
3280 * MAC hasn't been changed */
3281 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3282 "Failed to get mac address (port %d)",
3283 test_params->bonded_port_id);
3284 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3285 sizeof(read_mac_addr)),
3286 "bonded port (%d) mac address not set to that of primary port",
3287 test_params->bonded_port_id);
3289 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3290 "Failed to get mac address (port %d)",
3291 test_params->slave_port_ids[0]);
3292 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3293 sizeof(read_mac_addr)),
3294 "slave port (%d) mac address not set to that of primary port",
3295 test_params->slave_port_ids[0]);
3297 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3298 "Failed to get mac address (port %d)",
3299 test_params->slave_port_ids[1]);
3300 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3301 sizeof(read_mac_addr)),
3302 "slave port (%d) mac address not set to that of primary port",
3303 test_params->slave_port_ids[1]);
3305 /* change primary and verify that MAC addresses haven't changed */
3306 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3307 test_params->slave_port_ids[1]),
3308 "Failed to set bonded port (%d) primary port to (%d)\n",
3309 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3311 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3312 "Failed to get mac address (port %d)",
3313 test_params->bonded_port_id);
3314 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3315 sizeof(read_mac_addr)),
3316 "bonded port (%d) mac address not set to that of primary port",
3317 test_params->bonded_port_id);
3319 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3320 "Failed to get mac address (port %d)",
3321 test_params->slave_port_ids[0]);
3322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3323 sizeof(read_mac_addr)),
3324 "slave port (%d) mac address not set to that of primary port",
3325 test_params->slave_port_ids[0]);
3327 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3328 "Failed to get mac address (port %d)",
3329 test_params->slave_port_ids[1]);
3330 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3331 sizeof(read_mac_addr)),
3332 "slave port (%d) mac address not set to that of primary port",
3333 test_params->slave_port_ids[1]);
3335 /* stop / start bonded device and verify that primary MAC address is
3336 * propagated to bonded device and slaves */
3338 rte_eth_dev_stop(test_params->bonded_port_id);
3340 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3341 "Failed to start bonded device");
3343 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3344 "Failed to get mac address (port %d)",
3345 test_params->bonded_port_id);
3346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3347 sizeof(read_mac_addr)),
3348 "bonded port (%d) mac address not set to that of primary port",
3349 test_params->bonded_port_id);
3351 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3352 "Failed to get mac address (port %d)",
3353 test_params->slave_port_ids[0]);
3354 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3355 sizeof(read_mac_addr)),
3356 "slave port (%d) mac address not set to that of primary port",
3357 test_params->slave_port_ids[0]);
3359 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3360 "Failed to get mac address (port %d)",
3361 test_params->slave_port_ids[1]);
3362 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3363 sizeof(read_mac_addr)),
3364 "slave port (%d) mac address not set to that of primary port",
3365 test_params->slave_port_ids[1]);
3367 /* Set explicit MAC address */
3368 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3369 test_params->bonded_port_id,
3370 (struct rte_ether_addr *)bonded_mac),
3371 "failed to set MAC");
3373 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3374 "Failed to get mac address (port %d)",
3375 test_params->bonded_port_id);
3376 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3377 sizeof(read_mac_addr)),
3378 "bonded port (%d) mac address not set to that of bonded port",
3379 test_params->bonded_port_id);
3381 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3382 "Failed to get mac address (port %d)",
3383 test_params->slave_port_ids[0]);
3384 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3385 sizeof(read_mac_addr)),
3386 "slave port (%d) mac address not as expected\n",
3387 test_params->slave_port_ids[0]);
3389 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3390 "Failed to get mac address (port %d)",
3391 test_params->slave_port_ids[1]);
3392 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3393 sizeof(read_mac_addr)),
3394 "slave port (%d) mac address not set to that of bonded port",
3395 test_params->slave_port_ids[1]);
3397 /* Clean up and remove slaves from bonded device */
3398 return remove_slaves_and_stop_bonded_device();
3401 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3404 test_balance_verify_slave_link_status_change_behaviour(void)
3406 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3407 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3408 struct rte_eth_stats port_stats;
3410 uint16_t slaves[RTE_MAX_ETHPORTS];
3412 int i, burst_size, slave_count;
3414 memset(pkt_burst, 0, sizeof(pkt_burst));
3416 /* Initialize bonded device with 4 slaves in round robin mode */
3417 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3418 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3419 "Failed to initialise bonded device");
3421 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3422 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3423 "Failed to set balance xmit policy.");
3426 /* Verify Current Slaves Count /Active Slave Count is */
3427 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3429 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3430 "Number of slaves (%d) is not as expected (%d).",
3431 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3433 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3434 slaves, RTE_MAX_ETHPORTS);
3435 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3436 "Number of active slaves (%d) is not as expected (%d).",
3437 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3439 /* Set 2 slaves link status to down */
3440 virtual_ethdev_simulate_link_status_interrupt(
3441 test_params->slave_port_ids[1], 0);
3442 virtual_ethdev_simulate_link_status_interrupt(
3443 test_params->slave_port_ids[3], 0);
3445 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3446 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3447 "Number of active slaves (%d) is not as expected (%d).",
3450 /* Send to sets of packet burst and verify that they are balanced across
3454 TEST_ASSERT_EQUAL(generate_test_burst(
3455 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3456 "generate_test_burst failed");
3458 TEST_ASSERT_EQUAL(generate_test_burst(
3459 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3460 "generate_test_burst failed");
3462 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3463 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3464 burst_size, "rte_eth_tx_burst failed");
3466 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3467 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3468 burst_size, "rte_eth_tx_burst failed");
3471 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3472 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3473 "(%d) port_stats.opackets (%d) not as expected (%d).",
3474 test_params->bonded_port_id, (int)port_stats.opackets,
3475 burst_size + burst_size);
3477 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3478 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3479 "(%d) port_stats.opackets (%d) not as expected (%d).",
3480 test_params->slave_port_ids[0], (int)port_stats.opackets,
3483 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3484 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3485 "(%d) port_stats.opackets (%d) not as expected (%d).",
3486 test_params->slave_port_ids[2], (int)port_stats.opackets,
3489 /* verify that all packets get send on primary slave when no other slaves
3491 virtual_ethdev_simulate_link_status_interrupt(
3492 test_params->slave_port_ids[2], 0);
3494 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3495 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3496 "Number of active slaves (%d) is not as expected (%d).",
3499 TEST_ASSERT_EQUAL(generate_test_burst(
3500 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3501 "generate_test_burst failed");
3503 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3504 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3505 burst_size, "rte_eth_tx_burst failed");
3507 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3508 TEST_ASSERT_EQUAL(port_stats.opackets,
3509 (uint64_t)(burst_size + burst_size + burst_size),
3510 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3511 test_params->bonded_port_id, (int)port_stats.opackets,
3512 burst_size + burst_size + burst_size);
3514 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3515 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3516 "(%d) port_stats.opackets (%d) not as expected (%d).",
3517 test_params->slave_port_ids[0], (int)port_stats.opackets,
3518 burst_size + burst_size);
3520 virtual_ethdev_simulate_link_status_interrupt(
3521 test_params->slave_port_ids[0], 0);
3522 virtual_ethdev_simulate_link_status_interrupt(
3523 test_params->slave_port_ids[1], 1);
3524 virtual_ethdev_simulate_link_status_interrupt(
3525 test_params->slave_port_ids[2], 1);
3526 virtual_ethdev_simulate_link_status_interrupt(
3527 test_params->slave_port_ids[3], 1);
3529 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3530 TEST_ASSERT_EQUAL(generate_test_burst(
3531 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3532 "Failed to generate packet burst");
3534 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3535 &pkt_burst[i][0], burst_size);
3538 /* Verify that pkts are not received on slaves with link status down */
3540 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3543 /* Verify bonded device rx count */
3544 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3545 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3546 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3547 test_params->bonded_port_id, (int)port_stats.ipackets,
3550 /* Clean up and remove slaves from bonded device */
3551 return remove_slaves_and_stop_bonded_device();
3555 test_broadcast_tx_burst(void)
3557 int i, pktlen, burst_size;
3558 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3560 struct rte_eth_stats port_stats;
3562 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3563 BONDING_MODE_BROADCAST, 0, 2, 1),
3564 "Failed to initialise bonded device");
3566 initialize_eth_header(test_params->pkt_eth_hdr,
3567 (struct rte_ether_addr *)src_mac,
3568 (struct rte_ether_addr *)dst_mac_0,
3569 RTE_ETHER_TYPE_IPV4, 0, 0);
3571 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3573 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3574 dst_addr_0, pktlen);
3576 burst_size = 20 * test_params->bonded_slave_count;
3578 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3579 "Burst size specified is greater than supported.");
3581 /* Generate a burst of packets to transmit */
3582 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3583 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3584 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3585 1), burst_size, "Failed to generate packet burst");
3587 /* Send burst on bonded port */
3588 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3589 pkts_burst, burst_size), burst_size,
3590 "Bonded Port (%d) rx burst failed, packets transmitted value "
3591 "not as expected (%d)",
3592 test_params->bonded_port_id, burst_size);
3594 /* Verify bonded port tx stats */
3595 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3596 TEST_ASSERT_EQUAL(port_stats.opackets,
3597 (uint64_t)burst_size * test_params->bonded_slave_count,
3598 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3599 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3602 /* Verify slave ports tx stats */
3603 for (i = 0; i < test_params->bonded_slave_count; i++) {
3604 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3605 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3606 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3607 test_params->bonded_port_id,
3608 (unsigned int)port_stats.opackets, burst_size);
3611 /* Put all slaves down and try and transmit */
3612 for (i = 0; i < test_params->bonded_slave_count; i++) {
3614 virtual_ethdev_simulate_link_status_interrupt(
3615 test_params->slave_port_ids[i], 0);
3618 /* Send burst on bonded port */
3619 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3620 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3621 "transmitted an unexpected number of packets");
3623 /* Clean up and remove slaves from bonded device */
3624 return remove_slaves_and_stop_bonded_device();
3628 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3629 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3630 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3631 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3634 test_broadcast_tx_burst_slave_tx_fail(void)
3636 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3637 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3639 struct rte_eth_stats port_stats;
3643 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3644 BONDING_MODE_BROADCAST, 0,
3645 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3646 "Failed to initialise bonded device");
3648 /* Generate test bursts for transmission */
3649 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3650 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3651 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3652 "Failed to generate test packet burst");
3654 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3655 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3656 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3659 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3660 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3661 virtual_ethdev_tx_burst_fn_set_success(
3662 test_params->slave_port_ids[0],
3664 virtual_ethdev_tx_burst_fn_set_success(
3665 test_params->slave_port_ids[1],
3667 virtual_ethdev_tx_burst_fn_set_success(
3668 test_params->slave_port_ids[2],
3671 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3672 test_params->slave_port_ids[0],
3673 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3675 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3676 test_params->slave_port_ids[1],
3677 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3679 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3680 test_params->slave_port_ids[2],
3681 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3683 /* Transmit burst */
3684 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3685 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3687 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3688 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3689 "Transmitted (%d) packets, expected to transmit (%d) packets",
3690 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3691 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3693 /* Verify that failed packet are expected failed packets */
3694 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3695 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3696 "expected mbuf (%d) pointer %p not expected pointer %p",
3697 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3700 /* Verify slave ports tx stats */
3702 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3704 TEST_ASSERT_EQUAL(port_stats.opackets,
3705 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3706 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3707 "Port (%d) opackets value (%u) not as expected (%d)",
3708 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3709 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3710 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3713 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3715 TEST_ASSERT_EQUAL(port_stats.opackets,
3716 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3717 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3718 "Port (%d) opackets value (%u) not as expected (%d)",
3719 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3720 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3721 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3723 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3725 TEST_ASSERT_EQUAL(port_stats.opackets,
3726 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3727 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3728 "Port (%d) opackets value (%u) not as expected (%d)",
3729 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3730 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3731 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3734 /* Verify that all mbufs who transmission failed have a ref value of one */
3735 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3736 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3737 "mbufs refcnts not as expected");
3739 free_mbufs(&pkts_burst[tx_count],
3740 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3742 /* Clean up and remove slaves from bonded device */
3743 return remove_slaves_and_stop_bonded_device();
3746 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3749 test_broadcast_rx_burst(void)
3751 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3753 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3754 struct rte_eth_stats port_stats;
3756 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3759 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3761 /* Initialize bonded device with 4 slaves in round robin mode */
3762 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3763 BONDING_MODE_BROADCAST, 0, 3, 1),
3764 "Failed to initialise bonded device");
3766 /* Generate test bursts of packets to transmit */
3767 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3768 TEST_ASSERT_EQUAL(generate_test_burst(
3769 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3770 burst_size[i], "failed to generate packet burst");
3773 /* Add rx data to slave 0 */
3774 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3775 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3776 &gen_pkt_burst[i][0], burst_size[i]);
3780 /* Call rx burst on bonded device */
3781 /* Send burst on bonded port */
3782 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3783 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3784 burst_size[0] + burst_size[1] + burst_size[2],
3787 /* Verify bonded device rx count */
3788 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3789 TEST_ASSERT_EQUAL(port_stats.ipackets,
3790 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3791 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3792 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3793 burst_size[0] + burst_size[1] + burst_size[2]);
3796 /* Verify bonded slave devices rx counts */
3797 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3798 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3799 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3800 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3803 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3804 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3805 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3806 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3809 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3810 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3811 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3812 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3815 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3816 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3817 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3818 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3821 /* free mbufs allocate for rx testing */
3822 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3823 for (j = 0; j < MAX_PKT_BURST; j++) {
3824 if (gen_pkt_burst[i][j] != NULL) {
3825 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3826 gen_pkt_burst[i][j] = NULL;
3831 /* Clean up and remove slaves from bonded device */
3832 return remove_slaves_and_stop_bonded_device();
3836 test_broadcast_verify_promiscuous_enable_disable(void)
3841 /* Initialize bonded device with 4 slaves in round robin mode */
3842 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3843 BONDING_MODE_BROADCAST, 0, 4, 1),
3844 "Failed to initialise bonded device");
3846 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3847 TEST_ASSERT_SUCCESS(ret,
3848 "Failed to enable promiscuous mode for port %d: %s",
3849 test_params->bonded_port_id, rte_strerror(-ret));
3852 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3853 "Port (%d) promiscuous mode not enabled",
3854 test_params->bonded_port_id);
3856 for (i = 0; i < test_params->bonded_slave_count; i++) {
3857 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3858 test_params->slave_port_ids[i]), 1,
3859 "Port (%d) promiscuous mode not enabled",
3860 test_params->slave_port_ids[i]);
3863 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3864 TEST_ASSERT_SUCCESS(ret,
3865 "Failed to disable promiscuous mode for port %d: %s",
3866 test_params->bonded_port_id, rte_strerror(-ret));
3868 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3869 "Port (%d) promiscuous mode not disabled",
3870 test_params->bonded_port_id);
3872 for (i = 0; i < test_params->bonded_slave_count; i++) {
3873 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3874 test_params->slave_port_ids[i]), 0,
3875 "Port (%d) promiscuous mode not disabled",
3876 test_params->slave_port_ids[i]);
3879 /* Clean up and remove slaves from bonded device */
3880 return remove_slaves_and_stop_bonded_device();
3884 test_broadcast_verify_mac_assignment(void)
3886 struct rte_ether_addr read_mac_addr;
3887 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3891 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3892 "Failed to get mac address (port %d)",
3893 test_params->slave_port_ids[0]);
3894 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1),
3895 "Failed to get mac address (port %d)",
3896 test_params->slave_port_ids[2]);
3898 /* Initialize bonded device with 4 slaves in round robin mode */
3899 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3900 BONDING_MODE_BROADCAST, 0, 4, 1),
3901 "Failed to initialise bonded device");
3903 /* Verify that all MACs are the same as first slave added to bonded
3905 for (i = 0; i < test_params->bonded_slave_count; i++) {
3906 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3907 "Failed to get mac address (port %d)",
3908 test_params->slave_port_ids[i]);
3909 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3910 sizeof(read_mac_addr)),
3911 "slave port (%d) mac address not set to that of primary port",
3912 test_params->slave_port_ids[i]);
3915 /* change primary and verify that MAC addresses haven't changed */
3916 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3917 test_params->slave_port_ids[2]),
3918 "Failed to set bonded port (%d) primary port to (%d)",
3919 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3921 for (i = 0; i < test_params->bonded_slave_count; i++) {
3922 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3923 "Failed to get mac address (port %d)",
3924 test_params->slave_port_ids[i]);
3925 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3926 sizeof(read_mac_addr)),
3927 "slave port (%d) mac address has changed to that of primary "
3928 "port without stop/start toggle of bonded device",
3929 test_params->slave_port_ids[i]);
3932 /* stop / start bonded device and verify that primary MAC address is
3933 * propagated to bonded device and slaves */
3935 rte_eth_dev_stop(test_params->bonded_port_id);
3937 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3938 "Failed to start bonded device");
3940 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3941 "Failed to get mac address (port %d)",
3942 test_params->bonded_port_id);
3943 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3944 sizeof(read_mac_addr)),
3945 "bonded port (%d) mac address not set to that of new primary port",
3946 test_params->slave_port_ids[i]);
3948 for (i = 0; i < test_params->bonded_slave_count; i++) {
3949 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3950 "Failed to get mac address (port %d)",
3951 test_params->slave_port_ids[i]);
3952 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3953 sizeof(read_mac_addr)),
3954 "slave port (%d) mac address not set to that of new primary "
3955 "port", test_params->slave_port_ids[i]);
3958 /* Set explicit MAC address */
3959 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3960 test_params->bonded_port_id,
3961 (struct rte_ether_addr *)bonded_mac),
3962 "Failed to set MAC address");
3964 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3965 "Failed to get mac address (port %d)",
3966 test_params->bonded_port_id);
3967 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3968 sizeof(read_mac_addr)),
3969 "bonded port (%d) mac address not set to that of new primary port",
3970 test_params->slave_port_ids[i]);
3973 for (i = 0; i < test_params->bonded_slave_count; i++) {
3974 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3975 "Failed to get mac address (port %d)",
3976 test_params->slave_port_ids[i]);
3977 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3978 sizeof(read_mac_addr)),
3979 "slave port (%d) mac address not set to that of new primary "
3980 "port", test_params->slave_port_ids[i]);
3983 /* Clean up and remove slaves from bonded device */
3984 return remove_slaves_and_stop_bonded_device();
3987 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3989 test_broadcast_verify_slave_link_status_change_behaviour(void)
3991 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3992 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3993 struct rte_eth_stats port_stats;
3995 uint16_t slaves[RTE_MAX_ETHPORTS];
3997 int i, burst_size, slave_count;
3999 memset(pkt_burst, 0, sizeof(pkt_burst));
4001 /* Initialize bonded device with 4 slaves in round robin mode */
4002 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4003 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
4004 1), "Failed to initialise bonded device");
4006 /* Verify Current Slaves Count /Active Slave Count is */
4007 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4009 TEST_ASSERT_EQUAL(slave_count, 4,
4010 "Number of slaves (%d) is not as expected (%d).",
4013 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4014 slaves, RTE_MAX_ETHPORTS);
4015 TEST_ASSERT_EQUAL(slave_count, 4,
4016 "Number of active slaves (%d) is not as expected (%d).",
4019 /* Set 2 slaves link status to down */
4020 virtual_ethdev_simulate_link_status_interrupt(
4021 test_params->slave_port_ids[1], 0);
4022 virtual_ethdev_simulate_link_status_interrupt(
4023 test_params->slave_port_ids[3], 0);
4025 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4026 slaves, RTE_MAX_ETHPORTS);
4027 TEST_ASSERT_EQUAL(slave_count, 2,
4028 "Number of active slaves (%d) is not as expected (%d).",
4031 for (i = 0; i < test_params->bonded_slave_count; i++)
4032 rte_eth_stats_reset(test_params->slave_port_ids[i]);
4034 /* Verify that pkts are not sent on slaves with link status down */
4037 TEST_ASSERT_EQUAL(generate_test_burst(
4038 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
4039 "generate_test_burst failed");
4041 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
4042 &pkt_burst[0][0], burst_size), burst_size,
4043 "rte_eth_tx_burst failed\n");
4045 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4046 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
4047 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
4048 test_params->bonded_port_id, (int)port_stats.opackets,
4049 burst_size * slave_count);
4051 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4052 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4053 "(%d) port_stats.opackets not as expected",
4054 test_params->slave_port_ids[0]);
4056 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4057 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4058 "(%d) port_stats.opackets not as expected",
4059 test_params->slave_port_ids[1]);
4061 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4062 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4063 "(%d) port_stats.opackets not as expected",
4064 test_params->slave_port_ids[2]);
4067 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4068 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4069 "(%d) port_stats.opackets not as expected",
4070 test_params->slave_port_ids[3]);
4073 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4074 TEST_ASSERT_EQUAL(generate_test_burst(
4075 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
4076 burst_size, "failed to generate packet burst");
4078 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4079 &pkt_burst[i][0], burst_size);
4082 /* Verify that pkts are not received on slaves with link status down */
4083 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
4084 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
4085 burst_size + burst_size, "rte_eth_rx_burst failed");
4088 /* Verify bonded device rx count */
4089 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4090 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
4091 "(%d) port_stats.ipackets not as expected\n",
4092 test_params->bonded_port_id);
4094 /* Clean up and remove slaves from bonded device */
4095 return remove_slaves_and_stop_bonded_device();
4099 test_reconfigure_bonded_device(void)
4101 test_params->nb_rx_q = 4;
4102 test_params->nb_tx_q = 4;
4104 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4105 "failed to reconfigure bonded device");
4107 test_params->nb_rx_q = 2;
4108 test_params->nb_tx_q = 2;
4110 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4111 "failed to reconfigure bonded device with less rx/tx queues");
4118 test_close_bonded_device(void)
4120 rte_eth_dev_close(test_params->bonded_port_id);
4125 testsuite_teardown(void)
4127 free(test_params->pkt_eth_hdr);
4128 test_params->pkt_eth_hdr = NULL;
4130 /* Clean up and remove slaves from bonded device */
4131 remove_slaves_and_stop_bonded_device();
4135 free_virtualpmd_tx_queue(void)
4137 int i, slave_port, to_free_cnt;
4138 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4140 /* Free tx queue of virtual pmd */
4141 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4143 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4144 test_params->slave_port_ids[slave_port],
4145 pkts_to_free, MAX_PKT_BURST);
4146 for (i = 0; i < to_free_cnt; i++)
4147 rte_pktmbuf_free(pkts_to_free[i]);
4152 test_tlb_tx_burst(void)
4154 int i, burst_size, nb_tx;
4155 uint64_t nb_tx2 = 0;
4156 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4157 struct rte_eth_stats port_stats[32];
4158 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4161 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4162 (BONDING_MODE_TLB, 1, 3, 1),
4163 "Failed to initialise bonded device");
4165 burst_size = 20 * test_params->bonded_slave_count;
4167 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4168 "Burst size specified is greater than supported.\n");
4171 /* Generate bursts of packets */
4172 for (i = 0; i < 400000; i++) {
4173 /*test two types of mac src own(bonding) and others */
4175 initialize_eth_header(test_params->pkt_eth_hdr,
4176 (struct rte_ether_addr *)src_mac,
4177 (struct rte_ether_addr *)dst_mac_0,
4178 RTE_ETHER_TYPE_IPV4, 0, 0);
4180 initialize_eth_header(test_params->pkt_eth_hdr,
4181 (struct rte_ether_addr *)test_params->default_slave_mac,
4182 (struct rte_ether_addr *)dst_mac_0,
4183 RTE_ETHER_TYPE_IPV4, 0, 0);
4185 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4187 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4188 dst_addr_0, pktlen);
4189 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4190 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4191 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4192 /* Send burst on bonded port */
4193 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4197 free_virtualpmd_tx_queue();
4199 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4200 "number of packet not equal burst size");
4206 /* Verify bonded port tx stats */
4207 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4209 all_bond_opackets = port_stats[0].opackets;
4210 all_bond_obytes = port_stats[0].obytes;
4212 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4213 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4214 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4218 /* Verify slave ports tx stats */
4219 for (i = 0; i < test_params->bonded_slave_count; i++) {
4220 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4221 sum_ports_opackets += port_stats[i].opackets;
4224 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4225 "Total packets sent by slaves is not equal to packets sent by bond interface");
4227 /* checking if distribution of packets is balanced over slaves */
4228 for (i = 0; i < test_params->bonded_slave_count; i++) {
4229 TEST_ASSERT(port_stats[i].obytes > 0 &&
4230 port_stats[i].obytes < all_bond_obytes,
4231 "Packets are not balanced over slaves");
4234 /* Put all slaves down and try and transmit */
4235 for (i = 0; i < test_params->bonded_slave_count; i++) {
4236 virtual_ethdev_simulate_link_status_interrupt(
4237 test_params->slave_port_ids[i], 0);
4240 /* Send burst on bonded port */
4241 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4243 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4245 /* Clean ugit checkout masterp and remove slaves from bonded device */
4246 return remove_slaves_and_stop_bonded_device();
4249 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4252 test_tlb_rx_burst(void)
4254 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4255 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4257 struct rte_eth_stats port_stats;
4261 uint16_t i, j, nb_rx, burst_size = 17;
4263 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4264 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4266 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4267 "Failed to initialize bonded device");
4270 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4271 TEST_ASSERT(primary_port >= 0,
4272 "failed to get primary slave for bonded port (%d)",
4273 test_params->bonded_port_id);
4275 for (i = 0; i < test_params->bonded_slave_count; i++) {
4276 /* Generate test bursts of packets to transmit */
4277 TEST_ASSERT_EQUAL(generate_test_burst(
4278 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4279 "burst generation failed");
4281 /* Add rx data to slave */
4282 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4283 &gen_pkt_burst[0], burst_size);
4285 /* Call rx burst on bonded device */
4286 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4287 &rx_pkt_burst[0], MAX_PKT_BURST);
4289 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4291 if (test_params->slave_port_ids[i] == primary_port) {
4292 /* Verify bonded device rx count */
4293 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4294 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4295 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4296 test_params->bonded_port_id,
4297 (unsigned int)port_stats.ipackets, burst_size);
4299 /* Verify bonded slave devices rx count */
4300 for (j = 0; j < test_params->bonded_slave_count; j++) {
4301 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4303 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4304 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4305 test_params->slave_port_ids[i],
4306 (unsigned int)port_stats.ipackets, burst_size);
4308 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4309 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4310 test_params->slave_port_ids[i],
4311 (unsigned int)port_stats.ipackets, 0);
4315 for (j = 0; j < test_params->bonded_slave_count; j++) {
4316 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4317 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4318 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4319 test_params->slave_port_ids[i],
4320 (unsigned int)port_stats.ipackets, 0);
4325 for (i = 0; i < burst_size; i++)
4326 rte_pktmbuf_free(rx_pkt_burst[i]);
4328 /* reset bonded device stats */
4329 rte_eth_stats_reset(test_params->bonded_port_id);
4332 /* Clean up and remove slaves from bonded device */
4333 return remove_slaves_and_stop_bonded_device();
4337 test_tlb_verify_promiscuous_enable_disable(void)
4339 int i, primary_port, promiscuous_en;
4342 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4343 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4344 BONDING_MODE_TLB, 0, 4, 1),
4345 "Failed to initialize bonded device");
4347 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4348 TEST_ASSERT(primary_port >= 0,
4349 "failed to get primary slave for bonded port (%d)",
4350 test_params->bonded_port_id);
4352 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
4353 TEST_ASSERT_SUCCESS(ret,
4354 "Failed to enable promiscuous mode for port %d: %s",
4355 test_params->bonded_port_id, rte_strerror(-ret));
4357 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4358 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4359 "Port (%d) promiscuous mode not enabled\n",
4360 test_params->bonded_port_id);
4361 for (i = 0; i < test_params->bonded_slave_count; i++) {
4362 promiscuous_en = rte_eth_promiscuous_get(
4363 test_params->slave_port_ids[i]);
4364 if (primary_port == test_params->slave_port_ids[i]) {
4365 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4366 "Port (%d) promiscuous mode not enabled\n",
4367 test_params->bonded_port_id);
4369 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4370 "Port (%d) promiscuous mode enabled\n",
4371 test_params->bonded_port_id);
4376 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
4377 TEST_ASSERT_SUCCESS(ret,
4378 "Failed to disable promiscuous mode for port %d: %s\n",
4379 test_params->bonded_port_id, rte_strerror(-ret));
4381 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4382 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4383 "Port (%d) promiscuous mode not disabled\n",
4384 test_params->bonded_port_id);
4386 for (i = 0; i < test_params->bonded_slave_count; i++) {
4387 promiscuous_en = rte_eth_promiscuous_get(
4388 test_params->slave_port_ids[i]);
4389 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4390 "slave port (%d) promiscuous mode not disabled\n",
4391 test_params->slave_port_ids[i]);
4394 /* Clean up and remove slaves from bonded device */
4395 return remove_slaves_and_stop_bonded_device();
4399 test_tlb_verify_mac_assignment(void)
4401 struct rte_ether_addr read_mac_addr;
4402 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
4404 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
4405 "Failed to get mac address (port %d)",
4406 test_params->slave_port_ids[0]);
4407 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
4408 "Failed to get mac address (port %d)",
4409 test_params->slave_port_ids[1]);
4411 /* Initialize bonded device with 2 slaves in active backup mode */
4412 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4413 BONDING_MODE_TLB, 0, 2, 1),
4414 "Failed to initialize bonded device");
4416 /* Verify that bonded MACs is that of first slave and that the other slave
4417 * MAC hasn't been changed */
4418 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4419 "Failed to get mac address (port %d)",
4420 test_params->bonded_port_id);
4421 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4422 sizeof(read_mac_addr)),
4423 "bonded port (%d) mac address not set to that of primary port",
4424 test_params->bonded_port_id);
4426 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4427 "Failed to get mac address (port %d)",
4428 test_params->slave_port_ids[0]);
4429 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4430 sizeof(read_mac_addr)),
4431 "slave port (%d) mac address not set to that of primary port",
4432 test_params->slave_port_ids[0]);
4434 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4435 "Failed to get mac address (port %d)",
4436 test_params->slave_port_ids[1]);
4437 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4438 sizeof(read_mac_addr)),
4439 "slave port (%d) mac address not as expected",
4440 test_params->slave_port_ids[1]);
4442 /* change primary and verify that MAC addresses haven't changed */
4443 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4444 test_params->slave_port_ids[1]), 0,
4445 "Failed to set bonded port (%d) primary port to (%d)",
4446 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4448 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4449 "Failed to get mac address (port %d)",
4450 test_params->bonded_port_id);
4451 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4452 sizeof(read_mac_addr)),
4453 "bonded port (%d) mac address not set to that of primary port",
4454 test_params->bonded_port_id);
4456 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4457 "Failed to get mac address (port %d)",
4458 test_params->slave_port_ids[0]);
4459 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4460 sizeof(read_mac_addr)),
4461 "slave port (%d) mac address not set to that of primary port",
4462 test_params->slave_port_ids[0]);
4464 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4465 "Failed to get mac address (port %d)",
4466 test_params->slave_port_ids[1]);
4467 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4468 sizeof(read_mac_addr)),
4469 "slave port (%d) mac address not as expected",
4470 test_params->slave_port_ids[1]);
4472 /* stop / start bonded device and verify that primary MAC address is
4473 * propagated to bonded device and slaves */
4475 rte_eth_dev_stop(test_params->bonded_port_id);
4477 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4478 "Failed to start device");
4480 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4481 "Failed to get mac address (port %d)",
4482 test_params->bonded_port_id);
4483 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4484 sizeof(read_mac_addr)),
4485 "bonded port (%d) mac address not set to that of primary port",
4486 test_params->bonded_port_id);
4488 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4489 "Failed to get mac address (port %d)",
4490 test_params->slave_port_ids[0]);
4491 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4492 sizeof(read_mac_addr)),
4493 "slave port (%d) mac address not as expected",
4494 test_params->slave_port_ids[0]);
4496 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4497 "Failed to get mac address (port %d)",
4498 test_params->slave_port_ids[1]);
4499 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4500 sizeof(read_mac_addr)),
4501 "slave port (%d) mac address not set to that of primary port",
4502 test_params->slave_port_ids[1]);
4505 /* Set explicit MAC address */
4506 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4507 test_params->bonded_port_id,
4508 (struct rte_ether_addr *)bonded_mac),
4509 "failed to set MAC address");
4511 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4512 "Failed to get mac address (port %d)",
4513 test_params->bonded_port_id);
4514 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4515 sizeof(read_mac_addr)),
4516 "bonded port (%d) mac address not set to that of bonded port",
4517 test_params->bonded_port_id);
4519 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4520 "Failed to get mac address (port %d)",
4521 test_params->slave_port_ids[0]);
4522 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4523 sizeof(read_mac_addr)),
4524 "slave port (%d) mac address not as expected",
4525 test_params->slave_port_ids[0]);
4527 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4528 "Failed to get mac address (port %d)",
4529 test_params->slave_port_ids[1]);
4530 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4531 sizeof(read_mac_addr)),
4532 "slave port (%d) mac address not set to that of bonded port",
4533 test_params->slave_port_ids[1]);
4535 /* Clean up and remove slaves from bonded device */
4536 return remove_slaves_and_stop_bonded_device();
4540 test_tlb_verify_slave_link_status_change_failover(void)
4542 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4543 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4544 struct rte_eth_stats port_stats;
4546 uint16_t slaves[RTE_MAX_ETHPORTS];
4548 int i, burst_size, slave_count, primary_port;
4552 memset(pkt_burst, 0, sizeof(pkt_burst));
4556 /* Initialize bonded device with 4 slaves in round robin mode */
4557 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4558 BONDING_MODE_TLB, 0,
4559 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4560 "Failed to initialize bonded device with slaves");
4562 /* Verify Current Slaves Count /Active Slave Count is */
4563 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4565 TEST_ASSERT_EQUAL(slave_count, 4,
4566 "Number of slaves (%d) is not as expected (%d).\n",
4569 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4570 slaves, RTE_MAX_ETHPORTS);
4571 TEST_ASSERT_EQUAL(slave_count, (int)4,
4572 "Number of slaves (%d) is not as expected (%d).\n",
4575 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4576 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4577 "Primary port not as expected");
4579 /* Bring 2 slaves down and verify active slave count */
4580 virtual_ethdev_simulate_link_status_interrupt(
4581 test_params->slave_port_ids[1], 0);
4582 virtual_ethdev_simulate_link_status_interrupt(
4583 test_params->slave_port_ids[3], 0);
4585 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4586 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4587 "Number of active slaves (%d) is not as expected (%d).",
4590 virtual_ethdev_simulate_link_status_interrupt(
4591 test_params->slave_port_ids[1], 1);
4592 virtual_ethdev_simulate_link_status_interrupt(
4593 test_params->slave_port_ids[3], 1);
4596 /* Bring primary port down, verify that active slave count is 3 and primary
4598 virtual_ethdev_simulate_link_status_interrupt(
4599 test_params->slave_port_ids[0], 0);
4601 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4602 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4603 "Number of active slaves (%d) is not as expected (%d).",
4606 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4607 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4608 "Primary port not as expected");
4609 rte_delay_us(500000);
4610 /* Verify that pkts are sent on new primary slave */
4611 for (i = 0; i < 4; i++) {
4612 TEST_ASSERT_EQUAL(generate_test_burst(
4613 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4614 "generate_test_burst failed\n");
4615 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4616 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4617 "rte_eth_tx_burst failed\n");
4618 rte_delay_us(11000);
4621 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4622 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4623 "(%d) port_stats.opackets not as expected\n",
4624 test_params->slave_port_ids[0]);
4626 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4627 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4628 "(%d) port_stats.opackets not as expected\n",
4629 test_params->slave_port_ids[1]);
4631 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4632 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4633 "(%d) port_stats.opackets not as expected\n",
4634 test_params->slave_port_ids[2]);
4636 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4637 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4638 "(%d) port_stats.opackets not as expected\n",
4639 test_params->slave_port_ids[3]);
4642 /* Generate packet burst for testing */
4644 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4645 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4649 virtual_ethdev_add_mbufs_to_rx_queue(
4650 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4653 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4654 MAX_PKT_BURST) != burst_size) {
4655 printf("rte_eth_rx_burst\n");
4660 /* Verify bonded device rx count */
4661 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4662 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4663 "(%d) port_stats.ipackets not as expected\n",
4664 test_params->bonded_port_id);
4666 /* Clean up and remove slaves from bonded device */
4667 return remove_slaves_and_stop_bonded_device();
4670 #define TEST_ALB_SLAVE_COUNT 2
4672 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4673 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4674 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4675 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4677 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4678 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4679 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4680 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4681 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4684 test_alb_change_mac_in_reply_sent(void)
4686 struct rte_mbuf *pkt;
4687 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4689 struct rte_ether_hdr *eth_pkt;
4690 struct rte_arp_hdr *arp_pkt;
4692 int slave_idx, nb_pkts, pkt_idx;
4695 struct rte_ether_addr bond_mac, client_mac;
4696 struct rte_ether_addr *slave_mac1, *slave_mac2;
4698 TEST_ASSERT_SUCCESS(
4699 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4700 0, TEST_ALB_SLAVE_COUNT, 1),
4701 "Failed to initialize_bonded_device_with_slaves.");
4703 /* Flush tx queue */
4704 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4705 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4707 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4708 test_params->slave_port_ids[slave_idx], pkts_sent,
4712 rte_ether_addr_copy(
4713 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4717 * Generating four packets with different mac and ip addresses and sending
4718 * them through the bonding port.
4720 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4721 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4722 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4723 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4724 RTE_ETHER_TYPE_ARP, 0, 0);
4725 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4726 sizeof(struct rte_ether_hdr));
4727 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4729 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4731 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4732 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4733 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4734 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4735 RTE_ETHER_TYPE_ARP, 0, 0);
4736 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4737 sizeof(struct rte_ether_hdr));
4738 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4740 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4742 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4743 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4744 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4745 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4746 RTE_ETHER_TYPE_ARP, 0, 0);
4747 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4748 sizeof(struct rte_ether_hdr));
4749 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4751 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4753 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4754 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4755 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4756 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4757 RTE_ETHER_TYPE_ARP, 0, 0);
4758 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4759 sizeof(struct rte_ether_hdr));
4760 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4762 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4765 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4767 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4770 * Checking if packets are properly distributed on bonding ports. Packets
4771 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4773 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4774 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4775 test_params->slave_port_ids[slave_idx], pkts_sent,
4778 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4779 eth_pkt = rte_pktmbuf_mtod(
4780 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4781 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4782 sizeof(struct rte_ether_hdr));
4784 if (slave_idx%2 == 0) {
4785 if (!rte_is_same_ether_addr(slave_mac1,
4786 &arp_pkt->arp_data.arp_sha)) {
4791 if (!rte_is_same_ether_addr(slave_mac2,
4792 &arp_pkt->arp_data.arp_sha)) {
4801 retval += remove_slaves_and_stop_bonded_device();
4806 test_alb_reply_from_client(void)
4808 struct rte_ether_hdr *eth_pkt;
4809 struct rte_arp_hdr *arp_pkt;
4811 struct rte_mbuf *pkt;
4812 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4814 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4817 struct rte_ether_addr bond_mac, client_mac;
4818 struct rte_ether_addr *slave_mac1, *slave_mac2;
4820 TEST_ASSERT_SUCCESS(
4821 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4822 0, TEST_ALB_SLAVE_COUNT, 1),
4823 "Failed to initialize_bonded_device_with_slaves.");
4825 /* Flush tx queue */
4826 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4827 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4828 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4829 test_params->slave_port_ids[slave_idx], pkts_sent,
4833 rte_ether_addr_copy(
4834 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4838 * Generating four packets with different mac and ip addresses and placing
4839 * them in the rx queue to be received by the bonding driver on rx_burst.
4841 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4842 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4843 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4844 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4845 RTE_ETHER_TYPE_ARP, 0, 0);
4846 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4847 sizeof(struct rte_ether_hdr));
4848 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4850 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4853 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4854 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4855 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4856 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4857 RTE_ETHER_TYPE_ARP, 0, 0);
4858 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4859 sizeof(struct rte_ether_hdr));
4860 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4862 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4865 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4866 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4867 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4868 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4869 RTE_ETHER_TYPE_ARP, 0, 0);
4870 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4871 sizeof(struct rte_ether_hdr));
4872 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4874 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4877 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4878 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4879 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4880 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4881 RTE_ETHER_TYPE_ARP, 0, 0);
4882 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4883 sizeof(struct rte_ether_hdr));
4884 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4886 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4890 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4891 * packets to every client in alb table.
4893 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4894 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4896 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4897 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4900 * Checking if update ARP packets were properly send on slave ports.
4902 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4903 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4904 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4905 nb_pkts_sum += nb_pkts;
4907 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4908 eth_pkt = rte_pktmbuf_mtod(
4909 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4910 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4911 sizeof(struct rte_ether_hdr));
4913 if (slave_idx%2 == 0) {
4914 if (!rte_is_same_ether_addr(slave_mac1,
4915 &arp_pkt->arp_data.arp_sha)) {
4920 if (!rte_is_same_ether_addr(slave_mac2,
4921 &arp_pkt->arp_data.arp_sha)) {
4929 /* Check if proper number of packets was send */
4930 if (nb_pkts_sum < 4) {
4936 retval += remove_slaves_and_stop_bonded_device();
4941 test_alb_receive_vlan_reply(void)
4943 struct rte_ether_hdr *eth_pkt;
4944 struct rte_vlan_hdr *vlan_pkt;
4945 struct rte_arp_hdr *arp_pkt;
4947 struct rte_mbuf *pkt;
4948 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4950 int slave_idx, nb_pkts, pkt_idx;
4953 struct rte_ether_addr bond_mac, client_mac;
4955 TEST_ASSERT_SUCCESS(
4956 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4957 0, TEST_ALB_SLAVE_COUNT, 1),
4958 "Failed to initialize_bonded_device_with_slaves.");
4960 /* Flush tx queue */
4961 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4962 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4963 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4964 test_params->slave_port_ids[slave_idx], pkts_sent,
4968 rte_ether_addr_copy(
4969 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4973 * Generating packet with double VLAN header and placing it in the rx queue.
4975 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4976 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4977 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4978 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4979 RTE_ETHER_TYPE_VLAN, 0, 0);
4980 vlan_pkt = (struct rte_vlan_hdr *)((char *)(eth_pkt + 1));
4981 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4982 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4983 vlan_pkt = vlan_pkt+1;
4984 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4985 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
4986 arp_pkt = (struct rte_arp_hdr *)((char *)(vlan_pkt + 1));
4987 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4989 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4992 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4993 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4996 * Checking if VLAN headers in generated ARP Update packet are correct.
4998 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4999 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
5000 test_params->slave_port_ids[slave_idx], pkts_sent,
5003 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
5004 eth_pkt = rte_pktmbuf_mtod(
5005 pkts_sent[pkt_idx], struct rte_ether_hdr *);
5006 vlan_pkt = (struct rte_vlan_hdr *)(
5007 (char *)(eth_pkt + 1));
5008 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
5012 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5013 RTE_ETHER_TYPE_VLAN)) {
5017 vlan_pkt = vlan_pkt+1;
5018 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
5022 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5023 RTE_ETHER_TYPE_ARP)) {
5031 retval += remove_slaves_and_stop_bonded_device();
5036 test_alb_ipv4_tx(void)
5038 int burst_size, retval, pkts_send;
5039 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
5043 TEST_ASSERT_SUCCESS(
5044 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
5045 0, TEST_ALB_SLAVE_COUNT, 1),
5046 "Failed to initialize_bonded_device_with_slaves.");
5050 /* Generate test bursts of packets to transmit */
5051 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
5057 * Checking if ipv4 traffic is transmitted via TLB policy.
5059 pkts_send = rte_eth_tx_burst(
5060 test_params->bonded_port_id, 0, pkt_burst, burst_size);
5061 if (pkts_send != burst_size) {
5067 retval += remove_slaves_and_stop_bonded_device();
5071 static struct unit_test_suite link_bonding_test_suite = {
5072 .suite_name = "Link Bonding Unit Test Suite",
5073 .setup = test_setup,
5074 .teardown = testsuite_teardown,
5075 .unit_test_cases = {
5076 TEST_CASE(test_create_bonded_device),
5077 TEST_CASE(test_create_bonded_device_with_invalid_params),
5078 TEST_CASE(test_add_slave_to_bonded_device),
5079 TEST_CASE(test_add_slave_to_invalid_bonded_device),
5080 TEST_CASE(test_remove_slave_from_bonded_device),
5081 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
5082 TEST_CASE(test_get_slaves_from_bonded_device),
5083 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
5084 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
5085 TEST_CASE(test_start_bonded_device),
5086 TEST_CASE(test_stop_bonded_device),
5087 TEST_CASE(test_set_bonding_mode),
5088 TEST_CASE(test_set_primary_slave),
5089 TEST_CASE(test_set_explicit_bonded_mac),
5090 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
5091 TEST_CASE(test_status_interrupt),
5092 TEST_CASE(test_adding_slave_after_bonded_device_started),
5093 TEST_CASE(test_roundrobin_tx_burst),
5094 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
5095 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
5096 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
5097 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
5098 TEST_CASE(test_roundrobin_verify_mac_assignment),
5099 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
5100 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
5101 TEST_CASE(test_activebackup_tx_burst),
5102 TEST_CASE(test_activebackup_rx_burst),
5103 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
5104 TEST_CASE(test_activebackup_verify_mac_assignment),
5105 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
5106 TEST_CASE(test_balance_xmit_policy_configuration),
5107 TEST_CASE(test_balance_l2_tx_burst),
5108 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
5109 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
5110 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
5111 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
5112 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
5113 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
5114 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
5115 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
5116 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
5117 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
5118 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
5119 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
5120 TEST_CASE(test_balance_rx_burst),
5121 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
5122 TEST_CASE(test_balance_verify_mac_assignment),
5123 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
5124 TEST_CASE(test_tlb_tx_burst),
5125 TEST_CASE(test_tlb_rx_burst),
5126 TEST_CASE(test_tlb_verify_mac_assignment),
5127 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
5128 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
5129 TEST_CASE(test_alb_change_mac_in_reply_sent),
5130 TEST_CASE(test_alb_reply_from_client),
5131 TEST_CASE(test_alb_receive_vlan_reply),
5132 TEST_CASE(test_alb_ipv4_tx),
5133 TEST_CASE(test_broadcast_tx_burst),
5134 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
5135 TEST_CASE(test_broadcast_rx_burst),
5136 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
5137 TEST_CASE(test_broadcast_verify_mac_assignment),
5138 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
5139 TEST_CASE(test_reconfigure_bonded_device),
5140 TEST_CASE(test_close_bonded_device),
5142 TEST_CASES_END() /**< NULL terminate unit test array */
5148 test_link_bonding(void)
5150 return unit_test_suite_runner(&link_bonding_test_suite);
5153 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);