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_MS 500
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;
1206 pthread_mutex_lock(&mutex);
1207 if (test_lsc_interrupt_count < 1)
1208 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1210 pthread_mutex_unlock(&mutex);
1212 if (retval == 0 && test_lsc_interrupt_count < 1)
1219 test_status_interrupt(void)
1222 uint16_t slaves[RTE_MAX_ETHPORTS];
1224 /* initialized bonding device with T slaves */
1225 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1226 BONDING_MODE_ROUND_ROBIN, 1,
1227 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1228 "Failed to initialise bonded device");
1230 test_lsc_interrupt_count = 0;
1232 /* register link status change interrupt callback */
1233 rte_eth_dev_callback_register(test_params->bonded_port_id,
1234 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1235 &test_params->bonded_port_id);
1237 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1238 slaves, RTE_MAX_ETHPORTS);
1240 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1241 "Number of active slaves (%d) is not as expected (%d)",
1242 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1244 /* Bring all 4 slaves link status to down and test that we have received a
1246 virtual_ethdev_simulate_link_status_interrupt(
1247 test_params->slave_port_ids[0], 0);
1248 virtual_ethdev_simulate_link_status_interrupt(
1249 test_params->slave_port_ids[1], 0);
1250 virtual_ethdev_simulate_link_status_interrupt(
1251 test_params->slave_port_ids[2], 0);
1253 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1254 "Received a link status change interrupt unexpectedly");
1256 virtual_ethdev_simulate_link_status_interrupt(
1257 test_params->slave_port_ids[3], 0);
1259 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1260 "timed out waiting for interrupt");
1262 TEST_ASSERT(test_lsc_interrupt_count > 0,
1263 "Did not receive link status change interrupt");
1265 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1266 slaves, RTE_MAX_ETHPORTS);
1268 TEST_ASSERT_EQUAL(slave_count, 0,
1269 "Number of active slaves (%d) is not as expected (%d)",
1272 /* bring one slave port up so link status will change */
1273 test_lsc_interrupt_count = 0;
1275 virtual_ethdev_simulate_link_status_interrupt(
1276 test_params->slave_port_ids[0], 1);
1278 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1279 "timed out waiting for interrupt");
1281 /* test that we have received another lsc interrupt */
1282 TEST_ASSERT(test_lsc_interrupt_count > 0,
1283 "Did not receive link status change interrupt");
1285 /* Verify that calling the same slave lsc interrupt doesn't cause another
1286 * lsc interrupt from bonded device */
1287 test_lsc_interrupt_count = 0;
1289 virtual_ethdev_simulate_link_status_interrupt(
1290 test_params->slave_port_ids[0], 1);
1292 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1293 "received unexpected interrupt");
1295 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1296 "Did not receive link status change interrupt");
1299 /* unregister lsc callback before exiting */
1300 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1301 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1302 &test_params->bonded_port_id);
1304 /* Clean up and remove slaves from bonded device */
1305 return remove_slaves_and_stop_bonded_device();
1309 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1310 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1311 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1313 uint16_t pktlen, generated_burst_size, ether_type;
1317 ether_type = RTE_ETHER_TYPE_IPV4;
1319 ether_type = RTE_ETHER_TYPE_IPV6;
1322 initialize_eth_header(test_params->pkt_eth_hdr,
1323 (struct rte_ether_addr *)src_mac,
1324 (struct rte_ether_addr *)dst_mac_1,
1325 ether_type, vlan, vlan_id);
1327 initialize_eth_header(test_params->pkt_eth_hdr,
1328 (struct rte_ether_addr *)src_mac,
1329 (struct rte_ether_addr *)dst_mac_0,
1330 ether_type, vlan, vlan_id);
1333 if (toggle_udp_port)
1334 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1337 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1342 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1343 dst_addr_1, pktlen);
1345 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1346 dst_addr_0, pktlen);
1348 ip_hdr = test_params->pkt_ipv4_hdr;
1351 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1352 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1355 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1356 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1359 ip_hdr = test_params->pkt_ipv6_hdr;
1362 /* Generate burst of packets to transmit */
1363 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1364 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1365 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1367 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1368 "Failed to generate packet burst");
1370 return generated_burst_size;
1373 /** Round Robin Mode Tests */
1376 test_roundrobin_tx_burst(void)
1379 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1380 struct rte_eth_stats port_stats;
1382 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1383 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1384 "Failed to initialise bonded device");
1386 burst_size = 20 * test_params->bonded_slave_count;
1388 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1389 "Burst size specified is greater than supported.");
1391 /* Generate test bursts of packets to transmit */
1392 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1393 burst_size, "failed to generate test burst");
1395 /* Send burst on bonded port */
1396 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1397 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1400 /* Verify bonded port tx stats */
1401 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1402 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1403 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1404 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1407 /* Verify slave ports tx stats */
1408 for (i = 0; i < test_params->bonded_slave_count; i++) {
1409 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1410 TEST_ASSERT_EQUAL(port_stats.opackets,
1411 (uint64_t)burst_size / test_params->bonded_slave_count,
1412 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1413 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1414 burst_size / test_params->bonded_slave_count);
1417 /* Put all slaves down and try and transmit */
1418 for (i = 0; i < test_params->bonded_slave_count; i++) {
1419 virtual_ethdev_simulate_link_status_interrupt(
1420 test_params->slave_port_ids[i], 0);
1423 /* Send burst on bonded port */
1424 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1425 pkt_burst, burst_size), 0,
1426 "tx burst return unexpected value");
1428 /* Clean up and remove slaves from bonded device */
1429 return remove_slaves_and_stop_bonded_device();
1433 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1437 for (i = 0; i < nb_mbufs; i++) {
1438 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1439 TEST_ASSERT_EQUAL(refcnt, val,
1440 "mbuf ref count (%d)is not the expected value (%d)",
1447 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1451 for (i = 0; i < nb_mbufs; i++)
1452 rte_pktmbuf_free(mbufs[i]);
1455 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1456 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1457 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1458 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1461 test_roundrobin_tx_burst_slave_tx_fail(void)
1463 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1464 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1466 struct rte_eth_stats port_stats;
1468 int i, first_fail_idx, tx_count;
1470 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1471 BONDING_MODE_ROUND_ROBIN, 0,
1472 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1473 "Failed to initialise bonded device");
1475 /* Generate test bursts of packets to transmit */
1476 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1477 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1478 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1479 "Failed to generate test packet burst");
1481 /* Copy references to packets which we expect not to be transmitted */
1482 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1483 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1484 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1485 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1487 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1488 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1489 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1492 /* Set virtual slave to only fail transmission of
1493 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1494 virtual_ethdev_tx_burst_fn_set_success(
1495 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1498 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1499 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1500 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1502 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1503 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1505 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1506 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1507 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1508 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1509 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1511 /* Verify that failed packet are expected failed packets */
1512 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1513 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1514 "expected mbuf (%d) pointer %p not expected pointer %p",
1515 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1518 /* Verify bonded port tx stats */
1519 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1521 TEST_ASSERT_EQUAL(port_stats.opackets,
1522 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1523 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1524 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1525 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1526 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1527 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1529 /* Verify slave ports tx stats */
1530 for (i = 0; i < test_params->bonded_slave_count; i++) {
1531 int slave_expected_tx_count;
1533 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1535 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1536 test_params->bonded_slave_count;
1538 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1539 slave_expected_tx_count = slave_expected_tx_count -
1540 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1542 TEST_ASSERT_EQUAL(port_stats.opackets,
1543 (uint64_t)slave_expected_tx_count,
1544 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1545 test_params->slave_port_ids[i],
1546 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1549 /* Verify that all mbufs have a ref value of zero */
1550 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1551 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1552 "mbufs refcnts not as expected");
1553 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1555 /* Clean up and remove slaves from bonded device */
1556 return remove_slaves_and_stop_bonded_device();
1560 test_roundrobin_rx_burst_on_single_slave(void)
1562 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1563 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1565 struct rte_eth_stats port_stats;
1567 int i, j, burst_size = 25;
1569 /* Initialize bonded device with 4 slaves in round robin mode */
1570 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1571 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1572 "Failed to initialize bonded device with slaves");
1574 /* Generate test bursts of packets to transmit */
1575 TEST_ASSERT_EQUAL(generate_test_burst(
1576 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1577 "burst generation failed");
1579 for (i = 0; i < test_params->bonded_slave_count; i++) {
1580 /* Add rx data to slave */
1581 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1582 &gen_pkt_burst[0], burst_size);
1584 /* Call rx burst on bonded device */
1585 /* Send burst on bonded port */
1586 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1587 test_params->bonded_port_id, 0, rx_pkt_burst,
1588 MAX_PKT_BURST), burst_size,
1589 "round-robin rx burst failed");
1591 /* Verify bonded device rx count */
1592 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1593 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1594 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1595 test_params->bonded_port_id,
1596 (unsigned int)port_stats.ipackets, burst_size);
1600 /* Verify bonded slave devices rx count */
1601 /* Verify slave ports tx stats */
1602 for (j = 0; j < test_params->bonded_slave_count; j++) {
1603 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1606 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1607 "Slave Port (%d) ipackets value (%u) not as expected"
1608 " (%d)", test_params->slave_port_ids[i],
1609 (unsigned int)port_stats.ipackets, burst_size);
1611 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1612 "Slave Port (%d) ipackets value (%u) not as expected"
1613 " (%d)", test_params->slave_port_ids[i],
1614 (unsigned int)port_stats.ipackets, 0);
1617 /* Reset bonded slaves stats */
1618 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1620 /* reset bonded device stats */
1621 rte_eth_stats_reset(test_params->bonded_port_id);
1625 for (i = 0; i < MAX_PKT_BURST; i++) {
1626 if (rx_pkt_burst[i] != NULL)
1627 rte_pktmbuf_free(rx_pkt_burst[i]);
1631 /* Clean up and remove slaves from bonded device */
1632 return remove_slaves_and_stop_bonded_device();
1635 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1638 test_roundrobin_rx_burst_on_multiple_slaves(void)
1640 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1642 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1643 struct rte_eth_stats port_stats;
1645 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1648 /* Initialize bonded device with 4 slaves in round robin mode */
1649 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1650 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1651 "Failed to initialize bonded device with slaves");
1653 /* Generate test bursts of packets to transmit */
1654 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1655 TEST_ASSERT_EQUAL(generate_test_burst(
1656 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1657 burst_size[i], "burst generation failed");
1660 /* Add rx data to slaves */
1661 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1662 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1663 &gen_pkt_burst[i][0], burst_size[i]);
1666 /* Call rx burst on bonded device */
1667 /* Send burst on bonded port */
1668 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1670 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1671 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1672 burst_size[0] + burst_size[1] + burst_size[2]);
1674 /* Verify bonded device rx count */
1675 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1676 TEST_ASSERT_EQUAL(port_stats.ipackets,
1677 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1678 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1679 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1680 burst_size[0] + burst_size[1] + burst_size[2]);
1682 /* Verify bonded slave devices rx counts */
1683 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1684 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1685 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1686 test_params->slave_port_ids[0],
1687 (unsigned int)port_stats.ipackets, burst_size[0]);
1689 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1690 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1691 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1692 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1695 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1696 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1697 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1698 test_params->slave_port_ids[2],
1699 (unsigned int)port_stats.ipackets, burst_size[2]);
1701 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1702 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1703 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1704 test_params->slave_port_ids[3],
1705 (unsigned int)port_stats.ipackets, 0);
1708 for (i = 0; i < MAX_PKT_BURST; i++) {
1709 if (rx_pkt_burst[i] != NULL)
1710 rte_pktmbuf_free(rx_pkt_burst[i]);
1713 /* Clean up and remove slaves from bonded device */
1714 return remove_slaves_and_stop_bonded_device();
1718 test_roundrobin_verify_mac_assignment(void)
1720 struct rte_ether_addr read_mac_addr;
1721 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_2;
1725 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
1726 "Failed to get mac address (port %d)",
1727 test_params->slave_port_ids[0]);
1728 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2),
1729 "Failed to get mac address (port %d)",
1730 test_params->slave_port_ids[2]);
1732 /* Initialize bonded device with 4 slaves in round robin mode */
1733 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1734 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1735 "Failed to initialize bonded device with slaves");
1737 /* Verify that all MACs are the same as first slave added to bonded dev */
1738 for (i = 0; i < test_params->bonded_slave_count; i++) {
1739 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1740 "Failed to get mac address (port %d)",
1741 test_params->slave_port_ids[i]);
1742 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1743 sizeof(read_mac_addr)),
1744 "slave port (%d) mac address not set to that of primary port",
1745 test_params->slave_port_ids[i]);
1748 /* change primary and verify that MAC addresses haven't changed */
1749 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1750 test_params->slave_port_ids[2]),
1751 "Failed to set bonded port (%d) primary port to (%d)",
1752 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1754 for (i = 0; i < test_params->bonded_slave_count; i++) {
1755 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1756 "Failed to get mac address (port %d)",
1757 test_params->slave_port_ids[i]);
1758 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1759 sizeof(read_mac_addr)),
1760 "slave port (%d) mac address has changed to that of primary"
1761 " port without stop/start toggle of bonded device",
1762 test_params->slave_port_ids[i]);
1765 /* stop / start bonded device and verify that primary MAC address is
1766 * propagate to bonded device and slaves */
1767 rte_eth_dev_stop(test_params->bonded_port_id);
1769 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1770 "Failed to start bonded device");
1772 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1773 "Failed to get mac address (port %d)",
1774 test_params->bonded_port_id);
1775 TEST_ASSERT_SUCCESS(
1776 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1777 "bonded port (%d) mac address not set to that of new primary port",
1778 test_params->slave_port_ids[i]);
1780 for (i = 0; i < test_params->bonded_slave_count; i++) {
1781 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1782 "Failed to get mac address (port %d)",
1783 test_params->slave_port_ids[i]);
1784 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1785 sizeof(read_mac_addr)),
1786 "slave port (%d) mac address not set to that of new primary"
1787 " port", test_params->slave_port_ids[i]);
1790 /* Set explicit MAC address */
1791 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1792 test_params->bonded_port_id,
1793 (struct rte_ether_addr *)bonded_mac),
1794 "Failed to set MAC");
1796 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
1797 "Failed to get mac address (port %d)",
1798 test_params->bonded_port_id);
1799 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1800 sizeof(read_mac_addr)),
1801 "bonded port (%d) mac address not set to that of new primary port",
1802 test_params->slave_port_ids[i]);
1804 for (i = 0; i < test_params->bonded_slave_count; i++) {
1805 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
1806 "Failed to get mac address (port %d)",
1807 test_params->slave_port_ids[i]);
1808 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1809 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1810 " that of new primary port\n", test_params->slave_port_ids[i]);
1813 /* Clean up and remove slaves from bonded device */
1814 return remove_slaves_and_stop_bonded_device();
1818 test_roundrobin_verify_promiscuous_enable_disable(void)
1820 int i, promiscuous_en;
1823 /* Initialize bonded device with 4 slaves in round robin mode */
1824 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1825 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1826 "Failed to initialize bonded device with slaves");
1828 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
1829 TEST_ASSERT_SUCCESS(ret,
1830 "Failed to enable promiscuous mode for port %d: %s",
1831 test_params->bonded_port_id, rte_strerror(-ret));
1833 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1834 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1835 "Port (%d) promiscuous mode not enabled",
1836 test_params->bonded_port_id);
1838 for (i = 0; i < test_params->bonded_slave_count; i++) {
1839 promiscuous_en = rte_eth_promiscuous_get(
1840 test_params->slave_port_ids[i]);
1841 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1842 "slave port (%d) promiscuous mode not enabled",
1843 test_params->slave_port_ids[i]);
1846 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
1847 TEST_ASSERT_SUCCESS(ret,
1848 "Failed to disable promiscuous mode for port %d: %s",
1849 test_params->bonded_port_id, rte_strerror(-ret));
1851 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1852 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1853 "Port (%d) promiscuous mode not disabled\n",
1854 test_params->bonded_port_id);
1856 for (i = 0; i < test_params->bonded_slave_count; i++) {
1857 promiscuous_en = rte_eth_promiscuous_get(
1858 test_params->slave_port_ids[i]);
1859 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1860 "Port (%d) promiscuous mode not disabled\n",
1861 test_params->slave_port_ids[i]);
1864 /* Clean up and remove slaves from bonded device */
1865 return remove_slaves_and_stop_bonded_device();
1868 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1869 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1872 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1874 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1875 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1876 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1878 struct rte_eth_stats port_stats;
1879 uint16_t slaves[RTE_MAX_ETHPORTS];
1881 int i, burst_size, slave_count;
1883 /* NULL all pointers in array to simplify cleanup */
1884 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1886 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1887 * in round robin mode */
1888 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1889 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1890 "Failed to initialize bonded device with slaves");
1892 /* Verify Current Slaves Count /Active Slave Count is */
1893 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1895 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1896 "Number of slaves (%d) is not as expected (%d).",
1897 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1899 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1900 slaves, RTE_MAX_ETHPORTS);
1901 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1902 "Number of active slaves (%d) is not as expected (%d).",
1903 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1905 /* Set 2 slaves eth_devs link status to down */
1906 virtual_ethdev_simulate_link_status_interrupt(
1907 test_params->slave_port_ids[1], 0);
1908 virtual_ethdev_simulate_link_status_interrupt(
1909 test_params->slave_port_ids[3], 0);
1911 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1912 slaves, RTE_MAX_ETHPORTS);
1913 TEST_ASSERT_EQUAL(slave_count,
1914 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1915 "Number of active slaves (%d) is not as expected (%d).\n",
1916 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1920 /* Verify that pkts are not sent on slaves with link status down:
1922 * 1. Generate test burst of traffic
1923 * 2. Transmit burst on bonded eth_dev
1924 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1925 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1928 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1929 burst_size, "generate_test_burst failed");
1931 rte_eth_stats_reset(test_params->bonded_port_id);
1935 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1936 burst_size), burst_size, "rte_eth_tx_burst failed");
1938 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1939 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1940 "Port (%d) opackets stats (%d) not expected (%d) value",
1941 test_params->bonded_port_id, (int)port_stats.opackets,
1944 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1945 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1946 "Port (%d) opackets stats (%d) not expected (%d) value",
1947 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1949 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1950 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1951 "Port (%d) opackets stats (%d) not expected (%d) value",
1952 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1954 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1955 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1956 "Port (%d) opackets stats (%d) not expected (%d) value",
1957 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1959 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1960 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1961 "Port (%d) opackets stats (%d) not expected (%d) value",
1962 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1964 /* Verify that pkts are not sent on slaves with link status down:
1966 * 1. Generate test bursts of traffic
1967 * 2. Add bursts on to virtual eth_devs
1968 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1969 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1970 * 4. Verify stats for bonded eth_dev
1971 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1973 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1974 TEST_ASSERT_EQUAL(generate_test_burst(
1975 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1976 burst_size, "failed to generate packet burst");
1978 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1979 &gen_pkt_burst[i][0], burst_size);
1982 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1983 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1984 burst_size + burst_size,
1985 "rte_eth_rx_burst failed");
1987 /* Verify bonded device rx count */
1988 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1989 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1990 "(%d) port_stats.ipackets not as expected\n",
1991 test_params->bonded_port_id);
1994 for (i = 0; i < MAX_PKT_BURST; i++) {
1995 if (rx_pkt_burst[i] != NULL)
1996 rte_pktmbuf_free(rx_pkt_burst[i]);
1999 /* Clean up and remove slaves from bonded device */
2000 return remove_slaves_and_stop_bonded_device();
2003 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
2005 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
2008 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2011 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2013 struct rte_ether_addr *mac_addr =
2014 (struct rte_ether_addr *)polling_slave_mac;
2015 char slave_name[RTE_ETH_NAME_MAX_LEN];
2019 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2020 /* Generate slave name / MAC address */
2021 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2022 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i;
2024 /* Create slave devices with no ISR Support */
2025 if (polling_test_slaves[i] == -1) {
2026 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2027 rte_socket_id(), 0);
2028 TEST_ASSERT(polling_test_slaves[i] >= 0,
2029 "Failed to create virtual virtual ethdev %s\n", slave_name);
2031 /* Configure slave */
2032 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2033 "Failed to configure virtual ethdev %s(%d)", slave_name,
2034 polling_test_slaves[i]);
2037 /* Add slave to bonded device */
2038 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2039 polling_test_slaves[i]),
2040 "Failed to add slave %s(%d) to bonded device %d",
2041 slave_name, polling_test_slaves[i],
2042 test_params->bonded_port_id);
2045 /* Initialize bonded device */
2046 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2047 "Failed to configure bonded device %d",
2048 test_params->bonded_port_id);
2051 /* Register link status change interrupt callback */
2052 rte_eth_dev_callback_register(test_params->bonded_port_id,
2053 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2054 &test_params->bonded_port_id);
2056 /* link status change callback for first slave link up */
2057 test_lsc_interrupt_count = 0;
2059 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2061 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2064 /* no link status change callback for second slave link up */
2065 test_lsc_interrupt_count = 0;
2067 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2069 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2071 /* link status change callback for both slave links down */
2072 test_lsc_interrupt_count = 0;
2074 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2075 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2077 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2079 /* Un-Register link status change interrupt callback */
2080 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2081 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2082 &test_params->bonded_port_id);
2085 /* Clean up and remove slaves from bonded device */
2086 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2088 TEST_ASSERT_SUCCESS(
2089 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2090 polling_test_slaves[i]),
2091 "Failed to remove slave %d from bonded port (%d)",
2092 polling_test_slaves[i], test_params->bonded_port_id);
2095 return remove_slaves_and_stop_bonded_device();
2099 /** Active Backup Mode Tests */
2102 test_activebackup_tx_burst(void)
2104 int i, pktlen, primary_port, burst_size;
2105 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2106 struct rte_eth_stats port_stats;
2108 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2109 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2110 "Failed to initialize bonded device with slaves");
2112 initialize_eth_header(test_params->pkt_eth_hdr,
2113 (struct rte_ether_addr *)src_mac,
2114 (struct rte_ether_addr *)dst_mac_0,
2115 RTE_ETHER_TYPE_IPV4, 0, 0);
2116 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2118 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2119 dst_addr_0, pktlen);
2121 burst_size = 20 * test_params->bonded_slave_count;
2123 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2124 "Burst size specified is greater than supported.");
2126 /* Generate a burst of packets to transmit */
2127 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2128 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2129 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2130 burst_size, "failed to generate burst correctly");
2132 /* Send burst on bonded port */
2133 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2134 burst_size), burst_size, "tx burst failed");
2136 /* Verify bonded port tx stats */
2137 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2138 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2139 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2140 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2143 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2145 /* Verify slave ports tx stats */
2146 for (i = 0; i < test_params->bonded_slave_count; i++) {
2147 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2148 if (test_params->slave_port_ids[i] == primary_port) {
2149 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2150 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2151 test_params->bonded_port_id,
2152 (unsigned int)port_stats.opackets,
2153 burst_size / test_params->bonded_slave_count);
2155 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2156 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2157 test_params->bonded_port_id,
2158 (unsigned int)port_stats.opackets, 0);
2162 /* Put all slaves down and try and transmit */
2163 for (i = 0; i < test_params->bonded_slave_count; i++) {
2164 virtual_ethdev_simulate_link_status_interrupt(
2165 test_params->slave_port_ids[i], 0);
2168 /* Send burst on bonded port */
2169 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2170 pkts_burst, burst_size), 0, "Sending empty burst failed");
2172 /* Clean up and remove slaves from bonded device */
2173 return remove_slaves_and_stop_bonded_device();
2176 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2179 test_activebackup_rx_burst(void)
2181 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2182 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2184 struct rte_eth_stats port_stats;
2188 int i, j, burst_size = 17;
2190 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2191 BONDING_MODE_ACTIVE_BACKUP, 0,
2192 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2193 "Failed to initialize bonded device with slaves");
2195 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2196 TEST_ASSERT(primary_port >= 0,
2197 "failed to get primary slave for bonded port (%d)",
2198 test_params->bonded_port_id);
2200 for (i = 0; i < test_params->bonded_slave_count; i++) {
2201 /* Generate test bursts of packets to transmit */
2202 TEST_ASSERT_EQUAL(generate_test_burst(
2203 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2204 burst_size, "burst generation failed");
2206 /* Add rx data to slave */
2207 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2208 &gen_pkt_burst[0], burst_size);
2210 /* Call rx burst on bonded device */
2211 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2212 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2213 "rte_eth_rx_burst failed");
2215 if (test_params->slave_port_ids[i] == primary_port) {
2216 /* Verify bonded device rx count */
2217 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2218 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2219 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2220 test_params->bonded_port_id,
2221 (unsigned int)port_stats.ipackets, burst_size);
2223 /* Verify bonded slave devices rx count */
2224 for (j = 0; j < test_params->bonded_slave_count; j++) {
2225 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2227 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2228 "Slave Port (%d) ipackets value (%u) not as "
2229 "expected (%d)", test_params->slave_port_ids[i],
2230 (unsigned int)port_stats.ipackets, burst_size);
2232 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2233 "Slave Port (%d) ipackets value (%u) not as "
2234 "expected (%d)\n", test_params->slave_port_ids[i],
2235 (unsigned int)port_stats.ipackets, 0);
2239 for (j = 0; j < test_params->bonded_slave_count; j++) {
2240 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2241 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2242 "Slave Port (%d) ipackets value (%u) not as expected "
2243 "(%d)", test_params->slave_port_ids[i],
2244 (unsigned int)port_stats.ipackets, 0);
2249 for (i = 0; i < MAX_PKT_BURST; i++) {
2250 if (rx_pkt_burst[i] != NULL) {
2251 rte_pktmbuf_free(rx_pkt_burst[i]);
2252 rx_pkt_burst[i] = NULL;
2256 /* reset bonded device stats */
2257 rte_eth_stats_reset(test_params->bonded_port_id);
2260 /* Clean up and remove slaves from bonded device */
2261 return remove_slaves_and_stop_bonded_device();
2265 test_activebackup_verify_promiscuous_enable_disable(void)
2267 int i, primary_port, promiscuous_en;
2270 /* Initialize bonded device with 4 slaves in round robin mode */
2271 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2272 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2273 "Failed to initialize bonded device with slaves");
2275 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2276 TEST_ASSERT(primary_port >= 0,
2277 "failed to get primary slave for bonded port (%d)",
2278 test_params->bonded_port_id);
2280 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
2281 TEST_ASSERT_SUCCESS(ret,
2282 "Failed to enable promiscuous mode for port %d: %s",
2283 test_params->bonded_port_id, rte_strerror(-ret));
2285 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2286 "Port (%d) promiscuous mode not enabled",
2287 test_params->bonded_port_id);
2289 for (i = 0; i < test_params->bonded_slave_count; i++) {
2290 promiscuous_en = rte_eth_promiscuous_get(
2291 test_params->slave_port_ids[i]);
2292 if (primary_port == test_params->slave_port_ids[i]) {
2293 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2294 "slave port (%d) promiscuous mode not enabled",
2295 test_params->slave_port_ids[i]);
2297 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2298 "slave port (%d) promiscuous mode enabled",
2299 test_params->slave_port_ids[i]);
2304 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
2305 TEST_ASSERT_SUCCESS(ret,
2306 "Failed to disable promiscuous mode for port %d: %s",
2307 test_params->bonded_port_id, rte_strerror(-ret));
2309 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2310 "Port (%d) promiscuous mode not disabled\n",
2311 test_params->bonded_port_id);
2313 for (i = 0; i < test_params->bonded_slave_count; i++) {
2314 promiscuous_en = rte_eth_promiscuous_get(
2315 test_params->slave_port_ids[i]);
2316 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2317 "slave port (%d) promiscuous mode not disabled\n",
2318 test_params->slave_port_ids[i]);
2321 /* Clean up and remove slaves from bonded device */
2322 return remove_slaves_and_stop_bonded_device();
2326 test_activebackup_verify_mac_assignment(void)
2328 struct rte_ether_addr read_mac_addr;
2329 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
2331 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
2332 "Failed to get mac address (port %d)",
2333 test_params->slave_port_ids[0]);
2334 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
2335 "Failed to get mac address (port %d)",
2336 test_params->slave_port_ids[1]);
2338 /* Initialize bonded device with 2 slaves in active backup mode */
2339 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2340 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2341 "Failed to initialize bonded device with slaves");
2343 /* Verify that bonded MACs is that of first slave and that the other slave
2344 * MAC hasn't been changed */
2345 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2346 "Failed to get mac address (port %d)",
2347 test_params->bonded_port_id);
2348 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2349 sizeof(read_mac_addr)),
2350 "bonded port (%d) mac address not set to that of primary port",
2351 test_params->bonded_port_id);
2353 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2354 "Failed to get mac address (port %d)",
2355 test_params->slave_port_ids[0]);
2356 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2357 sizeof(read_mac_addr)),
2358 "slave port (%d) mac address not set to that of primary port",
2359 test_params->slave_port_ids[0]);
2361 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2362 "Failed to get mac address (port %d)",
2363 test_params->slave_port_ids[1]);
2364 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2365 sizeof(read_mac_addr)),
2366 "slave port (%d) mac address not as expected",
2367 test_params->slave_port_ids[1]);
2369 /* change primary and verify that MAC addresses haven't changed */
2370 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2371 test_params->slave_port_ids[1]), 0,
2372 "Failed to set bonded port (%d) primary port to (%d)",
2373 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2375 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2376 "Failed to get mac address (port %d)",
2377 test_params->bonded_port_id);
2378 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2379 sizeof(read_mac_addr)),
2380 "bonded port (%d) mac address not set to that of primary port",
2381 test_params->bonded_port_id);
2383 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2384 "Failed to get mac address (port %d)",
2385 test_params->slave_port_ids[0]);
2386 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2387 sizeof(read_mac_addr)),
2388 "slave port (%d) mac address not set to that of primary port",
2389 test_params->slave_port_ids[0]);
2391 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2392 "Failed to get mac address (port %d)",
2393 test_params->slave_port_ids[1]);
2394 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2395 sizeof(read_mac_addr)),
2396 "slave port (%d) mac address not as expected",
2397 test_params->slave_port_ids[1]);
2399 /* stop / start bonded device and verify that primary MAC address is
2400 * propagated to bonded device and slaves */
2402 rte_eth_dev_stop(test_params->bonded_port_id);
2404 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2405 "Failed to start device");
2407 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2408 "Failed to get mac address (port %d)",
2409 test_params->bonded_port_id);
2410 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2411 sizeof(read_mac_addr)),
2412 "bonded port (%d) mac address not set to that of primary port",
2413 test_params->bonded_port_id);
2415 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2416 "Failed to get mac address (port %d)",
2417 test_params->slave_port_ids[0]);
2418 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2419 sizeof(read_mac_addr)),
2420 "slave port (%d) mac address not as expected",
2421 test_params->slave_port_ids[0]);
2423 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2424 "Failed to get mac address (port %d)",
2425 test_params->slave_port_ids[1]);
2426 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2427 sizeof(read_mac_addr)),
2428 "slave port (%d) mac address not set to that of primary port",
2429 test_params->slave_port_ids[1]);
2431 /* Set explicit MAC address */
2432 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2433 test_params->bonded_port_id,
2434 (struct rte_ether_addr *)bonded_mac),
2435 "failed to set MAC address");
2437 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
2438 "Failed to get mac address (port %d)",
2439 test_params->bonded_port_id);
2440 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2441 sizeof(read_mac_addr)),
2442 "bonded port (%d) mac address not set to that of bonded port",
2443 test_params->bonded_port_id);
2445 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
2446 "Failed to get mac address (port %d)",
2447 test_params->slave_port_ids[0]);
2448 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2449 sizeof(read_mac_addr)),
2450 "slave port (%d) mac address not as expected",
2451 test_params->slave_port_ids[0]);
2453 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
2454 "Failed to get mac address (port %d)",
2455 test_params->slave_port_ids[1]);
2456 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2457 sizeof(read_mac_addr)),
2458 "slave port (%d) mac address not set to that of bonded port",
2459 test_params->slave_port_ids[1]);
2461 /* Clean up and remove slaves from bonded device */
2462 return remove_slaves_and_stop_bonded_device();
2466 test_activebackup_verify_slave_link_status_change_failover(void)
2468 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2469 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2470 struct rte_eth_stats port_stats;
2472 uint16_t slaves[RTE_MAX_ETHPORTS];
2474 int i, burst_size, slave_count, primary_port;
2478 memset(pkt_burst, 0, sizeof(pkt_burst));
2480 /* Generate packet burst for testing */
2481 TEST_ASSERT_EQUAL(generate_test_burst(
2482 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2483 "generate_test_burst failed");
2485 /* Initialize bonded device with 4 slaves in round robin mode */
2486 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2487 BONDING_MODE_ACTIVE_BACKUP, 0,
2488 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2489 "Failed to initialize bonded device with slaves");
2491 /* Verify Current Slaves Count /Active Slave Count is */
2492 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2494 TEST_ASSERT_EQUAL(slave_count, 4,
2495 "Number of slaves (%d) is not as expected (%d).",
2498 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2499 slaves, RTE_MAX_ETHPORTS);
2500 TEST_ASSERT_EQUAL(slave_count, 4,
2501 "Number of active slaves (%d) is not as expected (%d).",
2504 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2505 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2506 "Primary port not as expected");
2508 /* Bring 2 slaves down and verify active slave count */
2509 virtual_ethdev_simulate_link_status_interrupt(
2510 test_params->slave_port_ids[1], 0);
2511 virtual_ethdev_simulate_link_status_interrupt(
2512 test_params->slave_port_ids[3], 0);
2514 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2515 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2516 "Number of active slaves (%d) is not as expected (%d).",
2519 virtual_ethdev_simulate_link_status_interrupt(
2520 test_params->slave_port_ids[1], 1);
2521 virtual_ethdev_simulate_link_status_interrupt(
2522 test_params->slave_port_ids[3], 1);
2525 /* Bring primary port down, verify that active slave count is 3 and primary
2527 virtual_ethdev_simulate_link_status_interrupt(
2528 test_params->slave_port_ids[0], 0);
2530 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2531 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2533 "Number of active slaves (%d) is not as expected (%d).",
2536 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2537 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2538 "Primary port not as expected");
2540 /* Verify that pkts are sent on new primary slave */
2542 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2543 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2544 burst_size), burst_size, "rte_eth_tx_burst failed");
2546 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2547 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2548 "(%d) port_stats.opackets not as expected",
2549 test_params->slave_port_ids[2]);
2551 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2552 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2553 "(%d) port_stats.opackets not as expected\n",
2554 test_params->slave_port_ids[0]);
2556 rte_eth_stats_get(test_params->slave_port_ids[1], &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[1]);
2561 rte_eth_stats_get(test_params->slave_port_ids[3], &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[3]);
2566 /* Generate packet burst for testing */
2568 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2569 TEST_ASSERT_EQUAL(generate_test_burst(
2570 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2571 "generate_test_burst failed");
2573 virtual_ethdev_add_mbufs_to_rx_queue(
2574 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2577 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2578 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2579 burst_size, "rte_eth_rx_burst\n");
2581 /* Verify bonded device rx count */
2582 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2583 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2584 "(%d) port_stats.ipackets not as expected",
2585 test_params->bonded_port_id);
2587 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2588 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2589 "(%d) port_stats.opackets not as expected",
2590 test_params->slave_port_ids[2]);
2592 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2593 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2594 "(%d) port_stats.opackets not as expected",
2595 test_params->slave_port_ids[0]);
2597 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2598 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2599 "(%d) port_stats.opackets not as expected",
2600 test_params->slave_port_ids[1]);
2602 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2603 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2604 "(%d) port_stats.opackets not as expected",
2605 test_params->slave_port_ids[3]);
2607 /* Clean up and remove slaves from bonded device */
2608 return remove_slaves_and_stop_bonded_device();
2611 /** Balance Mode Tests */
2614 test_balance_xmit_policy_configuration(void)
2616 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2617 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2618 "Failed to initialize_bonded_device_with_slaves.");
2620 /* Invalid port id */
2621 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2622 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2623 "Expected call to failed as invalid port specified.");
2625 /* Set xmit policy on non bonded device */
2626 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2627 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2628 "Expected call to failed as invalid port specified.");
2631 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2632 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2633 "Failed to set balance xmit policy.");
2635 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2636 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2639 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2640 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2641 "Failed to set balance xmit policy.");
2643 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2644 BALANCE_XMIT_POLICY_LAYER23,
2645 "balance xmit policy not as expected.");
2648 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2649 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2650 "Failed to set balance xmit policy.");
2652 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2653 BALANCE_XMIT_POLICY_LAYER34,
2654 "balance xmit policy not as expected.");
2656 /* Invalid port id */
2657 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2658 "Expected call to failed as invalid port specified.");
2660 /* Clean up and remove slaves from bonded device */
2661 return remove_slaves_and_stop_bonded_device();
2664 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2667 test_balance_l2_tx_burst(void)
2669 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2670 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2674 struct rte_eth_stats port_stats;
2676 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2677 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2678 "Failed to initialize_bonded_device_with_slaves.");
2680 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2681 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2682 "Failed to set balance xmit policy.");
2684 initialize_eth_header(test_params->pkt_eth_hdr,
2685 (struct rte_ether_addr *)src_mac,
2686 (struct rte_ether_addr *)dst_mac_0,
2687 RTE_ETHER_TYPE_IPV4, 0, 0);
2688 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2690 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2691 dst_addr_0, pktlen);
2693 /* Generate a burst 1 of packets to transmit */
2694 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2695 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2696 test_params->pkt_udp_hdr, burst_size[0],
2697 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2698 "failed to generate packet burst");
2700 initialize_eth_header(test_params->pkt_eth_hdr,
2701 (struct rte_ether_addr *)src_mac,
2702 (struct rte_ether_addr *)dst_mac_1,
2703 RTE_ETHER_TYPE_IPV4, 0, 0);
2705 /* Generate a burst 2 of packets to transmit */
2706 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2707 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2708 test_params->pkt_udp_hdr, burst_size[1],
2709 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2710 "failed to generate packet burst");
2712 /* Send burst 1 on bonded port */
2713 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2714 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2715 &pkts_burst[i][0], burst_size[i]),
2716 burst_size[i], "Failed to transmit packet burst");
2719 /* Verify bonded port tx stats */
2720 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2721 TEST_ASSERT_EQUAL(port_stats.opackets,
2722 (uint64_t)(burst_size[0] + burst_size[1]),
2723 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2724 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2725 burst_size[0] + burst_size[1]);
2728 /* Verify slave ports tx stats */
2729 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2730 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2731 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2732 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2735 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2736 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2737 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2738 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2741 /* Put all slaves down and try and transmit */
2742 for (i = 0; i < test_params->bonded_slave_count; i++) {
2744 virtual_ethdev_simulate_link_status_interrupt(
2745 test_params->slave_port_ids[i], 0);
2748 /* Send burst on bonded port */
2749 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2750 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2751 0, "Expected zero packet");
2753 /* Clean up and remove slaves from bonded device */
2754 return remove_slaves_and_stop_bonded_device();
2758 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2759 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2761 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2763 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2764 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2766 struct rte_eth_stats port_stats;
2768 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2769 BONDING_MODE_BALANCE, 0, 2, 1),
2770 "Failed to initialize_bonded_device_with_slaves.");
2772 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2773 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2774 "Failed to set balance xmit policy.");
2779 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2780 "Burst size specified is greater than supported.");
2782 /* Generate test bursts of packets to transmit */
2783 TEST_ASSERT_EQUAL(generate_test_burst(
2784 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2785 burst_size_1, "failed to generate packet burst");
2787 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2788 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2789 "failed to generate packet burst");
2791 /* Send burst 1 on bonded port */
2792 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2794 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2796 /* Send burst 2 on bonded port */
2797 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2799 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2801 /* Verify bonded port tx stats */
2802 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2803 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2804 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2805 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2808 /* Verify slave ports tx stats */
2809 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2810 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2811 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2812 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2815 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2816 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2817 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2818 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2821 /* Put all slaves down and try and transmit */
2822 for (i = 0; i < test_params->bonded_slave_count; i++) {
2824 virtual_ethdev_simulate_link_status_interrupt(
2825 test_params->slave_port_ids[i], 0);
2828 /* Send burst on bonded port */
2829 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2830 test_params->bonded_port_id, 0, pkts_burst_1,
2831 burst_size_1), 0, "Expected zero packet");
2834 /* Clean up and remove slaves from bonded device */
2835 return remove_slaves_and_stop_bonded_device();
2839 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2841 return balance_l23_tx_burst(0, 1, 0, 1);
2845 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2847 return balance_l23_tx_burst(1, 1, 0, 1);
2851 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2853 return balance_l23_tx_burst(0, 0, 0, 1);
2857 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2859 return balance_l23_tx_burst(1, 0, 0, 1);
2863 test_balance_l23_tx_burst_toggle_mac_addr(void)
2865 return balance_l23_tx_burst(0, 0, 1, 0);
2869 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2870 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2871 uint8_t toggle_udp_port)
2873 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2875 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2876 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2878 struct rte_eth_stats port_stats;
2880 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2881 BONDING_MODE_BALANCE, 0, 2, 1),
2882 "Failed to initialize_bonded_device_with_slaves.");
2884 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2885 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2886 "Failed to set balance xmit policy.");
2891 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2892 "Burst size specified is greater than supported.");
2894 /* Generate test bursts of packets to transmit */
2895 TEST_ASSERT_EQUAL(generate_test_burst(
2896 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2897 burst_size_1, "failed to generate burst");
2899 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2900 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2901 toggle_udp_port), burst_size_2, "failed to generate burst");
2903 /* Send burst 1 on bonded port */
2904 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2906 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2908 /* Send burst 2 on bonded port */
2909 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2911 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2914 /* Verify bonded port tx stats */
2915 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2916 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2917 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2918 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2921 /* Verify slave ports tx stats */
2922 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2923 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2924 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2925 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2928 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2929 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2930 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2931 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2934 /* Put all slaves down and try and transmit */
2935 for (i = 0; i < test_params->bonded_slave_count; i++) {
2937 virtual_ethdev_simulate_link_status_interrupt(
2938 test_params->slave_port_ids[i], 0);
2941 /* Send burst on bonded port */
2942 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2943 test_params->bonded_port_id, 0, pkts_burst_1,
2944 burst_size_1), 0, "Expected zero packet");
2946 /* Clean up and remove slaves from bonded device */
2947 return remove_slaves_and_stop_bonded_device();
2951 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2953 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2957 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2959 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2963 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2965 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2969 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2971 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2975 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2977 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2981 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2983 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2986 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2987 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2988 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2989 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2990 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2993 test_balance_tx_burst_slave_tx_fail(void)
2995 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2996 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2998 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
3000 struct rte_eth_stats port_stats;
3002 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
3004 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3005 BONDING_MODE_BALANCE, 0,
3006 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3007 "Failed to initialise bonded device");
3009 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3010 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3011 "Failed to set balance xmit policy.");
3014 /* Generate test bursts for transmission */
3015 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
3016 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
3017 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
3018 "Failed to generate test packet burst 1");
3020 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3021 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
3023 /* copy mbuf referneces for expected transmission failures */
3024 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
3025 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
3027 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
3028 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
3029 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3030 "Failed to generate test packet burst 2");
3033 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3034 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3035 virtual_ethdev_tx_burst_fn_set_success(
3036 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3039 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3040 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3041 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3044 /* Transmit burst 1 */
3045 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3046 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3048 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3049 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3050 "Transmitted (%d) packets, expected to transmit (%d) packets",
3051 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3052 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3054 /* Verify that failed packet are expected failed packets */
3055 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3056 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3057 "expected mbuf (%d) pointer %p not expected pointer %p",
3058 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3061 /* Transmit burst 2 */
3062 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3063 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3065 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3066 "Transmitted (%d) packets, expected to transmit (%d) packets",
3067 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3070 /* Verify bonded port tx stats */
3071 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3073 TEST_ASSERT_EQUAL(port_stats.opackets,
3074 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3075 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3076 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3077 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3078 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3079 (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);
3083 /* Verify slave ports tx stats */
3085 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3087 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3088 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3089 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3090 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3091 test_params->slave_port_ids[0],
3092 (unsigned int)port_stats.opackets,
3093 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3094 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3099 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3101 TEST_ASSERT_EQUAL(port_stats.opackets,
3102 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3103 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3104 test_params->slave_port_ids[1],
3105 (unsigned int)port_stats.opackets,
3106 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3108 /* Verify that all mbufs have a ref value of zero */
3109 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3110 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3111 "mbufs refcnts not as expected");
3113 free_mbufs(&pkts_burst_1[tx_count_1],
3114 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3116 /* Clean up and remove slaves from bonded device */
3117 return remove_slaves_and_stop_bonded_device();
3120 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3123 test_balance_rx_burst(void)
3125 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3127 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3128 struct rte_eth_stats port_stats;
3130 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3133 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3135 /* Initialize bonded device with 4 slaves in round robin mode */
3136 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3137 BONDING_MODE_BALANCE, 0, 3, 1),
3138 "Failed to initialise bonded device");
3140 /* Generate test bursts of packets to transmit */
3141 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3142 TEST_ASSERT_EQUAL(generate_test_burst(
3143 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3144 0, 0), burst_size[i],
3145 "failed to generate packet burst");
3148 /* Add rx data to slaves */
3149 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3150 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3151 &gen_pkt_burst[i][0], burst_size[i]);
3154 /* Call rx burst on bonded device */
3155 /* Send burst on bonded port */
3156 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3157 rx_pkt_burst, MAX_PKT_BURST),
3158 burst_size[0] + burst_size[1] + burst_size[2],
3159 "balance rx burst failed\n");
3161 /* Verify bonded device rx count */
3162 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3163 TEST_ASSERT_EQUAL(port_stats.ipackets,
3164 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3165 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3166 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3167 burst_size[0] + burst_size[1] + burst_size[2]);
3170 /* Verify bonded slave devices rx counts */
3171 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3172 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3173 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3174 test_params->slave_port_ids[0],
3175 (unsigned int)port_stats.ipackets, burst_size[0]);
3177 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3178 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3179 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3180 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3183 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3184 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3185 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3186 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3189 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3190 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3191 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3192 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3196 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3197 for (j = 0; j < MAX_PKT_BURST; j++) {
3198 if (gen_pkt_burst[i][j] != NULL) {
3199 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3200 gen_pkt_burst[i][j] = NULL;
3205 /* Clean up and remove slaves from bonded device */
3206 return remove_slaves_and_stop_bonded_device();
3210 test_balance_verify_promiscuous_enable_disable(void)
3215 /* Initialize bonded device with 4 slaves in round robin mode */
3216 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3217 BONDING_MODE_BALANCE, 0, 4, 1),
3218 "Failed to initialise bonded device");
3220 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3221 TEST_ASSERT_SUCCESS(ret,
3222 "Failed to enable promiscuous mode for port %d: %s",
3223 test_params->bonded_port_id, rte_strerror(-ret));
3225 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3226 "Port (%d) promiscuous mode not enabled",
3227 test_params->bonded_port_id);
3229 for (i = 0; i < test_params->bonded_slave_count; i++) {
3230 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3231 test_params->slave_port_ids[i]), 1,
3232 "Port (%d) promiscuous mode not enabled",
3233 test_params->slave_port_ids[i]);
3236 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3237 TEST_ASSERT_SUCCESS(ret,
3238 "Failed to disable promiscuous mode for port %d: %s",
3239 test_params->bonded_port_id, rte_strerror(-ret));
3241 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3242 "Port (%d) promiscuous mode not disabled",
3243 test_params->bonded_port_id);
3245 for (i = 0; i < test_params->bonded_slave_count; i++) {
3246 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3247 test_params->slave_port_ids[i]), 0,
3248 "Port (%d) promiscuous mode not disabled",
3249 test_params->slave_port_ids[i]);
3252 /* Clean up and remove slaves from bonded device */
3253 return remove_slaves_and_stop_bonded_device();
3257 test_balance_verify_mac_assignment(void)
3259 struct rte_ether_addr read_mac_addr;
3260 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3262 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3263 "Failed to get mac address (port %d)",
3264 test_params->slave_port_ids[0]);
3265 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
3266 "Failed to get mac address (port %d)",
3267 test_params->slave_port_ids[1]);
3269 /* Initialize bonded device with 2 slaves in active backup mode */
3270 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3271 BONDING_MODE_BALANCE, 0, 2, 1),
3272 "Failed to initialise bonded device");
3274 /* Verify that bonded MACs is that of first slave and that the other slave
3275 * MAC hasn't been changed */
3276 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3277 "Failed to get mac address (port %d)",
3278 test_params->bonded_port_id);
3279 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3280 sizeof(read_mac_addr)),
3281 "bonded port (%d) mac address not set to that of primary port",
3282 test_params->bonded_port_id);
3284 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3285 "Failed to get mac address (port %d)",
3286 test_params->slave_port_ids[0]);
3287 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3288 sizeof(read_mac_addr)),
3289 "slave port (%d) mac address not set to that of primary port",
3290 test_params->slave_port_ids[0]);
3292 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3293 "Failed to get mac address (port %d)",
3294 test_params->slave_port_ids[1]);
3295 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3296 sizeof(read_mac_addr)),
3297 "slave port (%d) mac address not set to that of primary port",
3298 test_params->slave_port_ids[1]);
3300 /* change primary and verify that MAC addresses haven't changed */
3301 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3302 test_params->slave_port_ids[1]),
3303 "Failed to set bonded port (%d) primary port to (%d)\n",
3304 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3306 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3307 "Failed to get mac address (port %d)",
3308 test_params->bonded_port_id);
3309 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3310 sizeof(read_mac_addr)),
3311 "bonded port (%d) mac address not set to that of primary port",
3312 test_params->bonded_port_id);
3314 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3315 "Failed to get mac address (port %d)",
3316 test_params->slave_port_ids[0]);
3317 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3318 sizeof(read_mac_addr)),
3319 "slave port (%d) mac address not set to that of primary port",
3320 test_params->slave_port_ids[0]);
3322 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3323 "Failed to get mac address (port %d)",
3324 test_params->slave_port_ids[1]);
3325 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3326 sizeof(read_mac_addr)),
3327 "slave port (%d) mac address not set to that of primary port",
3328 test_params->slave_port_ids[1]);
3330 /* stop / start bonded device and verify that primary MAC address is
3331 * propagated to bonded device and slaves */
3333 rte_eth_dev_stop(test_params->bonded_port_id);
3335 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3336 "Failed to start bonded device");
3338 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3339 "Failed to get mac address (port %d)",
3340 test_params->bonded_port_id);
3341 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3342 sizeof(read_mac_addr)),
3343 "bonded port (%d) mac address not set to that of primary port",
3344 test_params->bonded_port_id);
3346 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3347 "Failed to get mac address (port %d)",
3348 test_params->slave_port_ids[0]);
3349 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3350 sizeof(read_mac_addr)),
3351 "slave port (%d) mac address not set to that of primary port",
3352 test_params->slave_port_ids[0]);
3354 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3355 "Failed to get mac address (port %d)",
3356 test_params->slave_port_ids[1]);
3357 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3358 sizeof(read_mac_addr)),
3359 "slave port (%d) mac address not set to that of primary port",
3360 test_params->slave_port_ids[1]);
3362 /* Set explicit MAC address */
3363 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3364 test_params->bonded_port_id,
3365 (struct rte_ether_addr *)bonded_mac),
3366 "failed to set MAC");
3368 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3369 "Failed to get mac address (port %d)",
3370 test_params->bonded_port_id);
3371 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3372 sizeof(read_mac_addr)),
3373 "bonded port (%d) mac address not set to that of bonded port",
3374 test_params->bonded_port_id);
3376 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
3377 "Failed to get mac address (port %d)",
3378 test_params->slave_port_ids[0]);
3379 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3380 sizeof(read_mac_addr)),
3381 "slave port (%d) mac address not as expected\n",
3382 test_params->slave_port_ids[0]);
3384 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
3385 "Failed to get mac address (port %d)",
3386 test_params->slave_port_ids[1]);
3387 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3388 sizeof(read_mac_addr)),
3389 "slave port (%d) mac address not set to that of bonded port",
3390 test_params->slave_port_ids[1]);
3392 /* Clean up and remove slaves from bonded device */
3393 return remove_slaves_and_stop_bonded_device();
3396 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3399 test_balance_verify_slave_link_status_change_behaviour(void)
3401 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3402 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3403 struct rte_eth_stats port_stats;
3405 uint16_t slaves[RTE_MAX_ETHPORTS];
3407 int i, burst_size, slave_count;
3409 memset(pkt_burst, 0, sizeof(pkt_burst));
3411 /* Initialize bonded device with 4 slaves in round robin mode */
3412 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3413 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3414 "Failed to initialise bonded device");
3416 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3417 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3418 "Failed to set balance xmit policy.");
3421 /* Verify Current Slaves Count /Active Slave Count is */
3422 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3424 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3425 "Number of slaves (%d) is not as expected (%d).",
3426 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3428 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3429 slaves, RTE_MAX_ETHPORTS);
3430 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3431 "Number of active slaves (%d) is not as expected (%d).",
3432 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3434 /* Set 2 slaves link status to down */
3435 virtual_ethdev_simulate_link_status_interrupt(
3436 test_params->slave_port_ids[1], 0);
3437 virtual_ethdev_simulate_link_status_interrupt(
3438 test_params->slave_port_ids[3], 0);
3440 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3441 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3442 "Number of active slaves (%d) is not as expected (%d).",
3445 /* Send to sets of packet burst and verify that they are balanced across
3449 TEST_ASSERT_EQUAL(generate_test_burst(
3450 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3451 "generate_test_burst failed");
3453 TEST_ASSERT_EQUAL(generate_test_burst(
3454 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3455 "generate_test_burst failed");
3457 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3458 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3459 burst_size, "rte_eth_tx_burst failed");
3461 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3462 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3463 burst_size, "rte_eth_tx_burst failed");
3466 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3467 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3468 "(%d) port_stats.opackets (%d) not as expected (%d).",
3469 test_params->bonded_port_id, (int)port_stats.opackets,
3470 burst_size + burst_size);
3472 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3473 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3474 "(%d) port_stats.opackets (%d) not as expected (%d).",
3475 test_params->slave_port_ids[0], (int)port_stats.opackets,
3478 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3479 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3480 "(%d) port_stats.opackets (%d) not as expected (%d).",
3481 test_params->slave_port_ids[2], (int)port_stats.opackets,
3484 /* verify that all packets get send on primary slave when no other slaves
3486 virtual_ethdev_simulate_link_status_interrupt(
3487 test_params->slave_port_ids[2], 0);
3489 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3490 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3491 "Number of active slaves (%d) is not as expected (%d).",
3494 TEST_ASSERT_EQUAL(generate_test_burst(
3495 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3496 "generate_test_burst failed");
3498 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3499 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3500 burst_size, "rte_eth_tx_burst failed");
3502 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3503 TEST_ASSERT_EQUAL(port_stats.opackets,
3504 (uint64_t)(burst_size + burst_size + burst_size),
3505 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3506 test_params->bonded_port_id, (int)port_stats.opackets,
3507 burst_size + burst_size + burst_size);
3509 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3510 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3511 "(%d) port_stats.opackets (%d) not as expected (%d).",
3512 test_params->slave_port_ids[0], (int)port_stats.opackets,
3513 burst_size + burst_size);
3515 virtual_ethdev_simulate_link_status_interrupt(
3516 test_params->slave_port_ids[0], 0);
3517 virtual_ethdev_simulate_link_status_interrupt(
3518 test_params->slave_port_ids[1], 1);
3519 virtual_ethdev_simulate_link_status_interrupt(
3520 test_params->slave_port_ids[2], 1);
3521 virtual_ethdev_simulate_link_status_interrupt(
3522 test_params->slave_port_ids[3], 1);
3524 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3525 TEST_ASSERT_EQUAL(generate_test_burst(
3526 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3527 "Failed to generate packet burst");
3529 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3530 &pkt_burst[i][0], burst_size);
3533 /* Verify that pkts are not received on slaves with link status down */
3535 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3538 /* Verify bonded device rx count */
3539 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3540 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3541 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3542 test_params->bonded_port_id, (int)port_stats.ipackets,
3545 /* Clean up and remove slaves from bonded device */
3546 return remove_slaves_and_stop_bonded_device();
3550 test_broadcast_tx_burst(void)
3552 int i, pktlen, burst_size;
3553 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3555 struct rte_eth_stats port_stats;
3557 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3558 BONDING_MODE_BROADCAST, 0, 2, 1),
3559 "Failed to initialise bonded device");
3561 initialize_eth_header(test_params->pkt_eth_hdr,
3562 (struct rte_ether_addr *)src_mac,
3563 (struct rte_ether_addr *)dst_mac_0,
3564 RTE_ETHER_TYPE_IPV4, 0, 0);
3566 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3568 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3569 dst_addr_0, pktlen);
3571 burst_size = 20 * test_params->bonded_slave_count;
3573 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3574 "Burst size specified is greater than supported.");
3576 /* Generate a burst of packets to transmit */
3577 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3578 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3579 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3580 1), burst_size, "Failed to generate packet burst");
3582 /* Send burst on bonded port */
3583 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3584 pkts_burst, burst_size), burst_size,
3585 "Bonded Port (%d) rx burst failed, packets transmitted value "
3586 "not as expected (%d)",
3587 test_params->bonded_port_id, burst_size);
3589 /* Verify bonded port tx stats */
3590 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3591 TEST_ASSERT_EQUAL(port_stats.opackets,
3592 (uint64_t)burst_size * test_params->bonded_slave_count,
3593 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3594 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3597 /* Verify slave ports tx stats */
3598 for (i = 0; i < test_params->bonded_slave_count; i++) {
3599 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3600 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3601 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3602 test_params->bonded_port_id,
3603 (unsigned int)port_stats.opackets, burst_size);
3606 /* Put all slaves down and try and transmit */
3607 for (i = 0; i < test_params->bonded_slave_count; i++) {
3609 virtual_ethdev_simulate_link_status_interrupt(
3610 test_params->slave_port_ids[i], 0);
3613 /* Send burst on bonded port */
3614 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3615 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3616 "transmitted an unexpected number of packets");
3618 /* Clean up and remove slaves from bonded device */
3619 return remove_slaves_and_stop_bonded_device();
3623 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3624 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3625 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3626 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3629 test_broadcast_tx_burst_slave_tx_fail(void)
3631 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3632 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3634 struct rte_eth_stats port_stats;
3638 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3639 BONDING_MODE_BROADCAST, 0,
3640 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3641 "Failed to initialise bonded device");
3643 /* Generate test bursts for transmission */
3644 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3645 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3646 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3647 "Failed to generate test packet burst");
3649 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3650 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3651 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3654 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3655 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3656 virtual_ethdev_tx_burst_fn_set_success(
3657 test_params->slave_port_ids[0],
3659 virtual_ethdev_tx_burst_fn_set_success(
3660 test_params->slave_port_ids[1],
3662 virtual_ethdev_tx_burst_fn_set_success(
3663 test_params->slave_port_ids[2],
3666 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3667 test_params->slave_port_ids[0],
3668 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3670 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3671 test_params->slave_port_ids[1],
3672 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3674 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3675 test_params->slave_port_ids[2],
3676 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3678 /* Transmit burst */
3679 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3680 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3682 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3683 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3684 "Transmitted (%d) packets, expected to transmit (%d) packets",
3685 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3686 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3688 /* Verify that failed packet are expected failed packets */
3689 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3690 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3691 "expected mbuf (%d) pointer %p not expected pointer %p",
3692 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3695 /* Verify slave ports tx stats */
3697 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3699 TEST_ASSERT_EQUAL(port_stats.opackets,
3700 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3701 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3702 "Port (%d) opackets value (%u) not as expected (%d)",
3703 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3704 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3705 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3708 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3710 TEST_ASSERT_EQUAL(port_stats.opackets,
3711 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3712 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3713 "Port (%d) opackets value (%u) not as expected (%d)",
3714 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3715 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3716 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3718 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3720 TEST_ASSERT_EQUAL(port_stats.opackets,
3721 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3722 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3723 "Port (%d) opackets value (%u) not as expected (%d)",
3724 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3725 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3726 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3729 /* Verify that all mbufs who transmission failed have a ref value of one */
3730 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3731 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3732 "mbufs refcnts not as expected");
3734 free_mbufs(&pkts_burst[tx_count],
3735 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3737 /* Clean up and remove slaves from bonded device */
3738 return remove_slaves_and_stop_bonded_device();
3741 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3744 test_broadcast_rx_burst(void)
3746 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3748 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3749 struct rte_eth_stats port_stats;
3751 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3754 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3756 /* Initialize bonded device with 4 slaves in round robin mode */
3757 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3758 BONDING_MODE_BROADCAST, 0, 3, 1),
3759 "Failed to initialise bonded device");
3761 /* Generate test bursts of packets to transmit */
3762 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3763 TEST_ASSERT_EQUAL(generate_test_burst(
3764 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3765 burst_size[i], "failed to generate packet burst");
3768 /* Add rx data to slave 0 */
3769 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3770 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3771 &gen_pkt_burst[i][0], burst_size[i]);
3775 /* Call rx burst on bonded device */
3776 /* Send burst on bonded port */
3777 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3778 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3779 burst_size[0] + burst_size[1] + burst_size[2],
3782 /* Verify bonded device rx count */
3783 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3784 TEST_ASSERT_EQUAL(port_stats.ipackets,
3785 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3786 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3787 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3788 burst_size[0] + burst_size[1] + burst_size[2]);
3791 /* Verify bonded slave devices rx counts */
3792 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3793 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3794 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3795 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3798 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3799 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3800 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3801 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3804 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3805 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3806 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3807 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3810 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3811 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3812 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3813 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3816 /* free mbufs allocate for rx testing */
3817 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3818 for (j = 0; j < MAX_PKT_BURST; j++) {
3819 if (gen_pkt_burst[i][j] != NULL) {
3820 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3821 gen_pkt_burst[i][j] = NULL;
3826 /* Clean up and remove slaves from bonded device */
3827 return remove_slaves_and_stop_bonded_device();
3831 test_broadcast_verify_promiscuous_enable_disable(void)
3836 /* Initialize bonded device with 4 slaves in round robin mode */
3837 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3838 BONDING_MODE_BROADCAST, 0, 4, 1),
3839 "Failed to initialise bonded device");
3841 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
3842 TEST_ASSERT_SUCCESS(ret,
3843 "Failed to enable promiscuous mode for port %d: %s",
3844 test_params->bonded_port_id, rte_strerror(-ret));
3847 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3848 "Port (%d) promiscuous mode not enabled",
3849 test_params->bonded_port_id);
3851 for (i = 0; i < test_params->bonded_slave_count; i++) {
3852 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3853 test_params->slave_port_ids[i]), 1,
3854 "Port (%d) promiscuous mode not enabled",
3855 test_params->slave_port_ids[i]);
3858 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
3859 TEST_ASSERT_SUCCESS(ret,
3860 "Failed to disable promiscuous mode for port %d: %s",
3861 test_params->bonded_port_id, rte_strerror(-ret));
3863 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3864 "Port (%d) promiscuous mode not disabled",
3865 test_params->bonded_port_id);
3867 for (i = 0; i < test_params->bonded_slave_count; i++) {
3868 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3869 test_params->slave_port_ids[i]), 0,
3870 "Port (%d) promiscuous mode not disabled",
3871 test_params->slave_port_ids[i]);
3874 /* Clean up and remove slaves from bonded device */
3875 return remove_slaves_and_stop_bonded_device();
3879 test_broadcast_verify_mac_assignment(void)
3881 struct rte_ether_addr read_mac_addr;
3882 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
3886 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
3887 "Failed to get mac address (port %d)",
3888 test_params->slave_port_ids[0]);
3889 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1),
3890 "Failed to get mac address (port %d)",
3891 test_params->slave_port_ids[2]);
3893 /* Initialize bonded device with 4 slaves in round robin mode */
3894 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3895 BONDING_MODE_BROADCAST, 0, 4, 1),
3896 "Failed to initialise bonded device");
3898 /* Verify that all MACs are the same as first slave added to bonded
3900 for (i = 0; i < test_params->bonded_slave_count; i++) {
3901 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3902 "Failed to get mac address (port %d)",
3903 test_params->slave_port_ids[i]);
3904 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3905 sizeof(read_mac_addr)),
3906 "slave port (%d) mac address not set to that of primary port",
3907 test_params->slave_port_ids[i]);
3910 /* change primary and verify that MAC addresses haven't changed */
3911 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3912 test_params->slave_port_ids[2]),
3913 "Failed to set bonded port (%d) primary port to (%d)",
3914 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3916 for (i = 0; i < test_params->bonded_slave_count; i++) {
3917 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3918 "Failed to get mac address (port %d)",
3919 test_params->slave_port_ids[i]);
3920 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3921 sizeof(read_mac_addr)),
3922 "slave port (%d) mac address has changed to that of primary "
3923 "port without stop/start toggle of bonded device",
3924 test_params->slave_port_ids[i]);
3927 /* stop / start bonded device and verify that primary MAC address is
3928 * propagated to bonded device and slaves */
3930 rte_eth_dev_stop(test_params->bonded_port_id);
3932 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3933 "Failed to start bonded device");
3935 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3936 "Failed to get mac address (port %d)",
3937 test_params->bonded_port_id);
3938 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3939 sizeof(read_mac_addr)),
3940 "bonded port (%d) mac address not set to that of new primary port",
3941 test_params->slave_port_ids[i]);
3943 for (i = 0; i < test_params->bonded_slave_count; i++) {
3944 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3945 "Failed to get mac address (port %d)",
3946 test_params->slave_port_ids[i]);
3947 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3948 sizeof(read_mac_addr)),
3949 "slave port (%d) mac address not set to that of new primary "
3950 "port", test_params->slave_port_ids[i]);
3953 /* Set explicit MAC address */
3954 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3955 test_params->bonded_port_id,
3956 (struct rte_ether_addr *)bonded_mac),
3957 "Failed to set MAC address");
3959 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
3960 "Failed to get mac address (port %d)",
3961 test_params->bonded_port_id);
3962 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3963 sizeof(read_mac_addr)),
3964 "bonded port (%d) mac address not set to that of new primary port",
3965 test_params->slave_port_ids[i]);
3968 for (i = 0; i < test_params->bonded_slave_count; i++) {
3969 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr),
3970 "Failed to get mac address (port %d)",
3971 test_params->slave_port_ids[i]);
3972 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3973 sizeof(read_mac_addr)),
3974 "slave port (%d) mac address not set to that of new primary "
3975 "port", test_params->slave_port_ids[i]);
3978 /* Clean up and remove slaves from bonded device */
3979 return remove_slaves_and_stop_bonded_device();
3982 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3984 test_broadcast_verify_slave_link_status_change_behaviour(void)
3986 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3987 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3988 struct rte_eth_stats port_stats;
3990 uint16_t slaves[RTE_MAX_ETHPORTS];
3992 int i, burst_size, slave_count;
3994 memset(pkt_burst, 0, sizeof(pkt_burst));
3996 /* Initialize bonded device with 4 slaves in round robin mode */
3997 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3998 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3999 1), "Failed to initialise bonded device");
4001 /* Verify Current Slaves Count /Active Slave Count is */
4002 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4004 TEST_ASSERT_EQUAL(slave_count, 4,
4005 "Number of slaves (%d) is not as expected (%d).",
4008 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4009 slaves, RTE_MAX_ETHPORTS);
4010 TEST_ASSERT_EQUAL(slave_count, 4,
4011 "Number of active slaves (%d) is not as expected (%d).",
4014 /* Set 2 slaves link status to down */
4015 virtual_ethdev_simulate_link_status_interrupt(
4016 test_params->slave_port_ids[1], 0);
4017 virtual_ethdev_simulate_link_status_interrupt(
4018 test_params->slave_port_ids[3], 0);
4020 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4021 slaves, RTE_MAX_ETHPORTS);
4022 TEST_ASSERT_EQUAL(slave_count, 2,
4023 "Number of active slaves (%d) is not as expected (%d).",
4026 for (i = 0; i < test_params->bonded_slave_count; i++)
4027 rte_eth_stats_reset(test_params->slave_port_ids[i]);
4029 /* Verify that pkts are not sent on slaves with link status down */
4032 TEST_ASSERT_EQUAL(generate_test_burst(
4033 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
4034 "generate_test_burst failed");
4036 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
4037 &pkt_burst[0][0], burst_size), burst_size,
4038 "rte_eth_tx_burst failed\n");
4040 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4041 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
4042 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
4043 test_params->bonded_port_id, (int)port_stats.opackets,
4044 burst_size * slave_count);
4046 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4047 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4048 "(%d) port_stats.opackets not as expected",
4049 test_params->slave_port_ids[0]);
4051 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4052 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4053 "(%d) port_stats.opackets not as expected",
4054 test_params->slave_port_ids[1]);
4056 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4057 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
4058 "(%d) port_stats.opackets not as expected",
4059 test_params->slave_port_ids[2]);
4062 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4063 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
4064 "(%d) port_stats.opackets not as expected",
4065 test_params->slave_port_ids[3]);
4068 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4069 TEST_ASSERT_EQUAL(generate_test_burst(
4070 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
4071 burst_size, "failed to generate packet burst");
4073 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4074 &pkt_burst[i][0], burst_size);
4077 /* Verify that pkts are not received on slaves with link status down */
4078 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
4079 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
4080 burst_size + burst_size, "rte_eth_rx_burst failed");
4083 /* Verify bonded device rx count */
4084 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4085 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
4086 "(%d) port_stats.ipackets not as expected\n",
4087 test_params->bonded_port_id);
4089 /* Clean up and remove slaves from bonded device */
4090 return remove_slaves_and_stop_bonded_device();
4094 test_reconfigure_bonded_device(void)
4096 test_params->nb_rx_q = 4;
4097 test_params->nb_tx_q = 4;
4099 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4100 "failed to reconfigure bonded device");
4102 test_params->nb_rx_q = 2;
4103 test_params->nb_tx_q = 2;
4105 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4106 "failed to reconfigure bonded device with less rx/tx queues");
4113 test_close_bonded_device(void)
4115 rte_eth_dev_close(test_params->bonded_port_id);
4120 testsuite_teardown(void)
4122 free(test_params->pkt_eth_hdr);
4123 test_params->pkt_eth_hdr = NULL;
4125 /* Clean up and remove slaves from bonded device */
4126 remove_slaves_and_stop_bonded_device();
4130 free_virtualpmd_tx_queue(void)
4132 int i, slave_port, to_free_cnt;
4133 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4135 /* Free tx queue of virtual pmd */
4136 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4138 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4139 test_params->slave_port_ids[slave_port],
4140 pkts_to_free, MAX_PKT_BURST);
4141 for (i = 0; i < to_free_cnt; i++)
4142 rte_pktmbuf_free(pkts_to_free[i]);
4147 test_tlb_tx_burst(void)
4149 int i, burst_size, nb_tx;
4150 uint64_t nb_tx2 = 0;
4151 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4152 struct rte_eth_stats port_stats[32];
4153 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4156 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4157 (BONDING_MODE_TLB, 1, 3, 1),
4158 "Failed to initialise bonded device");
4160 burst_size = 20 * test_params->bonded_slave_count;
4162 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4163 "Burst size specified is greater than supported.\n");
4166 /* Generate bursts of packets */
4167 for (i = 0; i < 400000; i++) {
4168 /*test two types of mac src own(bonding) and others */
4170 initialize_eth_header(test_params->pkt_eth_hdr,
4171 (struct rte_ether_addr *)src_mac,
4172 (struct rte_ether_addr *)dst_mac_0,
4173 RTE_ETHER_TYPE_IPV4, 0, 0);
4175 initialize_eth_header(test_params->pkt_eth_hdr,
4176 (struct rte_ether_addr *)test_params->default_slave_mac,
4177 (struct rte_ether_addr *)dst_mac_0,
4178 RTE_ETHER_TYPE_IPV4, 0, 0);
4180 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4182 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4183 dst_addr_0, pktlen);
4184 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4185 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4186 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4187 /* Send burst on bonded port */
4188 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4192 free_virtualpmd_tx_queue();
4194 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4195 "number of packet not equal burst size");
4201 /* Verify bonded port tx stats */
4202 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4204 all_bond_opackets = port_stats[0].opackets;
4205 all_bond_obytes = port_stats[0].obytes;
4207 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4208 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4209 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4213 /* Verify slave ports tx stats */
4214 for (i = 0; i < test_params->bonded_slave_count; i++) {
4215 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4216 sum_ports_opackets += port_stats[i].opackets;
4219 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4220 "Total packets sent by slaves is not equal to packets sent by bond interface");
4222 /* checking if distribution of packets is balanced over slaves */
4223 for (i = 0; i < test_params->bonded_slave_count; i++) {
4224 TEST_ASSERT(port_stats[i].obytes > 0 &&
4225 port_stats[i].obytes < all_bond_obytes,
4226 "Packets are not balanced over slaves");
4229 /* Put all slaves down and try and transmit */
4230 for (i = 0; i < test_params->bonded_slave_count; i++) {
4231 virtual_ethdev_simulate_link_status_interrupt(
4232 test_params->slave_port_ids[i], 0);
4235 /* Send burst on bonded port */
4236 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4238 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4240 /* Clean ugit checkout masterp and remove slaves from bonded device */
4241 return remove_slaves_and_stop_bonded_device();
4244 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4247 test_tlb_rx_burst(void)
4249 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4250 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4252 struct rte_eth_stats port_stats;
4256 uint16_t i, j, nb_rx, burst_size = 17;
4258 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4259 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4261 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4262 "Failed to initialize bonded device");
4265 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4266 TEST_ASSERT(primary_port >= 0,
4267 "failed to get primary slave for bonded port (%d)",
4268 test_params->bonded_port_id);
4270 for (i = 0; i < test_params->bonded_slave_count; i++) {
4271 /* Generate test bursts of packets to transmit */
4272 TEST_ASSERT_EQUAL(generate_test_burst(
4273 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4274 "burst generation failed");
4276 /* Add rx data to slave */
4277 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4278 &gen_pkt_burst[0], burst_size);
4280 /* Call rx burst on bonded device */
4281 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4282 &rx_pkt_burst[0], MAX_PKT_BURST);
4284 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4286 if (test_params->slave_port_ids[i] == primary_port) {
4287 /* Verify bonded device rx count */
4288 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4289 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4290 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4291 test_params->bonded_port_id,
4292 (unsigned int)port_stats.ipackets, burst_size);
4294 /* Verify bonded slave devices rx count */
4295 for (j = 0; j < test_params->bonded_slave_count; j++) {
4296 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4298 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4299 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4300 test_params->slave_port_ids[i],
4301 (unsigned int)port_stats.ipackets, burst_size);
4303 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
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, 0);
4310 for (j = 0; j < test_params->bonded_slave_count; j++) {
4311 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4312 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4313 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4314 test_params->slave_port_ids[i],
4315 (unsigned int)port_stats.ipackets, 0);
4320 for (i = 0; i < burst_size; i++)
4321 rte_pktmbuf_free(rx_pkt_burst[i]);
4323 /* reset bonded device stats */
4324 rte_eth_stats_reset(test_params->bonded_port_id);
4327 /* Clean up and remove slaves from bonded device */
4328 return remove_slaves_and_stop_bonded_device();
4332 test_tlb_verify_promiscuous_enable_disable(void)
4334 int i, primary_port, promiscuous_en;
4337 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4338 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4339 BONDING_MODE_TLB, 0, 4, 1),
4340 "Failed to initialize bonded device");
4342 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4343 TEST_ASSERT(primary_port >= 0,
4344 "failed to get primary slave for bonded port (%d)",
4345 test_params->bonded_port_id);
4347 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id);
4348 TEST_ASSERT_SUCCESS(ret,
4349 "Failed to enable promiscuous mode for port %d: %s",
4350 test_params->bonded_port_id, rte_strerror(-ret));
4352 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4353 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4354 "Port (%d) promiscuous mode not enabled\n",
4355 test_params->bonded_port_id);
4356 for (i = 0; i < test_params->bonded_slave_count; i++) {
4357 promiscuous_en = rte_eth_promiscuous_get(
4358 test_params->slave_port_ids[i]);
4359 if (primary_port == test_params->slave_port_ids[i]) {
4360 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4361 "Port (%d) promiscuous mode not enabled\n",
4362 test_params->bonded_port_id);
4364 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4365 "Port (%d) promiscuous mode enabled\n",
4366 test_params->bonded_port_id);
4371 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id);
4372 TEST_ASSERT_SUCCESS(ret,
4373 "Failed to disable promiscuous mode for port %d: %s\n",
4374 test_params->bonded_port_id, rte_strerror(-ret));
4376 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4377 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4378 "Port (%d) promiscuous mode not disabled\n",
4379 test_params->bonded_port_id);
4381 for (i = 0; i < test_params->bonded_slave_count; i++) {
4382 promiscuous_en = rte_eth_promiscuous_get(
4383 test_params->slave_port_ids[i]);
4384 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4385 "slave port (%d) promiscuous mode not disabled\n",
4386 test_params->slave_port_ids[i]);
4389 /* Clean up and remove slaves from bonded device */
4390 return remove_slaves_and_stop_bonded_device();
4394 test_tlb_verify_mac_assignment(void)
4396 struct rte_ether_addr read_mac_addr;
4397 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1;
4399 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0),
4400 "Failed to get mac address (port %d)",
4401 test_params->slave_port_ids[0]);
4402 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1),
4403 "Failed to get mac address (port %d)",
4404 test_params->slave_port_ids[1]);
4406 /* Initialize bonded device with 2 slaves in active backup mode */
4407 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4408 BONDING_MODE_TLB, 0, 2, 1),
4409 "Failed to initialize bonded device");
4411 /* Verify that bonded MACs is that of first slave and that the other slave
4412 * MAC hasn't been changed */
4413 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4414 "Failed to get mac address (port %d)",
4415 test_params->bonded_port_id);
4416 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4417 sizeof(read_mac_addr)),
4418 "bonded port (%d) mac address not set to that of primary port",
4419 test_params->bonded_port_id);
4421 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4422 "Failed to get mac address (port %d)",
4423 test_params->slave_port_ids[0]);
4424 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4425 sizeof(read_mac_addr)),
4426 "slave port (%d) mac address not set to that of primary port",
4427 test_params->slave_port_ids[0]);
4429 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4430 "Failed to get mac address (port %d)",
4431 test_params->slave_port_ids[1]);
4432 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4433 sizeof(read_mac_addr)),
4434 "slave port (%d) mac address not as expected",
4435 test_params->slave_port_ids[1]);
4437 /* change primary and verify that MAC addresses haven't changed */
4438 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4439 test_params->slave_port_ids[1]), 0,
4440 "Failed to set bonded port (%d) primary port to (%d)",
4441 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4443 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4444 "Failed to get mac address (port %d)",
4445 test_params->bonded_port_id);
4446 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4447 sizeof(read_mac_addr)),
4448 "bonded port (%d) mac address not set to that of primary port",
4449 test_params->bonded_port_id);
4451 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4452 "Failed to get mac address (port %d)",
4453 test_params->slave_port_ids[0]);
4454 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4455 sizeof(read_mac_addr)),
4456 "slave port (%d) mac address not set to that of primary port",
4457 test_params->slave_port_ids[0]);
4459 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4460 "Failed to get mac address (port %d)",
4461 test_params->slave_port_ids[1]);
4462 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4463 sizeof(read_mac_addr)),
4464 "slave port (%d) mac address not as expected",
4465 test_params->slave_port_ids[1]);
4467 /* stop / start bonded device and verify that primary MAC address is
4468 * propagated to bonded device and slaves */
4470 rte_eth_dev_stop(test_params->bonded_port_id);
4472 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4473 "Failed to start device");
4475 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4476 "Failed to get mac address (port %d)",
4477 test_params->bonded_port_id);
4478 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4479 sizeof(read_mac_addr)),
4480 "bonded port (%d) mac address not set to that of primary port",
4481 test_params->bonded_port_id);
4483 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4484 "Failed to get mac address (port %d)",
4485 test_params->slave_port_ids[0]);
4486 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4487 sizeof(read_mac_addr)),
4488 "slave port (%d) mac address not as expected",
4489 test_params->slave_port_ids[0]);
4491 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4492 "Failed to get mac address (port %d)",
4493 test_params->slave_port_ids[1]);
4494 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4495 sizeof(read_mac_addr)),
4496 "slave port (%d) mac address not set to that of primary port",
4497 test_params->slave_port_ids[1]);
4500 /* Set explicit MAC address */
4501 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4502 test_params->bonded_port_id,
4503 (struct rte_ether_addr *)bonded_mac),
4504 "failed to set MAC address");
4506 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr),
4507 "Failed to get mac address (port %d)",
4508 test_params->bonded_port_id);
4509 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4510 sizeof(read_mac_addr)),
4511 "bonded port (%d) mac address not set to that of bonded port",
4512 test_params->bonded_port_id);
4514 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr),
4515 "Failed to get mac address (port %d)",
4516 test_params->slave_port_ids[0]);
4517 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4518 sizeof(read_mac_addr)),
4519 "slave port (%d) mac address not as expected",
4520 test_params->slave_port_ids[0]);
4522 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr),
4523 "Failed to get mac address (port %d)",
4524 test_params->slave_port_ids[1]);
4525 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4526 sizeof(read_mac_addr)),
4527 "slave port (%d) mac address not set to that of bonded port",
4528 test_params->slave_port_ids[1]);
4530 /* Clean up and remove slaves from bonded device */
4531 return remove_slaves_and_stop_bonded_device();
4535 test_tlb_verify_slave_link_status_change_failover(void)
4537 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4538 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4539 struct rte_eth_stats port_stats;
4541 uint16_t slaves[RTE_MAX_ETHPORTS];
4543 int i, burst_size, slave_count, primary_port;
4547 memset(pkt_burst, 0, sizeof(pkt_burst));
4551 /* Initialize bonded device with 4 slaves in round robin mode */
4552 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4553 BONDING_MODE_TLB, 0,
4554 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4555 "Failed to initialize bonded device with slaves");
4557 /* Verify Current Slaves Count /Active Slave Count is */
4558 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4560 TEST_ASSERT_EQUAL(slave_count, 4,
4561 "Number of slaves (%d) is not as expected (%d).\n",
4564 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4565 slaves, RTE_MAX_ETHPORTS);
4566 TEST_ASSERT_EQUAL(slave_count, (int)4,
4567 "Number of slaves (%d) is not as expected (%d).\n",
4570 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4571 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4572 "Primary port not as expected");
4574 /* Bring 2 slaves down and verify active slave count */
4575 virtual_ethdev_simulate_link_status_interrupt(
4576 test_params->slave_port_ids[1], 0);
4577 virtual_ethdev_simulate_link_status_interrupt(
4578 test_params->slave_port_ids[3], 0);
4580 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4581 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4582 "Number of active slaves (%d) is not as expected (%d).",
4585 virtual_ethdev_simulate_link_status_interrupt(
4586 test_params->slave_port_ids[1], 1);
4587 virtual_ethdev_simulate_link_status_interrupt(
4588 test_params->slave_port_ids[3], 1);
4591 /* Bring primary port down, verify that active slave count is 3 and primary
4593 virtual_ethdev_simulate_link_status_interrupt(
4594 test_params->slave_port_ids[0], 0);
4596 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4597 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4598 "Number of active slaves (%d) is not as expected (%d).",
4601 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4602 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4603 "Primary port not as expected");
4604 rte_delay_us(500000);
4605 /* Verify that pkts are sent on new primary slave */
4606 for (i = 0; i < 4; i++) {
4607 TEST_ASSERT_EQUAL(generate_test_burst(
4608 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4609 "generate_test_burst failed\n");
4610 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4611 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4612 "rte_eth_tx_burst failed\n");
4613 rte_delay_us(11000);
4616 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4617 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4618 "(%d) port_stats.opackets not as expected\n",
4619 test_params->slave_port_ids[0]);
4621 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4622 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4623 "(%d) port_stats.opackets not as expected\n",
4624 test_params->slave_port_ids[1]);
4626 rte_eth_stats_get(test_params->slave_port_ids[2], &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[2]);
4631 rte_eth_stats_get(test_params->slave_port_ids[3], &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[3]);
4637 /* Generate packet burst for testing */
4639 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4640 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4644 virtual_ethdev_add_mbufs_to_rx_queue(
4645 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4648 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4649 MAX_PKT_BURST) != burst_size) {
4650 printf("rte_eth_rx_burst\n");
4655 /* Verify bonded device rx count */
4656 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4657 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4658 "(%d) port_stats.ipackets not as expected\n",
4659 test_params->bonded_port_id);
4661 /* Clean up and remove slaves from bonded device */
4662 return remove_slaves_and_stop_bonded_device();
4665 #define TEST_ALB_SLAVE_COUNT 2
4667 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4668 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4669 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4670 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4672 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4673 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4674 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4675 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4676 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4679 test_alb_change_mac_in_reply_sent(void)
4681 struct rte_mbuf *pkt;
4682 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4684 struct rte_ether_hdr *eth_pkt;
4685 struct rte_arp_hdr *arp_pkt;
4687 int slave_idx, nb_pkts, pkt_idx;
4690 struct rte_ether_addr bond_mac, client_mac;
4691 struct rte_ether_addr *slave_mac1, *slave_mac2;
4693 TEST_ASSERT_SUCCESS(
4694 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4695 0, TEST_ALB_SLAVE_COUNT, 1),
4696 "Failed to initialize_bonded_device_with_slaves.");
4698 /* Flush tx queue */
4699 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4700 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4702 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4703 test_params->slave_port_ids[slave_idx], pkts_sent,
4707 rte_ether_addr_copy(
4708 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4712 * Generating four packets with different mac and ip addresses and sending
4713 * them through the bonding port.
4715 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4716 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4717 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4718 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4719 RTE_ETHER_TYPE_ARP, 0, 0);
4720 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4721 sizeof(struct rte_ether_hdr));
4722 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4724 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4726 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4727 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4728 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4729 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4730 RTE_ETHER_TYPE_ARP, 0, 0);
4731 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4732 sizeof(struct rte_ether_hdr));
4733 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4735 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4737 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4738 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4739 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4740 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4741 RTE_ETHER_TYPE_ARP, 0, 0);
4742 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4743 sizeof(struct rte_ether_hdr));
4744 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4746 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4748 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4749 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4750 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4751 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4752 RTE_ETHER_TYPE_ARP, 0, 0);
4753 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4754 sizeof(struct rte_ether_hdr));
4755 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4757 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4760 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4762 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4765 * Checking if packets are properly distributed on bonding ports. Packets
4766 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4768 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4769 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4770 test_params->slave_port_ids[slave_idx], pkts_sent,
4773 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4774 eth_pkt = rte_pktmbuf_mtod(
4775 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4776 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4777 sizeof(struct rte_ether_hdr));
4779 if (slave_idx%2 == 0) {
4780 if (!rte_is_same_ether_addr(slave_mac1,
4781 &arp_pkt->arp_data.arp_sha)) {
4786 if (!rte_is_same_ether_addr(slave_mac2,
4787 &arp_pkt->arp_data.arp_sha)) {
4796 retval += remove_slaves_and_stop_bonded_device();
4801 test_alb_reply_from_client(void)
4803 struct rte_ether_hdr *eth_pkt;
4804 struct rte_arp_hdr *arp_pkt;
4806 struct rte_mbuf *pkt;
4807 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4809 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4812 struct rte_ether_addr bond_mac, client_mac;
4813 struct rte_ether_addr *slave_mac1, *slave_mac2;
4815 TEST_ASSERT_SUCCESS(
4816 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4817 0, TEST_ALB_SLAVE_COUNT, 1),
4818 "Failed to initialize_bonded_device_with_slaves.");
4820 /* Flush tx queue */
4821 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4822 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4823 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4824 test_params->slave_port_ids[slave_idx], pkts_sent,
4828 rte_ether_addr_copy(
4829 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4833 * Generating four packets with different mac and ip addresses and placing
4834 * them in the rx queue to be received by the bonding driver on rx_burst.
4836 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4837 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4838 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4839 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4840 RTE_ETHER_TYPE_ARP, 0, 0);
4841 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4842 sizeof(struct rte_ether_hdr));
4843 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4845 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4848 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4849 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN);
4850 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4851 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4852 RTE_ETHER_TYPE_ARP, 0, 0);
4853 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4854 sizeof(struct rte_ether_hdr));
4855 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4857 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4860 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4861 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN);
4862 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4863 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4864 RTE_ETHER_TYPE_ARP, 0, 0);
4865 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4866 sizeof(struct rte_ether_hdr));
4867 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4869 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4872 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4873 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN);
4874 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4875 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4876 RTE_ETHER_TYPE_ARP, 0, 0);
4877 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4878 sizeof(struct rte_ether_hdr));
4879 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4881 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4885 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4886 * packets to every client in alb table.
4888 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4889 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4891 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4892 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4895 * Checking if update ARP packets were properly send on slave ports.
4897 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4898 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4899 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4900 nb_pkts_sum += nb_pkts;
4902 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4903 eth_pkt = rte_pktmbuf_mtod(
4904 pkts_sent[pkt_idx], struct rte_ether_hdr *);
4905 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt +
4906 sizeof(struct rte_ether_hdr));
4908 if (slave_idx%2 == 0) {
4909 if (!rte_is_same_ether_addr(slave_mac1,
4910 &arp_pkt->arp_data.arp_sha)) {
4915 if (!rte_is_same_ether_addr(slave_mac2,
4916 &arp_pkt->arp_data.arp_sha)) {
4924 /* Check if proper number of packets was send */
4925 if (nb_pkts_sum < 4) {
4931 retval += remove_slaves_and_stop_bonded_device();
4936 test_alb_receive_vlan_reply(void)
4938 struct rte_ether_hdr *eth_pkt;
4939 struct rte_vlan_hdr *vlan_pkt;
4940 struct rte_arp_hdr *arp_pkt;
4942 struct rte_mbuf *pkt;
4943 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4945 int slave_idx, nb_pkts, pkt_idx;
4948 struct rte_ether_addr bond_mac, client_mac;
4950 TEST_ASSERT_SUCCESS(
4951 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4952 0, TEST_ALB_SLAVE_COUNT, 1),
4953 "Failed to initialize_bonded_device_with_slaves.");
4955 /* Flush tx queue */
4956 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4957 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4958 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4959 test_params->slave_port_ids[slave_idx], pkts_sent,
4963 rte_ether_addr_copy(
4964 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4968 * Generating packet with double VLAN header and placing it in the rx queue.
4970 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4971 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN);
4972 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
4973 initialize_eth_header(eth_pkt, &bond_mac, &client_mac,
4974 RTE_ETHER_TYPE_VLAN, 0, 0);
4975 vlan_pkt = (struct rte_vlan_hdr *)((char *)(eth_pkt + 1));
4976 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4977 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
4978 vlan_pkt = vlan_pkt+1;
4979 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4980 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
4981 arp_pkt = (struct rte_arp_hdr *)((char *)(vlan_pkt + 1));
4982 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4984 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4987 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4988 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4991 * Checking if VLAN headers in generated ARP Update packet are correct.
4993 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4994 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4995 test_params->slave_port_ids[slave_idx], pkts_sent,
4998 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4999 eth_pkt = rte_pktmbuf_mtod(
5000 pkts_sent[pkt_idx], struct rte_ether_hdr *);
5001 vlan_pkt = (struct rte_vlan_hdr *)(
5002 (char *)(eth_pkt + 1));
5003 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
5007 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5008 RTE_ETHER_TYPE_VLAN)) {
5012 vlan_pkt = vlan_pkt+1;
5013 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
5017 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(
5018 RTE_ETHER_TYPE_ARP)) {
5026 retval += remove_slaves_and_stop_bonded_device();
5031 test_alb_ipv4_tx(void)
5033 int burst_size, retval, pkts_send;
5034 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
5038 TEST_ASSERT_SUCCESS(
5039 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
5040 0, TEST_ALB_SLAVE_COUNT, 1),
5041 "Failed to initialize_bonded_device_with_slaves.");
5045 /* Generate test bursts of packets to transmit */
5046 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
5052 * Checking if ipv4 traffic is transmitted via TLB policy.
5054 pkts_send = rte_eth_tx_burst(
5055 test_params->bonded_port_id, 0, pkt_burst, burst_size);
5056 if (pkts_send != burst_size) {
5062 retval += remove_slaves_and_stop_bonded_device();
5066 static struct unit_test_suite link_bonding_test_suite = {
5067 .suite_name = "Link Bonding Unit Test Suite",
5068 .setup = test_setup,
5069 .teardown = testsuite_teardown,
5070 .unit_test_cases = {
5071 TEST_CASE(test_create_bonded_device),
5072 TEST_CASE(test_create_bonded_device_with_invalid_params),
5073 TEST_CASE(test_add_slave_to_bonded_device),
5074 TEST_CASE(test_add_slave_to_invalid_bonded_device),
5075 TEST_CASE(test_remove_slave_from_bonded_device),
5076 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
5077 TEST_CASE(test_get_slaves_from_bonded_device),
5078 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
5079 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
5080 TEST_CASE(test_start_bonded_device),
5081 TEST_CASE(test_stop_bonded_device),
5082 TEST_CASE(test_set_bonding_mode),
5083 TEST_CASE(test_set_primary_slave),
5084 TEST_CASE(test_set_explicit_bonded_mac),
5085 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
5086 TEST_CASE(test_status_interrupt),
5087 TEST_CASE(test_adding_slave_after_bonded_device_started),
5088 TEST_CASE(test_roundrobin_tx_burst),
5089 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
5090 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
5091 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
5092 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
5093 TEST_CASE(test_roundrobin_verify_mac_assignment),
5094 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
5095 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
5096 TEST_CASE(test_activebackup_tx_burst),
5097 TEST_CASE(test_activebackup_rx_burst),
5098 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
5099 TEST_CASE(test_activebackup_verify_mac_assignment),
5100 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
5101 TEST_CASE(test_balance_xmit_policy_configuration),
5102 TEST_CASE(test_balance_l2_tx_burst),
5103 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
5104 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
5105 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
5106 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
5107 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
5108 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
5109 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
5110 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
5111 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
5112 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
5113 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
5114 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
5115 TEST_CASE(test_balance_rx_burst),
5116 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
5117 TEST_CASE(test_balance_verify_mac_assignment),
5118 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
5119 TEST_CASE(test_tlb_tx_burst),
5120 TEST_CASE(test_tlb_rx_burst),
5121 TEST_CASE(test_tlb_verify_mac_assignment),
5122 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
5123 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
5124 TEST_CASE(test_alb_change_mac_in_reply_sent),
5125 TEST_CASE(test_alb_reply_from_client),
5126 TEST_CASE(test_alb_receive_vlan_reply),
5127 TEST_CASE(test_alb_ipv4_tx),
5128 TEST_CASE(test_broadcast_tx_burst),
5129 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
5130 TEST_CASE(test_broadcast_rx_burst),
5131 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
5132 TEST_CASE(test_broadcast_verify_mac_assignment),
5133 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
5134 TEST_CASE(test_reconfigure_bonded_device),
5135 TEST_CASE(test_close_bonded_device),
5137 TEST_CASES_END() /**< NULL terminate unit test array */
5143 test_link_bonding(void)
5145 return unit_test_suite_runner(&link_bonding_test_suite);
5148 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);