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 ether_addr *default_slave_mac;
77 struct ether_addr *default_bonded_mac;
80 struct ether_hdr *pkt_eth_hdr;
81 struct ipv4_hdr *pkt_ipv4_hdr;
82 struct ipv6_hdr *pkt_ipv6_hdr;
83 struct udp_hdr *pkt_udp_hdr;
87 static struct ipv4_hdr pkt_ipv4_hdr;
88 static struct ipv6_hdr pkt_ipv6_hdr;
89 static struct 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 ether_addr *)slave_mac,
103 .default_bonded_mac = (struct 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 = ETHER_MAX_LEN,
140 .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
143 .mq_mode = ETH_MQ_TX_NONE,
148 static const struct rte_eth_rxconf rx_conf_default = {
150 .pthresh = RX_PTHRESH,
151 .hthresh = RX_HTHRESH,
152 .wthresh = RX_WTHRESH,
154 .rx_free_thresh = RX_FREE_THRESH,
158 static struct rte_eth_txconf tx_conf_default = {
160 .pthresh = TX_PTHRESH,
161 .hthresh = TX_HTHRESH,
162 .wthresh = TX_WTHRESH,
164 .tx_free_thresh = TX_FREE_THRESH,
165 .tx_rs_thresh = TX_RSBIT_THRESH,
168 static void free_virtualpmd_tx_queue(void);
173 configure_ethdev(uint16_t port_id, uint8_t start, uint8_t en_isr)
178 default_pmd_conf.intr_conf.lsc = 1;
180 default_pmd_conf.intr_conf.lsc = 0;
182 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
183 test_params->nb_tx_q, &default_pmd_conf),
184 "rte_eth_dev_configure for port %d failed", port_id);
186 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
187 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
188 rte_eth_dev_socket_id(port_id), &rx_conf_default,
189 test_params->mbuf_pool) ,
190 "rte_eth_rx_queue_setup for port %d failed", port_id);
192 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
193 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
194 rte_eth_dev_socket_id(port_id), &tx_conf_default),
195 "rte_eth_tx_queue_setup for port %d failed", port_id);
198 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
199 "rte_eth_dev_start for port %d failed", port_id);
204 static int 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 ether_addr *mac_addr = (struct 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 ether_hdr) +
219 sizeof(struct 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[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 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 ether_addr *)slave_mac;
399 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
400 test_params->bonded_slave_count-1;
403 test_params->slave_port_ids[test_params->bonded_slave_count-1],
405 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
406 "bonded port mac address not set to that of primary port\n");
409 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
411 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
414 test_params->bonded_slave_count--;
420 test_remove_slave_from_invalid_bonded_device(void)
422 /* Invalid port ID */
423 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
424 test_params->bonded_port_id + 5,
425 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
426 "Expected call to failed as invalid port specified.");
428 /* Non bonded device */
429 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
430 test_params->slave_port_ids[0],
431 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
432 "Expected call to failed as invalid port specified.");
437 static int bonded_id = 2;
440 test_add_already_bonded_slave_to_bonded_device(void)
442 int port_id, current_slave_count;
443 uint16_t slaves[RTE_MAX_ETHPORTS];
444 char pmd_name[RTE_ETH_NAME_MAX_LEN];
446 test_add_slave_to_bonded_device();
448 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
449 slaves, RTE_MAX_ETHPORTS);
450 TEST_ASSERT_EQUAL(current_slave_count, 1,
451 "Number of slaves (%d) is not that expected (%d).",
452 current_slave_count, 1);
454 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
456 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
458 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
460 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
461 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
463 "Added slave (%d) to bonded port (%d) unexpectedly.",
464 test_params->slave_port_ids[test_params->bonded_slave_count-1],
467 return test_remove_slave_from_bonded_device();
472 test_get_slaves_from_bonded_device(void)
474 int current_slave_count;
475 uint16_t slaves[RTE_MAX_ETHPORTS];
477 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
478 "Failed to add slave to bonded device");
480 /* Invalid port id */
481 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
483 TEST_ASSERT(current_slave_count < 0,
484 "Invalid port id unexpectedly succeeded");
486 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
487 slaves, RTE_MAX_ETHPORTS);
488 TEST_ASSERT(current_slave_count < 0,
489 "Invalid port id unexpectedly succeeded");
491 /* Invalid slaves pointer */
492 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
493 NULL, RTE_MAX_ETHPORTS);
494 TEST_ASSERT(current_slave_count < 0,
495 "Invalid slave array unexpectedly succeeded");
497 current_slave_count = rte_eth_bond_active_slaves_get(
498 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
499 TEST_ASSERT(current_slave_count < 0,
500 "Invalid slave array unexpectedly succeeded");
502 /* non bonded device*/
503 current_slave_count = rte_eth_bond_slaves_get(
504 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
505 TEST_ASSERT(current_slave_count < 0,
506 "Invalid port id unexpectedly succeeded");
508 current_slave_count = rte_eth_bond_active_slaves_get(
509 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
510 TEST_ASSERT(current_slave_count < 0,
511 "Invalid port id unexpectedly succeeded");
513 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
514 "Failed to remove slaves from bonded device");
521 test_add_remove_multiple_slaves_to_from_bonded_device(void)
525 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
526 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
527 "Failed to add slave to bonded device");
529 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
530 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
531 "Failed to remove slaves from bonded device");
537 enable_bonded_slaves(void)
541 for (i = 0; i < test_params->bonded_slave_count; i++) {
542 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
545 virtual_ethdev_simulate_link_status_interrupt(
546 test_params->slave_port_ids[i], 1);
551 test_start_bonded_device(void)
553 struct rte_eth_link link_status;
555 int current_slave_count, current_bonding_mode, primary_port;
556 uint16_t slaves[RTE_MAX_ETHPORTS];
558 /* Add slave to bonded device*/
559 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
560 "Failed to add slave to bonded device");
562 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
563 "Failed to start bonded pmd eth device %d.",
564 test_params->bonded_port_id);
566 /* Change link status of virtual pmd so it will be added to the active
567 * slave list of the bonded device*/
568 virtual_ethdev_simulate_link_status_interrupt(
569 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
571 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
572 slaves, RTE_MAX_ETHPORTS);
573 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
574 "Number of slaves (%d) is not expected value (%d).",
575 current_slave_count, test_params->bonded_slave_count);
577 current_slave_count = rte_eth_bond_active_slaves_get(
578 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
579 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
580 "Number of active slaves (%d) is not expected value (%d).",
581 current_slave_count, test_params->bonded_slave_count);
583 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
584 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
585 "Bonded device mode (%d) is not expected value (%d).\n",
586 current_bonding_mode, test_params->bonding_mode);
588 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
589 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
590 "Primary port (%d) is not expected value (%d).",
591 primary_port, test_params->slave_port_ids[0]);
593 rte_eth_link_get(test_params->bonded_port_id, &link_status);
594 TEST_ASSERT_EQUAL(link_status.link_status, 1,
595 "Bonded port (%d) status (%d) is not expected value (%d).\n",
596 test_params->bonded_port_id, link_status.link_status, 1);
602 test_stop_bonded_device(void)
604 int current_slave_count;
605 uint16_t slaves[RTE_MAX_ETHPORTS];
607 struct rte_eth_link link_status;
609 rte_eth_dev_stop(test_params->bonded_port_id);
611 rte_eth_link_get(test_params->bonded_port_id, &link_status);
612 TEST_ASSERT_EQUAL(link_status.link_status, 0,
613 "Bonded port (%d) status (%d) is not expected value (%d).",
614 test_params->bonded_port_id, link_status.link_status, 0);
616 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
617 slaves, RTE_MAX_ETHPORTS);
618 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
619 "Number of slaves (%d) is not expected value (%d).",
620 current_slave_count, test_params->bonded_slave_count);
622 current_slave_count = rte_eth_bond_active_slaves_get(
623 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
624 TEST_ASSERT_EQUAL(current_slave_count, 0,
625 "Number of active slaves (%d) is not expected value (%d).",
626 current_slave_count, 0);
632 remove_slaves_and_stop_bonded_device(void)
634 /* Clean up and remove slaves from bonded device */
635 free_virtualpmd_tx_queue();
636 while (test_params->bonded_slave_count > 0)
637 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
638 "test_remove_slave_from_bonded_device failed");
640 rte_eth_dev_stop(test_params->bonded_port_id);
641 rte_eth_stats_reset(test_params->bonded_port_id);
642 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
648 test_set_bonding_mode(void)
652 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
653 BONDING_MODE_ACTIVE_BACKUP,
654 BONDING_MODE_BALANCE,
655 BONDING_MODE_BROADCAST
658 /* Test supported link bonding modes */
659 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
660 /* Invalid port ID */
661 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
663 "Expected call to failed as invalid port (%d) specified.",
666 /* Non bonded device */
667 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
669 "Expected call to failed as invalid port (%d) specified.",
670 test_params->slave_port_ids[0]);
672 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
674 "Failed to set link bonding mode on port (%d) to (%d).",
675 test_params->bonded_port_id, bonding_modes[i]);
677 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
678 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
679 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
680 bonding_mode, test_params->bonded_port_id,
683 /* Invalid port ID */
684 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
685 TEST_ASSERT(bonding_mode < 0,
686 "Expected call to failed as invalid port (%d) specified.",
689 /* Non bonded device */
690 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
691 TEST_ASSERT(bonding_mode < 0,
692 "Expected call to failed as invalid port (%d) specified.",
693 test_params->slave_port_ids[0]);
696 return remove_slaves_and_stop_bonded_device();
700 test_set_primary_slave(void)
703 struct ether_addr read_mac_addr;
704 struct ether_addr *expected_mac_addr;
706 /* Add 4 slaves to bonded device */
707 for (i = test_params->bonded_slave_count; i < 4; i++)
708 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
709 "Failed to add slave to bonded device.");
711 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
712 BONDING_MODE_ROUND_ROBIN),
713 "Failed to set link bonding mode on port (%d) to (%d).",
714 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
716 /* Invalid port ID */
717 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
718 test_params->slave_port_ids[i]),
719 "Expected call to failed as invalid port specified.");
721 /* Non bonded device */
722 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
723 test_params->slave_port_ids[i]),
724 "Expected call to failed as invalid port specified.");
726 /* Set slave as primary
727 * Verify slave it is now primary slave
728 * Verify that MAC address of bonded device is that of primary slave
729 * Verify that MAC address of all bonded slaves are that of primary slave
731 for (i = 0; i < 4; i++) {
732 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
733 test_params->slave_port_ids[i]),
734 "Failed to set bonded port (%d) primary port to (%d)",
735 test_params->bonded_port_id, test_params->slave_port_ids[i]);
737 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
738 TEST_ASSERT(retval >= 0,
739 "Failed to read primary port from bonded port (%d)\n",
740 test_params->bonded_port_id);
742 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
743 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
744 test_params->bonded_port_id, retval,
745 test_params->slave_port_ids[i]);
747 /* stop/start bonded eth dev to apply new MAC */
748 rte_eth_dev_stop(test_params->bonded_port_id);
750 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
751 "Failed to start bonded port %d",
752 test_params->bonded_port_id);
754 expected_mac_addr = (struct ether_addr *)&slave_mac;
755 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
757 /* Check primary slave MAC */
758 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
759 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
760 sizeof(read_mac_addr)),
761 "bonded port mac address not set to that of primary port\n");
763 /* Check bonded MAC */
764 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
765 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
766 sizeof(read_mac_addr)),
767 "bonded port mac address not set to that of primary port\n");
769 /* Check other slaves MACs */
770 for (j = 0; j < 4; j++) {
772 rte_eth_macaddr_get(test_params->slave_port_ids[j],
774 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
775 sizeof(read_mac_addr)),
776 "slave port mac address not set to that of primary "
783 /* Test with none existent port */
784 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
785 "read primary port from expectedly");
787 /* Test with slave port */
788 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
789 "read primary port from expectedly\n");
791 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
792 "Failed to stop and remove slaves from bonded device");
795 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
796 "read primary port from expectedly\n");
802 test_set_explicit_bonded_mac(void)
805 struct ether_addr read_mac_addr;
806 struct ether_addr *mac_addr;
808 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
810 mac_addr = (struct ether_addr *)explicit_bonded_mac;
812 /* Invalid port ID */
813 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
814 "Expected call to failed as invalid port specified.");
816 /* Non bonded device */
817 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
818 test_params->slave_port_ids[0], mac_addr),
819 "Expected call to failed as invalid port specified.");
821 /* NULL MAC address */
822 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
823 test_params->bonded_port_id, NULL),
824 "Expected call to failed as NULL MAC specified");
826 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
827 test_params->bonded_port_id, mac_addr),
828 "Failed to set MAC address on bonded port (%d)",
829 test_params->bonded_port_id);
831 /* Add 4 slaves to bonded device */
832 for (i = test_params->bonded_slave_count; i < 4; i++) {
833 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
834 "Failed to add slave to bonded device.\n");
837 /* Check bonded MAC */
838 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
839 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
840 "bonded port mac address not set to that of primary port");
842 /* Check other slaves MACs */
843 for (i = 0; i < 4; i++) {
844 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
845 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
846 sizeof(read_mac_addr)),
847 "slave port mac address not set to that of primary port");
850 /* test resetting mac address on bonded device */
852 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
853 "Failed to reset MAC address on bonded port (%d)",
854 test_params->bonded_port_id);
857 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
858 "Reset MAC address on bonded port (%d) unexpectedly",
859 test_params->slave_port_ids[1]);
861 /* test resetting mac address on bonded device with no slaves */
862 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
863 "Failed to remove slaves and stop bonded device");
865 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
866 "Failed to reset MAC address on bonded port (%d)",
867 test_params->bonded_port_id);
872 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
875 test_set_bonded_port_initialization_mac_assignment(void)
877 int i, slave_count, bonded_port_id;
879 uint16_t slaves[RTE_MAX_ETHPORTS];
880 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
882 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
884 /* Initialize default values for MAC addresses */
885 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
886 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
889 * 1. a - Create / configure bonded / slave ethdevs
891 bonded_port_id = rte_eth_bond_create("net_bonding_mac_ass_test",
892 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
893 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
895 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
896 "Failed to configure bonded ethdev");
898 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
899 char pmd_name[RTE_ETH_NAME_MAX_LEN];
901 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
903 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
905 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
906 &slave_mac_addr, rte_socket_id(), 1);
908 TEST_ASSERT(slave_port_ids[i] >= 0,
909 "Failed to create slave ethdev %s", pmd_name);
911 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
912 "Failed to configure virtual ethdev %s",
918 * 2. Add slave ethdevs to bonded device
920 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
921 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
923 "Failed to add slave (%d) to bonded port (%d).",
924 slave_port_ids[i], bonded_port_id);
927 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
929 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
930 "Number of slaves (%d) is not as expected (%d)",
931 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
935 * 3. Set explicit MAC address on bonded ethdev
937 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
938 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
940 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
941 bonded_port_id, &bonded_mac_addr),
942 "Failed to set MAC address on bonded port (%d)",
946 /* 4. a - Start bonded ethdev
947 * b - Enable slave devices
948 * c - Verify bonded/slaves ethdev MAC addresses
950 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
951 "Failed to start bonded pmd eth device %d.",
954 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
955 virtual_ethdev_simulate_link_status_interrupt(
956 slave_port_ids[i], 1);
959 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
960 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
961 sizeof(read_mac_addr)),
962 "bonded port mac address not as expected");
964 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
965 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
966 sizeof(read_mac_addr)),
967 "slave port 0 mac address not as expected");
969 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
970 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
971 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
972 sizeof(read_mac_addr)),
973 "slave port 1 mac address not as expected");
975 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
976 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
977 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
978 sizeof(read_mac_addr)),
979 "slave port 2 mac address not as expected");
982 /* 7. a - Change primary port
983 * b - Stop / Start bonded port
984 * d - Verify slave ethdev MAC addresses
986 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
988 "failed to set primary port on bonded device.");
990 rte_eth_dev_stop(bonded_port_id);
991 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
992 "Failed to start bonded pmd eth device %d.",
995 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
996 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
997 sizeof(read_mac_addr)),
998 "bonded port mac address not as expected");
1000 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1001 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1002 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1003 sizeof(read_mac_addr)),
1004 "slave port 0 mac address not as expected");
1006 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1007 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1008 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1009 sizeof(read_mac_addr)),
1010 "slave port 1 mac address not as expected");
1012 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1013 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1014 sizeof(read_mac_addr)),
1015 "slave port 2 mac address not as expected");
1017 /* 6. a - Stop bonded ethdev
1018 * b - remove slave ethdevs
1019 * c - Verify slave ethdevs MACs are restored
1021 rte_eth_dev_stop(bonded_port_id);
1023 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1024 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1026 "Failed to remove slave %d from bonded port (%d).",
1027 slave_port_ids[i], bonded_port_id);
1030 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1033 TEST_ASSERT_EQUAL(slave_count, 0,
1034 "Number of slaves (%d) is great than expected (%d).",
1037 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1038 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1039 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1040 sizeof(read_mac_addr)),
1041 "slave port 0 mac address not as expected");
1043 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1044 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1045 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1046 sizeof(read_mac_addr)),
1047 "slave port 1 mac address not as expected");
1049 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1050 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1051 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1052 sizeof(read_mac_addr)),
1053 "slave port 2 mac address not as expected");
1060 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1061 uint16_t number_of_slaves, uint8_t enable_slave)
1063 /* Configure bonded device */
1064 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1065 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1066 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1069 /* Add slaves to bonded device */
1070 while (number_of_slaves > test_params->bonded_slave_count)
1071 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1072 "Failed to add slave (%d to bonding port (%d).",
1073 test_params->bonded_slave_count - 1,
1074 test_params->bonded_port_id);
1076 /* Set link bonding mode */
1077 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1079 "Failed to set link bonding mode on port (%d) to (%d).",
1080 test_params->bonded_port_id, bonding_mode);
1082 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1083 "Failed to start bonded pmd eth device %d.",
1084 test_params->bonded_port_id);
1087 enable_bonded_slaves();
1093 test_adding_slave_after_bonded_device_started(void)
1097 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1098 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1099 "Failed to add slaves to bonded device");
1101 /* Enabled slave devices */
1102 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1103 virtual_ethdev_simulate_link_status_interrupt(
1104 test_params->slave_port_ids[i], 1);
1107 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1108 test_params->slave_port_ids[test_params->bonded_slave_count]),
1109 "Failed to add slave to bonded port.\n");
1111 rte_eth_stats_reset(
1112 test_params->slave_port_ids[test_params->bonded_slave_count]);
1114 test_params->bonded_slave_count++;
1116 return remove_slaves_and_stop_bonded_device();
1119 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1120 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1122 int test_lsc_interrupt_count;
1126 test_bonding_lsc_event_callback(uint16_t port_id __rte_unused,
1127 enum rte_eth_event_type type __rte_unused,
1128 void *param __rte_unused,
1129 void *ret_param __rte_unused)
1131 pthread_mutex_lock(&mutex);
1132 test_lsc_interrupt_count++;
1134 pthread_cond_signal(&cvar);
1135 pthread_mutex_unlock(&mutex);
1141 lsc_timeout(int wait_us)
1148 gettimeofday(&tp, NULL);
1150 /* Convert from timeval to timespec */
1151 ts.tv_sec = tp.tv_sec;
1152 ts.tv_nsec = tp.tv_usec * 1000;
1153 ts.tv_nsec += wait_us * 1000;
1155 pthread_mutex_lock(&mutex);
1156 if (test_lsc_interrupt_count < 1)
1157 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1159 pthread_mutex_unlock(&mutex);
1161 if (retval == 0 && test_lsc_interrupt_count < 1)
1168 test_status_interrupt(void)
1171 uint16_t slaves[RTE_MAX_ETHPORTS];
1173 /* initialized bonding device with T slaves */
1174 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1175 BONDING_MODE_ROUND_ROBIN, 1,
1176 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1177 "Failed to initialise bonded device");
1179 test_lsc_interrupt_count = 0;
1181 /* register link status change interrupt callback */
1182 rte_eth_dev_callback_register(test_params->bonded_port_id,
1183 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1184 &test_params->bonded_port_id);
1186 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1187 slaves, RTE_MAX_ETHPORTS);
1189 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1190 "Number of active slaves (%d) is not as expected (%d)",
1191 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1193 /* Bring all 4 slaves link status to down and test that we have received a
1195 virtual_ethdev_simulate_link_status_interrupt(
1196 test_params->slave_port_ids[0], 0);
1197 virtual_ethdev_simulate_link_status_interrupt(
1198 test_params->slave_port_ids[1], 0);
1199 virtual_ethdev_simulate_link_status_interrupt(
1200 test_params->slave_port_ids[2], 0);
1202 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1203 "Received a link status change interrupt unexpectedly");
1205 virtual_ethdev_simulate_link_status_interrupt(
1206 test_params->slave_port_ids[3], 0);
1208 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1209 "timed out waiting for interrupt");
1211 TEST_ASSERT(test_lsc_interrupt_count > 0,
1212 "Did not receive link status change interrupt");
1214 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1215 slaves, RTE_MAX_ETHPORTS);
1217 TEST_ASSERT_EQUAL(slave_count, 0,
1218 "Number of active slaves (%d) is not as expected (%d)",
1221 /* bring one slave port up so link status will change */
1222 test_lsc_interrupt_count = 0;
1224 virtual_ethdev_simulate_link_status_interrupt(
1225 test_params->slave_port_ids[0], 1);
1227 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1228 "timed out waiting for interrupt");
1230 /* test that we have received another lsc interrupt */
1231 TEST_ASSERT(test_lsc_interrupt_count > 0,
1232 "Did not receive link status change interrupt");
1234 /* Verify that calling the same slave lsc interrupt doesn't cause another
1235 * lsc interrupt from bonded device */
1236 test_lsc_interrupt_count = 0;
1238 virtual_ethdev_simulate_link_status_interrupt(
1239 test_params->slave_port_ids[0], 1);
1241 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1242 "received unexpected interrupt");
1244 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1245 "Did not receive link status change interrupt");
1248 /* unregister lsc callback before exiting */
1249 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1250 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1251 &test_params->bonded_port_id);
1253 /* Clean up and remove slaves from bonded device */
1254 return remove_slaves_and_stop_bonded_device();
1258 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1259 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1260 uint8_t toggle_ip_addr, uint16_t toggle_udp_port)
1262 uint16_t pktlen, generated_burst_size, ether_type;
1266 ether_type = ETHER_TYPE_IPv4;
1268 ether_type = ETHER_TYPE_IPv6;
1271 initialize_eth_header(test_params->pkt_eth_hdr,
1272 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1273 ether_type, vlan, vlan_id);
1275 initialize_eth_header(test_params->pkt_eth_hdr,
1276 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1277 ether_type, vlan, vlan_id);
1280 if (toggle_udp_port)
1281 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1284 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1289 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1290 dst_addr_1, pktlen);
1292 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1293 dst_addr_0, pktlen);
1295 ip_hdr = test_params->pkt_ipv4_hdr;
1298 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1299 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1302 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1303 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1306 ip_hdr = test_params->pkt_ipv6_hdr;
1309 /* Generate burst of packets to transmit */
1310 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1311 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1312 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1314 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1315 "Failed to generate packet burst");
1317 return generated_burst_size;
1320 /** Round Robin Mode Tests */
1323 test_roundrobin_tx_burst(void)
1326 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1327 struct rte_eth_stats port_stats;
1329 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1330 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1331 "Failed to initialise bonded device");
1333 burst_size = 20 * test_params->bonded_slave_count;
1335 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1336 "Burst size specified is greater than supported.");
1338 /* Generate test bursts of packets to transmit */
1339 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1340 burst_size, "failed to generate test burst");
1342 /* Send burst on bonded port */
1343 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1344 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1347 /* Verify bonded port tx stats */
1348 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1349 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1350 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1351 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1354 /* Verify slave ports tx stats */
1355 for (i = 0; i < test_params->bonded_slave_count; i++) {
1356 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1357 TEST_ASSERT_EQUAL(port_stats.opackets,
1358 (uint64_t)burst_size / test_params->bonded_slave_count,
1359 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1360 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1361 burst_size / test_params->bonded_slave_count);
1364 /* Put all slaves down and try and transmit */
1365 for (i = 0; i < test_params->bonded_slave_count; i++) {
1366 virtual_ethdev_simulate_link_status_interrupt(
1367 test_params->slave_port_ids[i], 0);
1370 /* Send burst on bonded port */
1371 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1372 pkt_burst, burst_size), 0,
1373 "tx burst return unexpected value");
1375 /* Clean up and remove slaves from bonded device */
1376 return remove_slaves_and_stop_bonded_device();
1380 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1384 for (i = 0; i < nb_mbufs; i++) {
1385 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1386 TEST_ASSERT_EQUAL(refcnt, val,
1387 "mbuf ref count (%d)is not the expected value (%d)",
1394 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1398 for (i = 0; i < nb_mbufs; i++)
1399 rte_pktmbuf_free(mbufs[i]);
1402 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1403 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1404 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1405 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1408 test_roundrobin_tx_burst_slave_tx_fail(void)
1410 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1411 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1413 struct rte_eth_stats port_stats;
1415 int i, first_fail_idx, tx_count;
1417 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1418 BONDING_MODE_ROUND_ROBIN, 0,
1419 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1420 "Failed to initialise bonded device");
1422 /* Generate test bursts of packets to transmit */
1423 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1424 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1425 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1426 "Failed to generate test packet burst");
1428 /* Copy references to packets which we expect not to be transmitted */
1429 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1430 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1431 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1432 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1434 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1435 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1436 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1439 /* Set virtual slave to only fail transmission of
1440 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1441 virtual_ethdev_tx_burst_fn_set_success(
1442 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1445 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1446 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1447 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1449 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1450 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1452 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1453 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1454 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1455 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1456 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1458 /* Verify that failed packet are expected failed packets */
1459 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1460 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1461 "expected mbuf (%d) pointer %p not expected pointer %p",
1462 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1465 /* Verify bonded port tx stats */
1466 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1468 TEST_ASSERT_EQUAL(port_stats.opackets,
1469 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1470 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1471 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1472 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1473 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1474 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1476 /* Verify slave ports tx stats */
1477 for (i = 0; i < test_params->bonded_slave_count; i++) {
1478 int slave_expected_tx_count;
1480 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1482 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1483 test_params->bonded_slave_count;
1485 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1486 slave_expected_tx_count = slave_expected_tx_count -
1487 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1489 TEST_ASSERT_EQUAL(port_stats.opackets,
1490 (uint64_t)slave_expected_tx_count,
1491 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1492 test_params->slave_port_ids[i],
1493 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1496 /* Verify that all mbufs have a ref value of zero */
1497 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1498 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1499 "mbufs refcnts not as expected");
1500 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1502 /* Clean up and remove slaves from bonded device */
1503 return remove_slaves_and_stop_bonded_device();
1507 test_roundrobin_rx_burst_on_single_slave(void)
1509 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1510 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1512 struct rte_eth_stats port_stats;
1514 int i, j, burst_size = 25;
1516 /* Initialize bonded device with 4 slaves in round robin mode */
1517 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1518 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1519 "Failed to initialize bonded device with slaves");
1521 /* Generate test bursts of packets to transmit */
1522 TEST_ASSERT_EQUAL(generate_test_burst(
1523 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1524 "burst generation failed");
1526 for (i = 0; i < test_params->bonded_slave_count; i++) {
1527 /* Add rx data to slave */
1528 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1529 &gen_pkt_burst[0], burst_size);
1531 /* Call rx burst on bonded device */
1532 /* Send burst on bonded port */
1533 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1534 test_params->bonded_port_id, 0, rx_pkt_burst,
1535 MAX_PKT_BURST), burst_size,
1536 "round-robin rx burst failed");
1538 /* Verify bonded device rx count */
1539 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1540 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1541 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1542 test_params->bonded_port_id,
1543 (unsigned int)port_stats.ipackets, burst_size);
1547 /* Verify bonded slave devices rx count */
1548 /* Verify slave ports tx stats */
1549 for (j = 0; j < test_params->bonded_slave_count; j++) {
1550 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1553 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1554 "Slave Port (%d) ipackets value (%u) not as expected"
1555 " (%d)", test_params->slave_port_ids[i],
1556 (unsigned int)port_stats.ipackets, burst_size);
1558 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1559 "Slave Port (%d) ipackets value (%u) not as expected"
1560 " (%d)", test_params->slave_port_ids[i],
1561 (unsigned int)port_stats.ipackets, 0);
1564 /* Reset bonded slaves stats */
1565 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1567 /* reset bonded device stats */
1568 rte_eth_stats_reset(test_params->bonded_port_id);
1572 for (i = 0; i < MAX_PKT_BURST; i++) {
1573 if (rx_pkt_burst[i] != NULL)
1574 rte_pktmbuf_free(rx_pkt_burst[i]);
1578 /* Clean up and remove slaves from bonded device */
1579 return remove_slaves_and_stop_bonded_device();
1582 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1585 test_roundrobin_rx_burst_on_multiple_slaves(void)
1587 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1589 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1590 struct rte_eth_stats port_stats;
1592 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1595 /* Initialize bonded device with 4 slaves in round robin mode */
1596 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1597 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1598 "Failed to initialize bonded device with slaves");
1600 /* Generate test bursts of packets to transmit */
1601 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1602 TEST_ASSERT_EQUAL(generate_test_burst(
1603 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1604 burst_size[i], "burst generation failed");
1607 /* Add rx data to slaves */
1608 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1609 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1610 &gen_pkt_burst[i][0], burst_size[i]);
1613 /* Call rx burst on bonded device */
1614 /* Send burst on bonded port */
1615 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1617 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1618 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1619 burst_size[0] + burst_size[1] + burst_size[2]);
1621 /* Verify bonded device rx count */
1622 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1623 TEST_ASSERT_EQUAL(port_stats.ipackets,
1624 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1625 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1626 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1627 burst_size[0] + burst_size[1] + burst_size[2]);
1629 /* Verify bonded slave devices rx counts */
1630 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1631 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1632 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1633 test_params->slave_port_ids[0],
1634 (unsigned int)port_stats.ipackets, burst_size[0]);
1636 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1637 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1638 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1639 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1642 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1643 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1644 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1645 test_params->slave_port_ids[2],
1646 (unsigned int)port_stats.ipackets, burst_size[2]);
1648 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1649 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1650 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1651 test_params->slave_port_ids[3],
1652 (unsigned int)port_stats.ipackets, 0);
1655 for (i = 0; i < MAX_PKT_BURST; i++) {
1656 if (rx_pkt_burst[i] != NULL)
1657 rte_pktmbuf_free(rx_pkt_burst[i]);
1660 /* Clean up and remove slaves from bonded device */
1661 return remove_slaves_and_stop_bonded_device();
1665 test_roundrobin_verify_mac_assignment(void)
1667 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1671 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1672 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1674 /* Initialize bonded device with 4 slaves in round robin mode */
1675 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1676 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1677 "Failed to initialize bonded device with slaves");
1679 /* Verify that all MACs are the same as first slave added to bonded dev */
1680 for (i = 0; i < test_params->bonded_slave_count; i++) {
1681 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1682 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1683 sizeof(read_mac_addr)),
1684 "slave port (%d) mac address not set to that of primary port",
1685 test_params->slave_port_ids[i]);
1688 /* change primary and verify that MAC addresses haven't changed */
1689 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1690 test_params->slave_port_ids[2]),
1691 "Failed to set bonded port (%d) primary port to (%d)",
1692 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1694 for (i = 0; i < test_params->bonded_slave_count; i++) {
1695 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1696 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1697 sizeof(read_mac_addr)),
1698 "slave port (%d) mac address has changed to that of primary"
1699 " port without stop/start toggle of bonded device",
1700 test_params->slave_port_ids[i]);
1703 /* stop / start bonded device and verify that primary MAC address is
1704 * propagate to bonded device and slaves */
1705 rte_eth_dev_stop(test_params->bonded_port_id);
1707 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1708 "Failed to start bonded device");
1710 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1711 TEST_ASSERT_SUCCESS(
1712 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1713 "bonded port (%d) mac address not set to that of new primary port",
1714 test_params->slave_port_ids[i]);
1716 for (i = 0; i < test_params->bonded_slave_count; i++) {
1717 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1718 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1719 sizeof(read_mac_addr)),
1720 "slave port (%d) mac address not set to that of new primary"
1721 " port", test_params->slave_port_ids[i]);
1724 /* Set explicit MAC address */
1725 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1726 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1727 "Failed to set MAC");
1729 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1730 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1731 sizeof(read_mac_addr)),
1732 "bonded port (%d) mac address not set to that of new primary port",
1733 test_params->slave_port_ids[i]);
1735 for (i = 0; i < test_params->bonded_slave_count; i++) {
1736 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1737 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1738 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1739 " that of new primary port\n", test_params->slave_port_ids[i]);
1742 /* Clean up and remove slaves from bonded device */
1743 return remove_slaves_and_stop_bonded_device();
1747 test_roundrobin_verify_promiscuous_enable_disable(void)
1749 int i, promiscuous_en;
1751 /* Initialize bonded device with 4 slaves in round robin mode */
1752 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1753 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1754 "Failed to initialize bonded device with slaves");
1756 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1758 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1759 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1760 "Port (%d) promiscuous mode not enabled",
1761 test_params->bonded_port_id);
1763 for (i = 0; i < test_params->bonded_slave_count; i++) {
1764 promiscuous_en = rte_eth_promiscuous_get(
1765 test_params->slave_port_ids[i]);
1766 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1767 "slave port (%d) promiscuous mode not enabled",
1768 test_params->slave_port_ids[i]);
1771 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1773 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1774 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1775 "Port (%d) promiscuous mode not disabled\n",
1776 test_params->bonded_port_id);
1778 for (i = 0; i < test_params->bonded_slave_count; i++) {
1779 promiscuous_en = rte_eth_promiscuous_get(
1780 test_params->slave_port_ids[i]);
1781 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1782 "Port (%d) promiscuous mode not disabled\n",
1783 test_params->slave_port_ids[i]);
1786 /* Clean up and remove slaves from bonded device */
1787 return remove_slaves_and_stop_bonded_device();
1790 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1791 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1794 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1796 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1797 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1798 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1800 struct rte_eth_stats port_stats;
1801 uint16_t slaves[RTE_MAX_ETHPORTS];
1803 int i, burst_size, slave_count;
1805 /* NULL all pointers in array to simplify cleanup */
1806 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1808 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1809 * in round robin mode */
1810 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1811 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1812 "Failed to initialize bonded device with slaves");
1814 /* Verify Current Slaves Count /Active Slave Count is */
1815 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1817 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1818 "Number of slaves (%d) is not as expected (%d).",
1819 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1821 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1822 slaves, RTE_MAX_ETHPORTS);
1823 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1824 "Number of active slaves (%d) is not as expected (%d).",
1825 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1827 /* Set 2 slaves eth_devs link status to down */
1828 virtual_ethdev_simulate_link_status_interrupt(
1829 test_params->slave_port_ids[1], 0);
1830 virtual_ethdev_simulate_link_status_interrupt(
1831 test_params->slave_port_ids[3], 0);
1833 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1834 slaves, RTE_MAX_ETHPORTS);
1835 TEST_ASSERT_EQUAL(slave_count,
1836 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1837 "Number of active slaves (%d) is not as expected (%d).\n",
1838 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1842 /* Verify that pkts are not sent on slaves with link status down:
1844 * 1. Generate test burst of traffic
1845 * 2. Transmit burst on bonded eth_dev
1846 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1847 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1850 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1851 burst_size, "generate_test_burst failed");
1853 rte_eth_stats_reset(test_params->bonded_port_id);
1857 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1858 burst_size), burst_size, "rte_eth_tx_burst failed");
1860 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1861 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1862 "Port (%d) opackets stats (%d) not expected (%d) value",
1863 test_params->bonded_port_id, (int)port_stats.opackets,
1866 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1867 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1868 "Port (%d) opackets stats (%d) not expected (%d) value",
1869 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1871 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1872 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1873 "Port (%d) opackets stats (%d) not expected (%d) value",
1874 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1876 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1877 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1878 "Port (%d) opackets stats (%d) not expected (%d) value",
1879 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1881 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1882 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1883 "Port (%d) opackets stats (%d) not expected (%d) value",
1884 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1886 /* Verify that pkts are not sent on slaves with link status down:
1888 * 1. Generate test bursts of traffic
1889 * 2. Add bursts on to virtual eth_devs
1890 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1891 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1892 * 4. Verify stats for bonded eth_dev
1893 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1895 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1896 TEST_ASSERT_EQUAL(generate_test_burst(
1897 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1898 burst_size, "failed to generate packet burst");
1900 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1901 &gen_pkt_burst[i][0], burst_size);
1904 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1905 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1906 burst_size + burst_size,
1907 "rte_eth_rx_burst failed");
1909 /* Verify bonded device rx count */
1910 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1911 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1912 "(%d) port_stats.ipackets not as expected\n",
1913 test_params->bonded_port_id);
1916 for (i = 0; i < MAX_PKT_BURST; i++) {
1917 if (rx_pkt_burst[i] != NULL)
1918 rte_pktmbuf_free(rx_pkt_burst[i]);
1921 /* Clean up and remove slaves from bonded device */
1922 return remove_slaves_and_stop_bonded_device();
1925 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1927 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1930 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1933 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1935 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1936 char slave_name[RTE_ETH_NAME_MAX_LEN];
1940 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1941 /* Generate slave name / MAC address */
1942 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1943 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
1945 /* Create slave devices with no ISR Support */
1946 if (polling_test_slaves[i] == -1) {
1947 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
1948 rte_socket_id(), 0);
1949 TEST_ASSERT(polling_test_slaves[i] >= 0,
1950 "Failed to create virtual virtual ethdev %s\n", slave_name);
1952 /* Configure slave */
1953 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
1954 "Failed to configure virtual ethdev %s(%d)", slave_name,
1955 polling_test_slaves[i]);
1958 /* Add slave to bonded device */
1959 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1960 polling_test_slaves[i]),
1961 "Failed to add slave %s(%d) to bonded device %d",
1962 slave_name, polling_test_slaves[i],
1963 test_params->bonded_port_id);
1966 /* Initialize bonded device */
1967 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
1968 "Failed to configure bonded device %d",
1969 test_params->bonded_port_id);
1972 /* Register link status change interrupt callback */
1973 rte_eth_dev_callback_register(test_params->bonded_port_id,
1974 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1975 &test_params->bonded_port_id);
1977 /* link status change callback for first slave link up */
1978 test_lsc_interrupt_count = 0;
1980 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
1982 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
1985 /* no link status change callback for second slave link up */
1986 test_lsc_interrupt_count = 0;
1988 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
1990 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
1992 /* link status change callback for both slave links down */
1993 test_lsc_interrupt_count = 0;
1995 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
1996 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
1998 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2000 /* Un-Register link status change interrupt callback */
2001 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2002 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2003 &test_params->bonded_port_id);
2006 /* Clean up and remove slaves from bonded device */
2007 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2009 TEST_ASSERT_SUCCESS(
2010 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2011 polling_test_slaves[i]),
2012 "Failed to remove slave %d from bonded port (%d)",
2013 polling_test_slaves[i], test_params->bonded_port_id);
2016 return remove_slaves_and_stop_bonded_device();
2020 /** Active Backup Mode Tests */
2023 test_activebackup_tx_burst(void)
2025 int i, pktlen, primary_port, burst_size;
2026 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2027 struct rte_eth_stats port_stats;
2029 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2030 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2031 "Failed to initialize bonded device with slaves");
2033 initialize_eth_header(test_params->pkt_eth_hdr,
2034 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2035 ETHER_TYPE_IPv4, 0, 0);
2036 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2038 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2039 dst_addr_0, pktlen);
2041 burst_size = 20 * test_params->bonded_slave_count;
2043 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2044 "Burst size specified is greater than supported.");
2046 /* Generate a burst of packets to transmit */
2047 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2048 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2049 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2050 burst_size, "failed to generate burst correctly");
2052 /* Send burst on bonded port */
2053 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2054 burst_size), burst_size, "tx burst failed");
2056 /* Verify bonded port tx stats */
2057 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2058 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2059 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2060 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2063 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2065 /* Verify slave ports tx stats */
2066 for (i = 0; i < test_params->bonded_slave_count; i++) {
2067 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2068 if (test_params->slave_port_ids[i] == primary_port) {
2069 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2070 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2071 test_params->bonded_port_id,
2072 (unsigned int)port_stats.opackets,
2073 burst_size / test_params->bonded_slave_count);
2075 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2076 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2077 test_params->bonded_port_id,
2078 (unsigned int)port_stats.opackets, 0);
2082 /* Put all slaves down and try and transmit */
2083 for (i = 0; i < test_params->bonded_slave_count; i++) {
2084 virtual_ethdev_simulate_link_status_interrupt(
2085 test_params->slave_port_ids[i], 0);
2088 /* Send burst on bonded port */
2089 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2090 pkts_burst, burst_size), 0, "Sending empty burst failed");
2092 /* Clean up and remove slaves from bonded device */
2093 return remove_slaves_and_stop_bonded_device();
2096 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2099 test_activebackup_rx_burst(void)
2101 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2102 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2104 struct rte_eth_stats port_stats;
2108 int i, j, burst_size = 17;
2110 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2111 BONDING_MODE_ACTIVE_BACKUP, 0,
2112 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2113 "Failed to initialize bonded device with slaves");
2115 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2116 TEST_ASSERT(primary_port >= 0,
2117 "failed to get primary slave for bonded port (%d)",
2118 test_params->bonded_port_id);
2120 for (i = 0; i < test_params->bonded_slave_count; i++) {
2121 /* Generate test bursts of packets to transmit */
2122 TEST_ASSERT_EQUAL(generate_test_burst(
2123 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2124 burst_size, "burst generation failed");
2126 /* Add rx data to slave */
2127 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2128 &gen_pkt_burst[0], burst_size);
2130 /* Call rx burst on bonded device */
2131 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2132 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2133 "rte_eth_rx_burst failed");
2135 if (test_params->slave_port_ids[i] == primary_port) {
2136 /* Verify bonded device rx count */
2137 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2138 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2139 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2140 test_params->bonded_port_id,
2141 (unsigned int)port_stats.ipackets, burst_size);
2143 /* Verify bonded slave devices rx count */
2144 for (j = 0; j < test_params->bonded_slave_count; j++) {
2145 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2147 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2148 "Slave Port (%d) ipackets value (%u) not as "
2149 "expected (%d)", test_params->slave_port_ids[i],
2150 (unsigned int)port_stats.ipackets, burst_size);
2152 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2153 "Slave Port (%d) ipackets value (%u) not as "
2154 "expected (%d)\n", test_params->slave_port_ids[i],
2155 (unsigned int)port_stats.ipackets, 0);
2159 for (j = 0; j < test_params->bonded_slave_count; j++) {
2160 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2161 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2162 "Slave Port (%d) ipackets value (%u) not as expected "
2163 "(%d)", test_params->slave_port_ids[i],
2164 (unsigned int)port_stats.ipackets, 0);
2169 for (i = 0; i < MAX_PKT_BURST; i++) {
2170 if (rx_pkt_burst[i] != NULL) {
2171 rte_pktmbuf_free(rx_pkt_burst[i]);
2172 rx_pkt_burst[i] = NULL;
2176 /* reset bonded device stats */
2177 rte_eth_stats_reset(test_params->bonded_port_id);
2180 /* Clean up and remove slaves from bonded device */
2181 return remove_slaves_and_stop_bonded_device();
2185 test_activebackup_verify_promiscuous_enable_disable(void)
2187 int i, primary_port, promiscuous_en;
2189 /* Initialize bonded device with 4 slaves in round robin mode */
2190 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2191 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2192 "Failed to initialize bonded device with slaves");
2194 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2195 TEST_ASSERT(primary_port >= 0,
2196 "failed to get primary slave for bonded port (%d)",
2197 test_params->bonded_port_id);
2199 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2201 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2202 "Port (%d) promiscuous mode not enabled",
2203 test_params->bonded_port_id);
2205 for (i = 0; i < test_params->bonded_slave_count; i++) {
2206 promiscuous_en = rte_eth_promiscuous_get(
2207 test_params->slave_port_ids[i]);
2208 if (primary_port == test_params->slave_port_ids[i]) {
2209 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2210 "slave port (%d) promiscuous mode not enabled",
2211 test_params->slave_port_ids[i]);
2213 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2214 "slave port (%d) promiscuous mode enabled",
2215 test_params->slave_port_ids[i]);
2220 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2222 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2223 "Port (%d) promiscuous mode not disabled\n",
2224 test_params->bonded_port_id);
2226 for (i = 0; i < test_params->bonded_slave_count; i++) {
2227 promiscuous_en = rte_eth_promiscuous_get(
2228 test_params->slave_port_ids[i]);
2229 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2230 "slave port (%d) promiscuous mode not disabled\n",
2231 test_params->slave_port_ids[i]);
2234 /* Clean up and remove slaves from bonded device */
2235 return remove_slaves_and_stop_bonded_device();
2239 test_activebackup_verify_mac_assignment(void)
2241 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2243 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2244 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2246 /* Initialize bonded device with 2 slaves in active backup mode */
2247 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2248 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2249 "Failed to initialize bonded device with slaves");
2251 /* Verify that bonded MACs is that of first slave and that the other slave
2252 * MAC hasn't been changed */
2253 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2254 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2255 sizeof(read_mac_addr)),
2256 "bonded port (%d) mac address not set to that of primary port",
2257 test_params->bonded_port_id);
2259 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2260 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2261 sizeof(read_mac_addr)),
2262 "slave port (%d) mac address not set to that of primary port",
2263 test_params->slave_port_ids[0]);
2265 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2266 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2267 sizeof(read_mac_addr)),
2268 "slave port (%d) mac address not as expected",
2269 test_params->slave_port_ids[1]);
2271 /* change primary and verify that MAC addresses haven't changed */
2272 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2273 test_params->slave_port_ids[1]), 0,
2274 "Failed to set bonded port (%d) primary port to (%d)",
2275 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2277 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2278 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2279 sizeof(read_mac_addr)),
2280 "bonded port (%d) mac address not set to that of primary port",
2281 test_params->bonded_port_id);
2283 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2284 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2285 sizeof(read_mac_addr)),
2286 "slave port (%d) mac address not set to that of primary port",
2287 test_params->slave_port_ids[0]);
2289 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2290 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2291 sizeof(read_mac_addr)),
2292 "slave port (%d) mac address not as expected",
2293 test_params->slave_port_ids[1]);
2295 /* stop / start bonded device and verify that primary MAC address is
2296 * propagated to bonded device and slaves */
2298 rte_eth_dev_stop(test_params->bonded_port_id);
2300 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2301 "Failed to start device");
2303 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2304 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2305 sizeof(read_mac_addr)),
2306 "bonded port (%d) mac address not set to that of primary port",
2307 test_params->bonded_port_id);
2309 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2311 sizeof(read_mac_addr)),
2312 "slave port (%d) mac address not as expected",
2313 test_params->slave_port_ids[0]);
2315 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2317 sizeof(read_mac_addr)),
2318 "slave port (%d) mac address not set to that of primary port",
2319 test_params->slave_port_ids[1]);
2321 /* Set explicit MAC address */
2322 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2323 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2324 "failed to set MAC address");
2326 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2327 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2328 sizeof(read_mac_addr)),
2329 "bonded port (%d) mac address not set to that of bonded port",
2330 test_params->bonded_port_id);
2332 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2333 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2334 sizeof(read_mac_addr)),
2335 "slave port (%d) mac address not as expected",
2336 test_params->slave_port_ids[0]);
2338 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2339 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2340 sizeof(read_mac_addr)),
2341 "slave port (%d) mac address not set to that of bonded port",
2342 test_params->slave_port_ids[1]);
2344 /* Clean up and remove slaves from bonded device */
2345 return remove_slaves_and_stop_bonded_device();
2349 test_activebackup_verify_slave_link_status_change_failover(void)
2351 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2352 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2353 struct rte_eth_stats port_stats;
2355 uint16_t slaves[RTE_MAX_ETHPORTS];
2357 int i, burst_size, slave_count, primary_port;
2361 memset(pkt_burst, 0, sizeof(pkt_burst));
2363 /* Generate packet burst for testing */
2364 TEST_ASSERT_EQUAL(generate_test_burst(
2365 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2366 "generate_test_burst failed");
2368 /* Initialize bonded device with 4 slaves in round robin mode */
2369 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2370 BONDING_MODE_ACTIVE_BACKUP, 0,
2371 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2372 "Failed to initialize bonded device with slaves");
2374 /* Verify Current Slaves Count /Active Slave Count is */
2375 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2377 TEST_ASSERT_EQUAL(slave_count, 4,
2378 "Number of slaves (%d) is not as expected (%d).",
2381 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2382 slaves, RTE_MAX_ETHPORTS);
2383 TEST_ASSERT_EQUAL(slave_count, 4,
2384 "Number of active slaves (%d) is not as expected (%d).",
2387 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2388 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2389 "Primary port not as expected");
2391 /* Bring 2 slaves down and verify active slave count */
2392 virtual_ethdev_simulate_link_status_interrupt(
2393 test_params->slave_port_ids[1], 0);
2394 virtual_ethdev_simulate_link_status_interrupt(
2395 test_params->slave_port_ids[3], 0);
2397 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2398 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2399 "Number of active slaves (%d) is not as expected (%d).",
2402 virtual_ethdev_simulate_link_status_interrupt(
2403 test_params->slave_port_ids[1], 1);
2404 virtual_ethdev_simulate_link_status_interrupt(
2405 test_params->slave_port_ids[3], 1);
2408 /* Bring primary port down, verify that active slave count is 3 and primary
2410 virtual_ethdev_simulate_link_status_interrupt(
2411 test_params->slave_port_ids[0], 0);
2413 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2414 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2416 "Number of active slaves (%d) is not as expected (%d).",
2419 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2420 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2421 "Primary port not as expected");
2423 /* Verify that pkts are sent on new primary slave */
2425 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2426 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2427 burst_size), burst_size, "rte_eth_tx_burst failed");
2429 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2430 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2431 "(%d) port_stats.opackets not as expected",
2432 test_params->slave_port_ids[2]);
2434 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2435 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2436 "(%d) port_stats.opackets not as expected\n",
2437 test_params->slave_port_ids[0]);
2439 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2440 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2441 "(%d) port_stats.opackets not as expected\n",
2442 test_params->slave_port_ids[1]);
2444 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2445 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2446 "(%d) port_stats.opackets not as expected\n",
2447 test_params->slave_port_ids[3]);
2449 /* Generate packet burst for testing */
2451 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2452 TEST_ASSERT_EQUAL(generate_test_burst(
2453 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2454 "generate_test_burst failed");
2456 virtual_ethdev_add_mbufs_to_rx_queue(
2457 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2460 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2461 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2462 burst_size, "rte_eth_rx_burst\n");
2464 /* Verify bonded device rx count */
2465 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2466 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2467 "(%d) port_stats.ipackets not as expected",
2468 test_params->bonded_port_id);
2470 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2471 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2472 "(%d) port_stats.opackets not as expected",
2473 test_params->slave_port_ids[2]);
2475 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2476 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2477 "(%d) port_stats.opackets not as expected",
2478 test_params->slave_port_ids[0]);
2480 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2481 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2482 "(%d) port_stats.opackets not as expected",
2483 test_params->slave_port_ids[1]);
2485 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2486 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2487 "(%d) port_stats.opackets not as expected",
2488 test_params->slave_port_ids[3]);
2490 /* Clean up and remove slaves from bonded device */
2491 return remove_slaves_and_stop_bonded_device();
2494 /** Balance Mode Tests */
2497 test_balance_xmit_policy_configuration(void)
2499 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2500 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2501 "Failed to initialize_bonded_device_with_slaves.");
2503 /* Invalid port id */
2504 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2505 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2506 "Expected call to failed as invalid port specified.");
2508 /* Set xmit policy on non bonded device */
2509 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2510 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2511 "Expected call to failed as invalid port specified.");
2514 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2515 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2516 "Failed to set balance xmit policy.");
2518 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2519 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2522 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2523 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2524 "Failed to set balance xmit policy.");
2526 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2527 BALANCE_XMIT_POLICY_LAYER23,
2528 "balance xmit policy not as expected.");
2531 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2532 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2533 "Failed to set balance xmit policy.");
2535 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2536 BALANCE_XMIT_POLICY_LAYER34,
2537 "balance xmit policy not as expected.");
2539 /* Invalid port id */
2540 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2541 "Expected call to failed as invalid port specified.");
2543 /* Clean up and remove slaves from bonded device */
2544 return remove_slaves_and_stop_bonded_device();
2547 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2550 test_balance_l2_tx_burst(void)
2552 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2553 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2557 struct rte_eth_stats port_stats;
2559 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2560 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2561 "Failed to initialize_bonded_device_with_slaves.");
2563 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2564 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2565 "Failed to set balance xmit policy.");
2567 initialize_eth_header(test_params->pkt_eth_hdr,
2568 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2569 ETHER_TYPE_IPv4, 0, 0);
2570 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2572 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2573 dst_addr_0, pktlen);
2575 /* Generate a burst 1 of packets to transmit */
2576 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2577 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2578 test_params->pkt_udp_hdr, burst_size[0],
2579 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2580 "failed to generate packet burst");
2582 initialize_eth_header(test_params->pkt_eth_hdr,
2583 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2584 ETHER_TYPE_IPv4, 0, 0);
2586 /* Generate a burst 2 of packets to transmit */
2587 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2588 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2589 test_params->pkt_udp_hdr, burst_size[1],
2590 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2591 "failed to generate packet burst");
2593 /* Send burst 1 on bonded port */
2594 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2595 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2596 &pkts_burst[i][0], burst_size[i]),
2597 burst_size[i], "Failed to transmit packet burst");
2600 /* Verify bonded port tx stats */
2601 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2602 TEST_ASSERT_EQUAL(port_stats.opackets,
2603 (uint64_t)(burst_size[0] + burst_size[1]),
2604 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2605 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2606 burst_size[0] + burst_size[1]);
2609 /* Verify slave ports tx stats */
2610 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2611 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2612 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2613 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2616 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2617 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2618 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2619 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2622 /* Put all slaves down and try and transmit */
2623 for (i = 0; i < test_params->bonded_slave_count; i++) {
2625 virtual_ethdev_simulate_link_status_interrupt(
2626 test_params->slave_port_ids[i], 0);
2629 /* Send burst on bonded port */
2630 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2631 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2632 0, "Expected zero packet");
2634 /* Clean up and remove slaves from bonded device */
2635 return remove_slaves_and_stop_bonded_device();
2639 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2640 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2642 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2644 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2645 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2647 struct rte_eth_stats port_stats;
2649 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2650 BONDING_MODE_BALANCE, 0, 2, 1),
2651 "Failed to initialize_bonded_device_with_slaves.");
2653 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2654 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2655 "Failed to set balance xmit policy.");
2660 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2661 "Burst size specified is greater than supported.");
2663 /* Generate test bursts of packets to transmit */
2664 TEST_ASSERT_EQUAL(generate_test_burst(
2665 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2666 burst_size_1, "failed to generate packet burst");
2668 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2669 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2670 "failed to generate packet burst");
2672 /* Send burst 1 on bonded port */
2673 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2675 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2677 /* Send burst 2 on bonded port */
2678 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2680 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2682 /* Verify bonded port tx stats */
2683 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2684 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2685 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2686 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2689 /* Verify slave ports tx stats */
2690 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2691 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2692 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2693 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2696 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2697 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2698 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2699 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2702 /* Put all slaves down and try and transmit */
2703 for (i = 0; i < test_params->bonded_slave_count; i++) {
2705 virtual_ethdev_simulate_link_status_interrupt(
2706 test_params->slave_port_ids[i], 0);
2709 /* Send burst on bonded port */
2710 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2711 test_params->bonded_port_id, 0, pkts_burst_1,
2712 burst_size_1), 0, "Expected zero packet");
2715 /* Clean up and remove slaves from bonded device */
2716 return remove_slaves_and_stop_bonded_device();
2720 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2722 return balance_l23_tx_burst(0, 1, 0, 1);
2726 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2728 return balance_l23_tx_burst(1, 1, 0, 1);
2732 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2734 return balance_l23_tx_burst(0, 0, 0, 1);
2738 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2740 return balance_l23_tx_burst(1, 0, 0, 1);
2744 test_balance_l23_tx_burst_toggle_mac_addr(void)
2746 return balance_l23_tx_burst(0, 0, 1, 0);
2750 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2751 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2752 uint8_t toggle_udp_port)
2754 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2756 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2757 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2759 struct rte_eth_stats port_stats;
2761 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2762 BONDING_MODE_BALANCE, 0, 2, 1),
2763 "Failed to initialize_bonded_device_with_slaves.");
2765 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2766 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2767 "Failed to set balance xmit policy.");
2772 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2773 "Burst size specified is greater than supported.");
2775 /* Generate test bursts of packets to transmit */
2776 TEST_ASSERT_EQUAL(generate_test_burst(
2777 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2778 burst_size_1, "failed to generate burst");
2780 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2781 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2782 toggle_udp_port), burst_size_2, "failed to generate burst");
2784 /* Send burst 1 on bonded port */
2785 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2787 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2789 /* Send burst 2 on bonded port */
2790 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2792 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2795 /* Verify bonded port tx stats */
2796 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2797 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2798 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2799 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2802 /* Verify slave ports tx stats */
2803 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2804 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2805 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2806 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2809 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2810 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2811 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2812 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2815 /* Put all slaves down and try and transmit */
2816 for (i = 0; i < test_params->bonded_slave_count; i++) {
2818 virtual_ethdev_simulate_link_status_interrupt(
2819 test_params->slave_port_ids[i], 0);
2822 /* Send burst on bonded port */
2823 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2824 test_params->bonded_port_id, 0, pkts_burst_1,
2825 burst_size_1), 0, "Expected zero packet");
2827 /* Clean up and remove slaves from bonded device */
2828 return remove_slaves_and_stop_bonded_device();
2832 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2834 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2838 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2840 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2844 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2846 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2850 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2852 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2856 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2858 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2862 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2864 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2867 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2868 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2869 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2870 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2871 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2874 test_balance_tx_burst_slave_tx_fail(void)
2876 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2877 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2879 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2881 struct rte_eth_stats port_stats;
2883 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2885 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2886 BONDING_MODE_BALANCE, 0,
2887 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2888 "Failed to initialise bonded device");
2890 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2891 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2892 "Failed to set balance xmit policy.");
2895 /* Generate test bursts for transmission */
2896 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2897 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2898 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2899 "Failed to generate test packet burst 1");
2901 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2902 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2904 /* copy mbuf referneces for expected transmission failures */
2905 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2906 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2908 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2909 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2910 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2911 "Failed to generate test packet burst 2");
2914 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2915 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2916 virtual_ethdev_tx_burst_fn_set_success(
2917 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2920 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2921 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2922 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2925 /* Transmit burst 1 */
2926 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2927 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2929 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2930 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2931 "Transmitted (%d) packets, expected to transmit (%d) packets",
2932 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2933 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2935 /* Verify that failed packet are expected failed packets */
2936 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
2937 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
2938 "expected mbuf (%d) pointer %p not expected pointer %p",
2939 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
2942 /* Transmit burst 2 */
2943 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2944 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2946 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2947 "Transmitted (%d) packets, expected to transmit (%d) packets",
2948 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2951 /* Verify bonded port tx stats */
2952 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2954 TEST_ASSERT_EQUAL(port_stats.opackets,
2955 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2956 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2957 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
2958 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2959 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2960 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2961 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2962 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2964 /* Verify slave ports tx stats */
2966 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2968 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
2969 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2970 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2971 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2972 test_params->slave_port_ids[0],
2973 (unsigned int)port_stats.opackets,
2974 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2975 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2980 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2982 TEST_ASSERT_EQUAL(port_stats.opackets,
2983 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2984 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2985 test_params->slave_port_ids[1],
2986 (unsigned int)port_stats.opackets,
2987 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2989 /* Verify that all mbufs have a ref value of zero */
2990 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
2991 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
2992 "mbufs refcnts not as expected");
2994 free_mbufs(&pkts_burst_1[tx_count_1],
2995 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2997 /* Clean up and remove slaves from bonded device */
2998 return remove_slaves_and_stop_bonded_device();
3001 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3004 test_balance_rx_burst(void)
3006 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3008 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3009 struct rte_eth_stats port_stats;
3011 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3014 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3016 /* Initialize bonded device with 4 slaves in round robin mode */
3017 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3018 BONDING_MODE_BALANCE, 0, 3, 1),
3019 "Failed to initialise bonded device");
3021 /* Generate test bursts of packets to transmit */
3022 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3023 TEST_ASSERT_EQUAL(generate_test_burst(
3024 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3025 0, 0), burst_size[i],
3026 "failed to generate packet burst");
3029 /* Add rx data to slaves */
3030 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3031 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3032 &gen_pkt_burst[i][0], burst_size[i]);
3035 /* Call rx burst on bonded device */
3036 /* Send burst on bonded port */
3037 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3038 rx_pkt_burst, MAX_PKT_BURST),
3039 burst_size[0] + burst_size[1] + burst_size[2],
3040 "balance rx burst failed\n");
3042 /* Verify bonded device rx count */
3043 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3044 TEST_ASSERT_EQUAL(port_stats.ipackets,
3045 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3046 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3047 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3048 burst_size[0] + burst_size[1] + burst_size[2]);
3051 /* Verify bonded slave devices rx counts */
3052 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3053 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3054 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3055 test_params->slave_port_ids[0],
3056 (unsigned int)port_stats.ipackets, burst_size[0]);
3058 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3059 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3060 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3061 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3064 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3065 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3066 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3067 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3070 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3071 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3072 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3073 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3077 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3078 for (j = 0; j < MAX_PKT_BURST; j++) {
3079 if (gen_pkt_burst[i][j] != NULL) {
3080 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3081 gen_pkt_burst[i][j] = NULL;
3086 /* Clean up and remove slaves from bonded device */
3087 return remove_slaves_and_stop_bonded_device();
3091 test_balance_verify_promiscuous_enable_disable(void)
3095 /* Initialize bonded device with 4 slaves in round robin mode */
3096 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3097 BONDING_MODE_BALANCE, 0, 4, 1),
3098 "Failed to initialise bonded device");
3100 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3102 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3103 "Port (%d) promiscuous mode not enabled",
3104 test_params->bonded_port_id);
3106 for (i = 0; i < test_params->bonded_slave_count; i++) {
3107 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3108 test_params->slave_port_ids[i]), 1,
3109 "Port (%d) promiscuous mode not enabled",
3110 test_params->slave_port_ids[i]);
3113 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3115 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3116 "Port (%d) promiscuous mode not disabled",
3117 test_params->bonded_port_id);
3119 for (i = 0; i < test_params->bonded_slave_count; i++) {
3120 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3121 test_params->slave_port_ids[i]), 0,
3122 "Port (%d) promiscuous mode not disabled",
3123 test_params->slave_port_ids[i]);
3126 /* Clean up and remove slaves from bonded device */
3127 return remove_slaves_and_stop_bonded_device();
3131 test_balance_verify_mac_assignment(void)
3133 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3135 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3136 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3138 /* Initialize bonded device with 2 slaves in active backup mode */
3139 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3140 BONDING_MODE_BALANCE, 0, 2, 1),
3141 "Failed to initialise bonded device");
3143 /* Verify that bonded MACs is that of first slave and that the other slave
3144 * MAC hasn't been changed */
3145 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3146 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3147 sizeof(read_mac_addr)),
3148 "bonded port (%d) mac address not set to that of primary port",
3149 test_params->bonded_port_id);
3151 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3152 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3153 sizeof(read_mac_addr)),
3154 "slave port (%d) mac address not set to that of primary port",
3155 test_params->slave_port_ids[0]);
3157 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3158 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3159 sizeof(read_mac_addr)),
3160 "slave port (%d) mac address not set to that of primary port",
3161 test_params->slave_port_ids[1]);
3163 /* change primary and verify that MAC addresses haven't changed */
3164 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3165 test_params->slave_port_ids[1]),
3166 "Failed to set bonded port (%d) primary port to (%d)\n",
3167 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3169 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3170 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3171 sizeof(read_mac_addr)),
3172 "bonded port (%d) mac address not set to that of primary port",
3173 test_params->bonded_port_id);
3175 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3176 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3177 sizeof(read_mac_addr)),
3178 "slave port (%d) mac address not set to that of primary port",
3179 test_params->slave_port_ids[0]);
3181 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3182 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3183 sizeof(read_mac_addr)),
3184 "slave port (%d) mac address not set to that of primary port",
3185 test_params->slave_port_ids[1]);
3187 /* stop / start bonded device and verify that primary MAC address is
3188 * propagated to bonded device and slaves */
3190 rte_eth_dev_stop(test_params->bonded_port_id);
3192 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3193 "Failed to start bonded device");
3195 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3196 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3197 sizeof(read_mac_addr)),
3198 "bonded port (%d) mac address not set to that of primary port",
3199 test_params->bonded_port_id);
3201 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3202 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3203 sizeof(read_mac_addr)),
3204 "slave port (%d) mac address not set to that of primary port",
3205 test_params->slave_port_ids[0]);
3207 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3208 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3209 sizeof(read_mac_addr)),
3210 "slave port (%d) mac address not set to that of primary port",
3211 test_params->slave_port_ids[1]);
3213 /* Set explicit MAC address */
3214 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3215 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3216 "failed to set MAC");
3218 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3219 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3220 sizeof(read_mac_addr)),
3221 "bonded port (%d) mac address not set to that of bonded port",
3222 test_params->bonded_port_id);
3224 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3225 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3226 sizeof(read_mac_addr)),
3227 "slave port (%d) mac address not as expected\n",
3228 test_params->slave_port_ids[0]);
3230 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3231 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3232 sizeof(read_mac_addr)),
3233 "slave port (%d) mac address not set to that of bonded port",
3234 test_params->slave_port_ids[1]);
3236 /* Clean up and remove slaves from bonded device */
3237 return remove_slaves_and_stop_bonded_device();
3240 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3243 test_balance_verify_slave_link_status_change_behaviour(void)
3245 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3246 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3247 struct rte_eth_stats port_stats;
3249 uint16_t slaves[RTE_MAX_ETHPORTS];
3251 int i, burst_size, slave_count;
3253 memset(pkt_burst, 0, sizeof(pkt_burst));
3255 /* Initialize bonded device with 4 slaves in round robin mode */
3256 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3257 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3258 "Failed to initialise bonded device");
3260 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3261 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3262 "Failed to set balance xmit policy.");
3265 /* Verify Current Slaves Count /Active Slave Count is */
3266 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3268 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3269 "Number of slaves (%d) is not as expected (%d).",
3270 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3272 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3273 slaves, RTE_MAX_ETHPORTS);
3274 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3275 "Number of active slaves (%d) is not as expected (%d).",
3276 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3278 /* Set 2 slaves link status to down */
3279 virtual_ethdev_simulate_link_status_interrupt(
3280 test_params->slave_port_ids[1], 0);
3281 virtual_ethdev_simulate_link_status_interrupt(
3282 test_params->slave_port_ids[3], 0);
3284 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3285 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3286 "Number of active slaves (%d) is not as expected (%d).",
3289 /* Send to sets of packet burst and verify that they are balanced across
3293 TEST_ASSERT_EQUAL(generate_test_burst(
3294 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3295 "generate_test_burst failed");
3297 TEST_ASSERT_EQUAL(generate_test_burst(
3298 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3299 "generate_test_burst failed");
3301 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3302 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3303 burst_size, "rte_eth_tx_burst failed");
3305 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3306 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3307 burst_size, "rte_eth_tx_burst failed");
3310 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3311 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3312 "(%d) port_stats.opackets (%d) not as expected (%d).",
3313 test_params->bonded_port_id, (int)port_stats.opackets,
3314 burst_size + burst_size);
3316 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3317 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3318 "(%d) port_stats.opackets (%d) not as expected (%d).",
3319 test_params->slave_port_ids[0], (int)port_stats.opackets,
3322 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3323 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3324 "(%d) port_stats.opackets (%d) not as expected (%d).",
3325 test_params->slave_port_ids[2], (int)port_stats.opackets,
3328 /* verify that all packets get send on primary slave when no other slaves
3330 virtual_ethdev_simulate_link_status_interrupt(
3331 test_params->slave_port_ids[2], 0);
3333 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3334 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3335 "Number of active slaves (%d) is not as expected (%d).",
3338 TEST_ASSERT_EQUAL(generate_test_burst(
3339 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3340 "generate_test_burst failed");
3342 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3343 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3344 burst_size, "rte_eth_tx_burst failed");
3346 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3347 TEST_ASSERT_EQUAL(port_stats.opackets,
3348 (uint64_t)(burst_size + burst_size + burst_size),
3349 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3350 test_params->bonded_port_id, (int)port_stats.opackets,
3351 burst_size + burst_size + burst_size);
3353 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3354 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3355 "(%d) port_stats.opackets (%d) not as expected (%d).",
3356 test_params->slave_port_ids[0], (int)port_stats.opackets,
3357 burst_size + burst_size);
3359 virtual_ethdev_simulate_link_status_interrupt(
3360 test_params->slave_port_ids[0], 0);
3361 virtual_ethdev_simulate_link_status_interrupt(
3362 test_params->slave_port_ids[1], 1);
3363 virtual_ethdev_simulate_link_status_interrupt(
3364 test_params->slave_port_ids[2], 1);
3365 virtual_ethdev_simulate_link_status_interrupt(
3366 test_params->slave_port_ids[3], 1);
3368 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3369 TEST_ASSERT_EQUAL(generate_test_burst(
3370 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3371 "Failed to generate packet burst");
3373 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3374 &pkt_burst[i][0], burst_size);
3377 /* Verify that pkts are not received on slaves with link status down */
3379 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3382 /* Verify bonded device rx count */
3383 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3384 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3385 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3386 test_params->bonded_port_id, (int)port_stats.ipackets,
3389 /* Clean up and remove slaves from bonded device */
3390 return remove_slaves_and_stop_bonded_device();
3394 test_broadcast_tx_burst(void)
3396 int i, pktlen, burst_size;
3397 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3399 struct rte_eth_stats port_stats;
3401 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3402 BONDING_MODE_BROADCAST, 0, 2, 1),
3403 "Failed to initialise bonded device");
3405 initialize_eth_header(test_params->pkt_eth_hdr,
3406 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3407 ETHER_TYPE_IPv4, 0, 0);
3409 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3411 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3412 dst_addr_0, pktlen);
3414 burst_size = 20 * test_params->bonded_slave_count;
3416 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3417 "Burst size specified is greater than supported.");
3419 /* Generate a burst of packets to transmit */
3420 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3421 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3422 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3423 1), burst_size, "Failed to generate packet burst");
3425 /* Send burst on bonded port */
3426 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3427 pkts_burst, burst_size), burst_size,
3428 "Bonded Port (%d) rx burst failed, packets transmitted value "
3429 "not as expected (%d)",
3430 test_params->bonded_port_id, burst_size);
3432 /* Verify bonded port tx stats */
3433 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3434 TEST_ASSERT_EQUAL(port_stats.opackets,
3435 (uint64_t)burst_size * test_params->bonded_slave_count,
3436 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3437 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3440 /* Verify slave ports tx stats */
3441 for (i = 0; i < test_params->bonded_slave_count; i++) {
3442 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3443 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3444 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3445 test_params->bonded_port_id,
3446 (unsigned int)port_stats.opackets, burst_size);
3449 /* Put all slaves down and try and transmit */
3450 for (i = 0; i < test_params->bonded_slave_count; i++) {
3452 virtual_ethdev_simulate_link_status_interrupt(
3453 test_params->slave_port_ids[i], 0);
3456 /* Send burst on bonded port */
3457 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3458 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3459 "transmitted an unexpected number of packets");
3461 /* Clean up and remove slaves from bonded device */
3462 return remove_slaves_and_stop_bonded_device();
3466 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3467 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3468 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3469 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3472 test_broadcast_tx_burst_slave_tx_fail(void)
3474 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3475 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3477 struct rte_eth_stats port_stats;
3481 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3482 BONDING_MODE_BROADCAST, 0,
3483 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3484 "Failed to initialise bonded device");
3486 /* Generate test bursts for transmission */
3487 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3488 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3489 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3490 "Failed to generate test packet burst");
3492 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3493 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3494 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3497 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3498 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3499 virtual_ethdev_tx_burst_fn_set_success(
3500 test_params->slave_port_ids[0],
3502 virtual_ethdev_tx_burst_fn_set_success(
3503 test_params->slave_port_ids[1],
3505 virtual_ethdev_tx_burst_fn_set_success(
3506 test_params->slave_port_ids[2],
3509 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3510 test_params->slave_port_ids[0],
3511 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3513 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3514 test_params->slave_port_ids[1],
3515 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3517 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3518 test_params->slave_port_ids[2],
3519 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3521 /* Transmit burst */
3522 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3523 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3525 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3526 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3527 "Transmitted (%d) packets, expected to transmit (%d) packets",
3528 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3529 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3531 /* Verify that failed packet are expected failed packets */
3532 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3533 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3534 "expected mbuf (%d) pointer %p not expected pointer %p",
3535 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3538 /* Verify slave ports tx stats */
3540 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3542 TEST_ASSERT_EQUAL(port_stats.opackets,
3543 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3544 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3545 "Port (%d) opackets value (%u) not as expected (%d)",
3546 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3547 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3548 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3551 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3553 TEST_ASSERT_EQUAL(port_stats.opackets,
3554 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3555 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3556 "Port (%d) opackets value (%u) not as expected (%d)",
3557 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3558 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3559 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3561 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3563 TEST_ASSERT_EQUAL(port_stats.opackets,
3564 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3565 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3566 "Port (%d) opackets value (%u) not as expected (%d)",
3567 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3568 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3569 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3572 /* Verify that all mbufs who transmission failed have a ref value of one */
3573 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3574 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3575 "mbufs refcnts not as expected");
3577 free_mbufs(&pkts_burst[tx_count],
3578 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3580 /* Clean up and remove slaves from bonded device */
3581 return remove_slaves_and_stop_bonded_device();
3584 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3587 test_broadcast_rx_burst(void)
3589 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3591 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3592 struct rte_eth_stats port_stats;
3594 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3597 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3599 /* Initialize bonded device with 4 slaves in round robin mode */
3600 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3601 BONDING_MODE_BROADCAST, 0, 3, 1),
3602 "Failed to initialise bonded device");
3604 /* Generate test bursts of packets to transmit */
3605 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3606 TEST_ASSERT_EQUAL(generate_test_burst(
3607 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3608 burst_size[i], "failed to generate packet burst");
3611 /* Add rx data to slave 0 */
3612 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3613 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3614 &gen_pkt_burst[i][0], burst_size[i]);
3618 /* Call rx burst on bonded device */
3619 /* Send burst on bonded port */
3620 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3621 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3622 burst_size[0] + burst_size[1] + burst_size[2],
3625 /* Verify bonded device rx count */
3626 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3627 TEST_ASSERT_EQUAL(port_stats.ipackets,
3628 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3629 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3630 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3631 burst_size[0] + burst_size[1] + burst_size[2]);
3634 /* Verify bonded slave devices rx counts */
3635 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3636 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3637 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3638 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3641 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3642 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3643 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3644 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3647 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3648 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3649 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3650 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3653 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3654 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3655 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3656 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3659 /* free mbufs allocate for rx testing */
3660 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3661 for (j = 0; j < MAX_PKT_BURST; j++) {
3662 if (gen_pkt_burst[i][j] != NULL) {
3663 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3664 gen_pkt_burst[i][j] = NULL;
3669 /* Clean up and remove slaves from bonded device */
3670 return remove_slaves_and_stop_bonded_device();
3674 test_broadcast_verify_promiscuous_enable_disable(void)
3678 /* Initialize bonded device with 4 slaves in round robin mode */
3679 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3680 BONDING_MODE_BROADCAST, 0, 4, 1),
3681 "Failed to initialise bonded device");
3683 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3686 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3687 "Port (%d) promiscuous mode not enabled",
3688 test_params->bonded_port_id);
3690 for (i = 0; i < test_params->bonded_slave_count; i++) {
3691 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3692 test_params->slave_port_ids[i]), 1,
3693 "Port (%d) promiscuous mode not enabled",
3694 test_params->slave_port_ids[i]);
3697 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3699 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3700 "Port (%d) promiscuous mode not disabled",
3701 test_params->bonded_port_id);
3703 for (i = 0; i < test_params->bonded_slave_count; i++) {
3704 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3705 test_params->slave_port_ids[i]), 0,
3706 "Port (%d) promiscuous mode not disabled",
3707 test_params->slave_port_ids[i]);
3710 /* Clean up and remove slaves from bonded device */
3711 return remove_slaves_and_stop_bonded_device();
3715 test_broadcast_verify_mac_assignment(void)
3717 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3721 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3722 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3724 /* Initialize bonded device with 4 slaves in round robin mode */
3725 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3726 BONDING_MODE_BROADCAST, 0, 4, 1),
3727 "Failed to initialise bonded device");
3729 /* Verify that all MACs are the same as first slave added to bonded
3731 for (i = 0; i < test_params->bonded_slave_count; i++) {
3732 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3733 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3734 sizeof(read_mac_addr)),
3735 "slave port (%d) mac address not set to that of primary port",
3736 test_params->slave_port_ids[i]);
3739 /* change primary and verify that MAC addresses haven't changed */
3740 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3741 test_params->slave_port_ids[2]),
3742 "Failed to set bonded port (%d) primary port to (%d)",
3743 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3745 for (i = 0; i < test_params->bonded_slave_count; i++) {
3746 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3747 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3748 sizeof(read_mac_addr)),
3749 "slave port (%d) mac address has changed to that of primary "
3750 "port without stop/start toggle of bonded device",
3751 test_params->slave_port_ids[i]);
3754 /* stop / start bonded device and verify that primary MAC address is
3755 * propagated to bonded device and slaves */
3757 rte_eth_dev_stop(test_params->bonded_port_id);
3759 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3760 "Failed to start bonded device");
3762 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3763 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3764 sizeof(read_mac_addr)),
3765 "bonded port (%d) mac address not set to that of new primary port",
3766 test_params->slave_port_ids[i]);
3768 for (i = 0; i < test_params->bonded_slave_count; i++) {
3769 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3770 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3771 sizeof(read_mac_addr)),
3772 "slave port (%d) mac address not set to that of new primary "
3773 "port", test_params->slave_port_ids[i]);
3776 /* Set explicit MAC address */
3777 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3778 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3779 "Failed to set MAC address");
3781 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3782 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3783 sizeof(read_mac_addr)),
3784 "bonded port (%d) mac address not set to that of new primary port",
3785 test_params->slave_port_ids[i]);
3788 for (i = 0; i < test_params->bonded_slave_count; i++) {
3789 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3790 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3791 sizeof(read_mac_addr)),
3792 "slave port (%d) mac address not set to that of new primary "
3793 "port", test_params->slave_port_ids[i]);
3796 /* Clean up and remove slaves from bonded device */
3797 return remove_slaves_and_stop_bonded_device();
3800 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3802 test_broadcast_verify_slave_link_status_change_behaviour(void)
3804 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3805 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3806 struct rte_eth_stats port_stats;
3808 uint16_t slaves[RTE_MAX_ETHPORTS];
3810 int i, burst_size, slave_count;
3812 memset(pkt_burst, 0, sizeof(pkt_burst));
3814 /* Initialize bonded device with 4 slaves in round robin mode */
3815 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3816 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3817 1), "Failed to initialise bonded device");
3819 /* Verify Current Slaves Count /Active Slave Count is */
3820 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3822 TEST_ASSERT_EQUAL(slave_count, 4,
3823 "Number of slaves (%d) is not as expected (%d).",
3826 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3827 slaves, RTE_MAX_ETHPORTS);
3828 TEST_ASSERT_EQUAL(slave_count, 4,
3829 "Number of active slaves (%d) is not as expected (%d).",
3832 /* Set 2 slaves link status to down */
3833 virtual_ethdev_simulate_link_status_interrupt(
3834 test_params->slave_port_ids[1], 0);
3835 virtual_ethdev_simulate_link_status_interrupt(
3836 test_params->slave_port_ids[3], 0);
3838 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3839 slaves, RTE_MAX_ETHPORTS);
3840 TEST_ASSERT_EQUAL(slave_count, 2,
3841 "Number of active slaves (%d) is not as expected (%d).",
3844 for (i = 0; i < test_params->bonded_slave_count; i++)
3845 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3847 /* Verify that pkts are not sent on slaves with link status down */
3850 TEST_ASSERT_EQUAL(generate_test_burst(
3851 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3852 "generate_test_burst failed");
3854 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3855 &pkt_burst[0][0], burst_size), burst_size,
3856 "rte_eth_tx_burst failed\n");
3858 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3859 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3860 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3861 test_params->bonded_port_id, (int)port_stats.opackets,
3862 burst_size * slave_count);
3864 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3865 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3866 "(%d) port_stats.opackets not as expected",
3867 test_params->slave_port_ids[0]);
3869 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3870 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3871 "(%d) port_stats.opackets not as expected",
3872 test_params->slave_port_ids[1]);
3874 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3875 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3876 "(%d) port_stats.opackets not as expected",
3877 test_params->slave_port_ids[2]);
3880 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3881 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3882 "(%d) port_stats.opackets not as expected",
3883 test_params->slave_port_ids[3]);
3886 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3887 TEST_ASSERT_EQUAL(generate_test_burst(
3888 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3889 burst_size, "failed to generate packet burst");
3891 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3892 &pkt_burst[i][0], burst_size);
3895 /* Verify that pkts are not received on slaves with link status down */
3896 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3897 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3898 burst_size + burst_size, "rte_eth_rx_burst failed");
3901 /* Verify bonded device rx count */
3902 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3903 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3904 "(%d) port_stats.ipackets not as expected\n",
3905 test_params->bonded_port_id);
3907 /* Clean up and remove slaves from bonded device */
3908 return remove_slaves_and_stop_bonded_device();
3912 test_reconfigure_bonded_device(void)
3914 test_params->nb_rx_q = 4;
3915 test_params->nb_tx_q = 4;
3917 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3918 "failed to reconfigure bonded device");
3920 test_params->nb_rx_q = 2;
3921 test_params->nb_tx_q = 2;
3923 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3924 "failed to reconfigure bonded device with less rx/tx queues");
3931 test_close_bonded_device(void)
3933 rte_eth_dev_close(test_params->bonded_port_id);
3938 testsuite_teardown(void)
3940 free(test_params->pkt_eth_hdr);
3941 test_params->pkt_eth_hdr = NULL;
3943 /* Clean up and remove slaves from bonded device */
3944 remove_slaves_and_stop_bonded_device();
3948 free_virtualpmd_tx_queue(void)
3950 int i, slave_port, to_free_cnt;
3951 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
3953 /* Free tx queue of virtual pmd */
3954 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
3956 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
3957 test_params->slave_port_ids[slave_port],
3958 pkts_to_free, MAX_PKT_BURST);
3959 for (i = 0; i < to_free_cnt; i++)
3960 rte_pktmbuf_free(pkts_to_free[i]);
3965 test_tlb_tx_burst(void)
3967 int i, burst_size, nb_tx;
3968 uint64_t nb_tx2 = 0;
3969 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
3970 struct rte_eth_stats port_stats[32];
3971 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
3974 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
3975 (BONDING_MODE_TLB, 1, 3, 1),
3976 "Failed to initialise bonded device");
3978 burst_size = 20 * test_params->bonded_slave_count;
3980 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3981 "Burst size specified is greater than supported.\n");
3984 /* Generate bursts of packets */
3985 for (i = 0; i < 400000; i++) {
3986 /*test two types of mac src own(bonding) and others */
3988 initialize_eth_header(test_params->pkt_eth_hdr,
3989 (struct ether_addr *)src_mac,
3990 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
3992 initialize_eth_header(test_params->pkt_eth_hdr,
3993 (struct ether_addr *)test_params->default_slave_mac,
3994 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
3996 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3998 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3999 dst_addr_0, pktlen);
4000 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4001 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4002 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4003 /* Send burst on bonded port */
4004 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4008 free_virtualpmd_tx_queue();
4010 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4011 "number of packet not equal burst size");
4017 /* Verify bonded port tx stats */
4018 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4020 all_bond_opackets = port_stats[0].opackets;
4021 all_bond_obytes = port_stats[0].obytes;
4023 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4024 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4025 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4029 /* Verify slave ports tx stats */
4030 for (i = 0; i < test_params->bonded_slave_count; i++) {
4031 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4032 sum_ports_opackets += port_stats[i].opackets;
4035 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4036 "Total packets sent by slaves is not equal to packets sent by bond interface");
4038 /* checking if distribution of packets is balanced over slaves */
4039 for (i = 0; i < test_params->bonded_slave_count; i++) {
4040 TEST_ASSERT(port_stats[i].obytes > 0 &&
4041 port_stats[i].obytes < all_bond_obytes,
4042 "Packets are not balanced over slaves");
4045 /* Put all slaves down and try and transmit */
4046 for (i = 0; i < test_params->bonded_slave_count; i++) {
4047 virtual_ethdev_simulate_link_status_interrupt(
4048 test_params->slave_port_ids[i], 0);
4051 /* Send burst on bonded port */
4052 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4054 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4056 /* Clean ugit checkout masterp and remove slaves from bonded device */
4057 return remove_slaves_and_stop_bonded_device();
4060 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4063 test_tlb_rx_burst(void)
4065 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4066 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4068 struct rte_eth_stats port_stats;
4072 uint16_t i, j, nb_rx, burst_size = 17;
4074 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4075 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4077 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4078 "Failed to initialize bonded device");
4081 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4082 TEST_ASSERT(primary_port >= 0,
4083 "failed to get primary slave for bonded port (%d)",
4084 test_params->bonded_port_id);
4086 for (i = 0; i < test_params->bonded_slave_count; i++) {
4087 /* Generate test bursts of packets to transmit */
4088 TEST_ASSERT_EQUAL(generate_test_burst(
4089 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4090 "burst generation failed");
4092 /* Add rx data to slave */
4093 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4094 &gen_pkt_burst[0], burst_size);
4096 /* Call rx burst on bonded device */
4097 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4098 &rx_pkt_burst[0], MAX_PKT_BURST);
4100 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4102 if (test_params->slave_port_ids[i] == primary_port) {
4103 /* Verify bonded device rx count */
4104 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4105 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4106 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4107 test_params->bonded_port_id,
4108 (unsigned int)port_stats.ipackets, burst_size);
4110 /* Verify bonded slave devices rx count */
4111 for (j = 0; j < test_params->bonded_slave_count; j++) {
4112 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4114 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4115 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4116 test_params->slave_port_ids[i],
4117 (unsigned int)port_stats.ipackets, burst_size);
4119 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4120 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4121 test_params->slave_port_ids[i],
4122 (unsigned int)port_stats.ipackets, 0);
4126 for (j = 0; j < test_params->bonded_slave_count; j++) {
4127 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4128 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4129 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4130 test_params->slave_port_ids[i],
4131 (unsigned int)port_stats.ipackets, 0);
4136 for (i = 0; i < burst_size; i++)
4137 rte_pktmbuf_free(rx_pkt_burst[i]);
4139 /* reset bonded device stats */
4140 rte_eth_stats_reset(test_params->bonded_port_id);
4143 /* Clean up and remove slaves from bonded device */
4144 return remove_slaves_and_stop_bonded_device();
4148 test_tlb_verify_promiscuous_enable_disable(void)
4150 int i, primary_port, promiscuous_en;
4152 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4153 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4154 BONDING_MODE_TLB, 0, 4, 1),
4155 "Failed to initialize bonded device");
4157 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4158 TEST_ASSERT(primary_port >= 0,
4159 "failed to get primary slave for bonded port (%d)",
4160 test_params->bonded_port_id);
4162 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4164 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4165 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4166 "Port (%d) promiscuous mode not enabled\n",
4167 test_params->bonded_port_id);
4168 for (i = 0; i < test_params->bonded_slave_count; i++) {
4169 promiscuous_en = rte_eth_promiscuous_get(
4170 test_params->slave_port_ids[i]);
4171 if (primary_port == test_params->slave_port_ids[i]) {
4172 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4173 "Port (%d) promiscuous mode not enabled\n",
4174 test_params->bonded_port_id);
4176 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4177 "Port (%d) promiscuous mode enabled\n",
4178 test_params->bonded_port_id);
4183 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4185 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4186 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4187 "Port (%d) promiscuous mode not disabled\n",
4188 test_params->bonded_port_id);
4190 for (i = 0; i < test_params->bonded_slave_count; i++) {
4191 promiscuous_en = rte_eth_promiscuous_get(
4192 test_params->slave_port_ids[i]);
4193 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4194 "slave port (%d) promiscuous mode not disabled\n",
4195 test_params->slave_port_ids[i]);
4198 /* Clean up and remove slaves from bonded device */
4199 return remove_slaves_and_stop_bonded_device();
4203 test_tlb_verify_mac_assignment(void)
4205 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4207 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4208 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4210 /* Initialize bonded device with 2 slaves in active backup mode */
4211 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4212 BONDING_MODE_TLB, 0, 2, 1),
4213 "Failed to initialize bonded device");
4215 /* Verify that bonded MACs is that of first slave and that the other slave
4216 * MAC hasn't been changed */
4217 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4218 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4219 sizeof(read_mac_addr)),
4220 "bonded port (%d) mac address not set to that of primary port",
4221 test_params->bonded_port_id);
4223 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4224 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4225 sizeof(read_mac_addr)),
4226 "slave port (%d) mac address not set to that of primary port",
4227 test_params->slave_port_ids[0]);
4229 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4230 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4231 sizeof(read_mac_addr)),
4232 "slave port (%d) mac address not as expected",
4233 test_params->slave_port_ids[1]);
4235 /* change primary and verify that MAC addresses haven't changed */
4236 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4237 test_params->slave_port_ids[1]), 0,
4238 "Failed to set bonded port (%d) primary port to (%d)",
4239 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4241 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4242 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4243 sizeof(read_mac_addr)),
4244 "bonded port (%d) mac address not set to that of primary port",
4245 test_params->bonded_port_id);
4247 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4248 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4249 sizeof(read_mac_addr)),
4250 "slave port (%d) mac address not set to that of primary port",
4251 test_params->slave_port_ids[0]);
4253 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4254 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4255 sizeof(read_mac_addr)),
4256 "slave port (%d) mac address not as expected",
4257 test_params->slave_port_ids[1]);
4259 /* stop / start bonded device and verify that primary MAC address is
4260 * propagated to bonded device and slaves */
4262 rte_eth_dev_stop(test_params->bonded_port_id);
4264 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4265 "Failed to start device");
4267 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4268 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4269 sizeof(read_mac_addr)),
4270 "bonded port (%d) mac address not set to that of primary port",
4271 test_params->bonded_port_id);
4273 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4274 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4275 sizeof(read_mac_addr)),
4276 "slave port (%d) mac address not as expected",
4277 test_params->slave_port_ids[0]);
4279 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4280 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4281 sizeof(read_mac_addr)),
4282 "slave port (%d) mac address not set to that of primary port",
4283 test_params->slave_port_ids[1]);
4286 /* Set explicit MAC address */
4287 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4288 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4289 "failed to set MAC address");
4291 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4292 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4293 sizeof(read_mac_addr)),
4294 "bonded port (%d) mac address not set to that of bonded port",
4295 test_params->bonded_port_id);
4297 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4298 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4299 sizeof(read_mac_addr)),
4300 "slave port (%d) mac address not as expected",
4301 test_params->slave_port_ids[0]);
4303 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4304 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4305 sizeof(read_mac_addr)),
4306 "slave port (%d) mac address not set to that of bonded port",
4307 test_params->slave_port_ids[1]);
4309 /* Clean up and remove slaves from bonded device */
4310 return remove_slaves_and_stop_bonded_device();
4314 test_tlb_verify_slave_link_status_change_failover(void)
4316 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4317 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4318 struct rte_eth_stats port_stats;
4320 uint16_t slaves[RTE_MAX_ETHPORTS];
4322 int i, burst_size, slave_count, primary_port;
4326 memset(pkt_burst, 0, sizeof(pkt_burst));
4330 /* Initialize bonded device with 4 slaves in round robin mode */
4331 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4332 BONDING_MODE_TLB, 0,
4333 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4334 "Failed to initialize bonded device with slaves");
4336 /* Verify Current Slaves Count /Active Slave Count is */
4337 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4339 TEST_ASSERT_EQUAL(slave_count, 4,
4340 "Number of slaves (%d) is not as expected (%d).\n",
4343 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4344 slaves, RTE_MAX_ETHPORTS);
4345 TEST_ASSERT_EQUAL(slave_count, (int)4,
4346 "Number of slaves (%d) is not as expected (%d).\n",
4349 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4350 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4351 "Primary port not as expected");
4353 /* Bring 2 slaves down and verify active slave count */
4354 virtual_ethdev_simulate_link_status_interrupt(
4355 test_params->slave_port_ids[1], 0);
4356 virtual_ethdev_simulate_link_status_interrupt(
4357 test_params->slave_port_ids[3], 0);
4359 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4360 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4361 "Number of active slaves (%d) is not as expected (%d).",
4364 virtual_ethdev_simulate_link_status_interrupt(
4365 test_params->slave_port_ids[1], 1);
4366 virtual_ethdev_simulate_link_status_interrupt(
4367 test_params->slave_port_ids[3], 1);
4370 /* Bring primary port down, verify that active slave count is 3 and primary
4372 virtual_ethdev_simulate_link_status_interrupt(
4373 test_params->slave_port_ids[0], 0);
4375 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4376 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4377 "Number of active slaves (%d) is not as expected (%d).",
4380 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4381 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4382 "Primary port not as expected");
4383 rte_delay_us(500000);
4384 /* Verify that pkts are sent on new primary slave */
4385 for (i = 0; i < 4; i++) {
4386 TEST_ASSERT_EQUAL(generate_test_burst(
4387 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4388 "generate_test_burst failed\n");
4389 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4390 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4391 "rte_eth_tx_burst failed\n");
4392 rte_delay_us(11000);
4395 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4396 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4397 "(%d) port_stats.opackets not as expected\n",
4398 test_params->slave_port_ids[0]);
4400 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4401 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4402 "(%d) port_stats.opackets not as expected\n",
4403 test_params->slave_port_ids[1]);
4405 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4406 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4407 "(%d) port_stats.opackets not as expected\n",
4408 test_params->slave_port_ids[2]);
4410 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4411 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4412 "(%d) port_stats.opackets not as expected\n",
4413 test_params->slave_port_ids[3]);
4416 /* Generate packet burst for testing */
4418 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4419 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4423 virtual_ethdev_add_mbufs_to_rx_queue(
4424 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4427 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4428 MAX_PKT_BURST) != burst_size) {
4429 printf("rte_eth_rx_burst\n");
4434 /* Verify bonded device rx count */
4435 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4436 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4437 "(%d) port_stats.ipackets not as expected\n",
4438 test_params->bonded_port_id);
4440 /* Clean up and remove slaves from bonded device */
4441 return remove_slaves_and_stop_bonded_device();
4444 #define TEST_ALB_SLAVE_COUNT 2
4446 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4447 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4448 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4449 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4451 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4452 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4453 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4454 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4455 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4458 test_alb_change_mac_in_reply_sent(void)
4460 struct rte_mbuf *pkt;
4461 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4463 struct ether_hdr *eth_pkt;
4464 struct arp_hdr *arp_pkt;
4466 int slave_idx, nb_pkts, pkt_idx;
4469 struct ether_addr bond_mac, client_mac;
4470 struct ether_addr *slave_mac1, *slave_mac2;
4472 TEST_ASSERT_SUCCESS(
4473 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4474 0, TEST_ALB_SLAVE_COUNT, 1),
4475 "Failed to initialize_bonded_device_with_slaves.");
4477 /* Flush tx queue */
4478 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4479 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4481 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4482 test_params->slave_port_ids[slave_idx], pkts_sent,
4487 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4491 * Generating four packets with different mac and ip addresses and sending
4492 * them through the bonding port.
4494 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4495 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4496 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4497 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4499 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4500 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4502 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4504 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4505 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4506 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4507 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4509 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4510 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4512 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4514 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4515 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4516 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4517 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4519 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4520 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4522 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4524 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4525 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4526 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4527 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4529 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4530 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4532 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4535 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4537 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4540 * Checking if packets are properly distributed on bonding ports. Packets
4541 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4543 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4544 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4545 test_params->slave_port_ids[slave_idx], pkts_sent,
4548 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4549 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4550 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4552 if (slave_idx%2 == 0) {
4553 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4558 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4567 retval += remove_slaves_and_stop_bonded_device();
4572 test_alb_reply_from_client(void)
4574 struct ether_hdr *eth_pkt;
4575 struct arp_hdr *arp_pkt;
4577 struct rte_mbuf *pkt;
4578 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4580 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4583 struct ether_addr bond_mac, client_mac;
4584 struct ether_addr *slave_mac1, *slave_mac2;
4586 TEST_ASSERT_SUCCESS(
4587 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4588 0, TEST_ALB_SLAVE_COUNT, 1),
4589 "Failed to initialize_bonded_device_with_slaves.");
4591 /* Flush tx queue */
4592 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4593 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4594 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4595 test_params->slave_port_ids[slave_idx], pkts_sent,
4600 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4604 * Generating four packets with different mac and ip addresses and placing
4605 * them in the rx queue to be received by the bonding driver on rx_burst.
4607 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4608 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4609 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4610 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4612 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4613 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4615 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4618 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4619 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4620 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4621 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4623 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4624 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4626 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4629 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4630 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4631 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4632 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4634 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4635 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4637 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4640 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4641 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4642 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4643 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4645 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4646 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4648 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4652 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4653 * packets to every client in alb table.
4655 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4656 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4658 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4659 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4662 * Checking if update ARP packets were properly send on slave ports.
4664 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4665 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4666 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4667 nb_pkts_sum += nb_pkts;
4669 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4670 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4671 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4673 if (slave_idx%2 == 0) {
4674 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4679 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4687 /* Check if proper number of packets was send */
4688 if (nb_pkts_sum < 4) {
4694 retval += remove_slaves_and_stop_bonded_device();
4699 test_alb_receive_vlan_reply(void)
4701 struct ether_hdr *eth_pkt;
4702 struct vlan_hdr *vlan_pkt;
4703 struct arp_hdr *arp_pkt;
4705 struct rte_mbuf *pkt;
4706 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4708 int slave_idx, nb_pkts, pkt_idx;
4711 struct ether_addr bond_mac, client_mac;
4713 TEST_ASSERT_SUCCESS(
4714 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4715 0, TEST_ALB_SLAVE_COUNT, 1),
4716 "Failed to initialize_bonded_device_with_slaves.");
4718 /* Flush tx queue */
4719 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4720 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4721 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4722 test_params->slave_port_ids[slave_idx], pkts_sent,
4727 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4731 * Generating packet with double VLAN header and placing it in the rx queue.
4733 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4734 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4735 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4736 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4738 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4739 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4740 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4741 vlan_pkt = vlan_pkt+1;
4742 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4743 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4744 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4745 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4747 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4750 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4751 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4754 * Checking if VLAN headers in generated ARP Update packet are correct.
4756 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4757 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4758 test_params->slave_port_ids[slave_idx], pkts_sent,
4761 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4762 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4763 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4764 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4768 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4772 vlan_pkt = vlan_pkt+1;
4773 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4777 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4785 retval += remove_slaves_and_stop_bonded_device();
4790 test_alb_ipv4_tx(void)
4792 int burst_size, retval, pkts_send;
4793 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4797 TEST_ASSERT_SUCCESS(
4798 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4799 0, TEST_ALB_SLAVE_COUNT, 1),
4800 "Failed to initialize_bonded_device_with_slaves.");
4804 /* Generate test bursts of packets to transmit */
4805 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4811 * Checking if ipv4 traffic is transmitted via TLB policy.
4813 pkts_send = rte_eth_tx_burst(
4814 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4815 if (pkts_send != burst_size) {
4821 retval += remove_slaves_and_stop_bonded_device();
4825 static struct unit_test_suite link_bonding_test_suite = {
4826 .suite_name = "Link Bonding Unit Test Suite",
4827 .setup = test_setup,
4828 .teardown = testsuite_teardown,
4829 .unit_test_cases = {
4830 TEST_CASE(test_create_bonded_device),
4831 TEST_CASE(test_create_bonded_device_with_invalid_params),
4832 TEST_CASE(test_add_slave_to_bonded_device),
4833 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4834 TEST_CASE(test_remove_slave_from_bonded_device),
4835 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4836 TEST_CASE(test_get_slaves_from_bonded_device),
4837 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4838 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4839 TEST_CASE(test_start_bonded_device),
4840 TEST_CASE(test_stop_bonded_device),
4841 TEST_CASE(test_set_bonding_mode),
4842 TEST_CASE(test_set_primary_slave),
4843 TEST_CASE(test_set_explicit_bonded_mac),
4844 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4845 TEST_CASE(test_status_interrupt),
4846 TEST_CASE(test_adding_slave_after_bonded_device_started),
4847 TEST_CASE(test_roundrobin_tx_burst),
4848 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4849 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4850 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4851 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4852 TEST_CASE(test_roundrobin_verify_mac_assignment),
4853 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4854 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4855 TEST_CASE(test_activebackup_tx_burst),
4856 TEST_CASE(test_activebackup_rx_burst),
4857 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4858 TEST_CASE(test_activebackup_verify_mac_assignment),
4859 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4860 TEST_CASE(test_balance_xmit_policy_configuration),
4861 TEST_CASE(test_balance_l2_tx_burst),
4862 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4863 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4864 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4865 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4866 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4867 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4868 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4869 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4870 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4871 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4872 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4873 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4874 TEST_CASE(test_balance_rx_burst),
4875 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4876 TEST_CASE(test_balance_verify_mac_assignment),
4877 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4878 TEST_CASE(test_tlb_tx_burst),
4879 TEST_CASE(test_tlb_rx_burst),
4880 TEST_CASE(test_tlb_verify_mac_assignment),
4881 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4882 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4883 TEST_CASE(test_alb_change_mac_in_reply_sent),
4884 TEST_CASE(test_alb_reply_from_client),
4885 TEST_CASE(test_alb_receive_vlan_reply),
4886 TEST_CASE(test_alb_ipv4_tx),
4887 TEST_CASE(test_broadcast_tx_burst),
4888 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4889 TEST_CASE(test_broadcast_rx_burst),
4890 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4891 TEST_CASE(test_broadcast_verify_mac_assignment),
4892 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4893 TEST_CASE(test_reconfigure_bonded_device),
4894 TEST_CASE(test_close_bonded_device),
4896 TEST_CASES_END() /**< NULL terminate unit test array */
4902 test_link_bonding(void)
4904 return unit_test_suite_runner(&link_bonding_test_suite);
4907 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);