4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include <sys/queue.h>
44 #include <rte_byteorder.h>
45 #include <rte_common.h>
46 #include <rte_debug.h>
47 #include <rte_ethdev.h>
49 #include <rte_lcore.h>
50 #include <rte_memory.h>
51 #include <rte_string_fns.h>
52 #include <rte_eth_bond.h>
54 #include "virtual_pmd.h"
55 #include "packet_burst_generator.h"
59 #define TEST_MAX_NUMBER_OF_PORTS (16)
61 #define RX_RING_SIZE 128
62 #define RX_FREE_THRESH 32
67 #define TX_RING_SIZE 512
68 #define TX_FREE_THRESH 32
72 #define TX_RSBIT_THRESH 32
73 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
74 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
75 ETH_TXQ_FLAGS_NOXSUMTCP)
77 #define MBUF_PAYLOAD_SIZE (2048)
78 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
79 #define MBUF_CACHE_SIZE (250)
80 #define BURST_SIZE (32)
82 #define DEFAULT_MBUF_DATA_SIZE (2048)
83 #define RTE_TEST_RX_DESC_MAX (2048)
84 #define RTE_TEST_TX_DESC_MAX (2048)
85 #define MAX_PKT_BURST (512)
86 #define DEF_PKT_BURST (16)
88 #define BONDED_DEV_NAME ("unit_test_bonded_device")
90 #define INVALID_SOCKET_ID (-1)
91 #define INVALID_PORT_ID (-1)
92 #define INVALID_BONDING_MODE (-1)
95 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
96 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
98 struct link_bonding_unittest_params {
99 int8_t bonded_port_id;
100 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
101 uint8_t bonded_slave_count;
102 uint8_t bonding_mode;
107 struct rte_mempool *mbuf_pool;
109 struct ether_addr *default_slave_mac;
110 struct ether_addr *default_bonded_mac;
113 struct ether_hdr *pkt_eth_hdr;
114 struct ipv4_hdr *pkt_ipv4_hdr;
115 struct ipv6_hdr *pkt_ipv6_hdr;
116 struct udp_hdr *pkt_udp_hdr;
120 static struct ipv4_hdr pkt_ipv4_hdr;
121 static struct ipv6_hdr pkt_ipv6_hdr;
122 static struct udp_hdr pkt_udp_hdr;
124 static struct link_bonding_unittest_params default_params = {
125 .bonded_port_id = -1,
126 .slave_port_ids = { -1 },
127 .bonded_slave_count = 0,
128 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
135 .default_slave_mac = (struct ether_addr *)slave_mac,
136 .default_bonded_mac = (struct ether_addr *)bonded_mac,
139 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
140 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
141 .pkt_udp_hdr = &pkt_udp_hdr
145 static struct link_bonding_unittest_params *test_params = &default_params;
147 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
148 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
151 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
152 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
155 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
156 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
157 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
158 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
159 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
160 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
162 static uint16_t src_port = 1024;
163 static uint16_t dst_port_0 = 1024;
164 static uint16_t dst_port_1 = 2024;
166 static uint16_t vlan_id = 0x100;
168 struct rte_eth_rxmode rx_mode = {
169 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
171 .header_split = 0, /**< Header Split disabled. */
172 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
173 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
174 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
175 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
176 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
177 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
180 struct rte_fdir_conf fdir_conf = {
181 .mode = RTE_FDIR_MODE_NONE,
182 .pballoc = RTE_FDIR_PBALLOC_64K,
183 .status = RTE_FDIR_REPORT_STATUS,
184 .flexbytes_offset = 0x6,
188 static struct rte_eth_conf default_pmd_conf = {
190 .mq_mode = ETH_MQ_RX_NONE,
191 .max_rx_pkt_len = ETHER_MAX_LEN,
193 .header_split = 0, /**< Header Split disabled */
194 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
195 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
196 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
197 .hw_strip_crc = 0, /**< CRC stripped by hardware */
200 .mq_mode = ETH_MQ_TX_NONE,
205 static const struct rte_eth_rxconf rx_conf_default = {
207 .pthresh = RX_PTHRESH,
208 .hthresh = RX_HTHRESH,
209 .wthresh = RX_WTHRESH,
211 .rx_free_thresh = RX_FREE_THRESH,
215 static struct rte_eth_txconf tx_conf_default = {
217 .pthresh = TX_PTHRESH,
218 .hthresh = TX_HTHRESH,
219 .wthresh = TX_WTHRESH,
221 .tx_free_thresh = TX_FREE_THRESH,
222 .tx_rs_thresh = TX_RSBIT_THRESH,
223 .txq_flags = TX_Q_FLAGS
228 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
233 default_pmd_conf.intr_conf.lsc = 1;
235 default_pmd_conf.intr_conf.lsc = 0;
237 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
238 test_params->nb_tx_q, &default_pmd_conf),
239 "rte_eth_dev_configure for port %d failed", port_id);
241 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
242 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
243 rte_eth_dev_socket_id(port_id), &rx_conf_default,
244 test_params->mbuf_pool) ,
245 "rte_eth_rx_queue_setup for port %d failed", port_id);
247 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
248 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
249 rte_eth_dev_socket_id(port_id), &tx_conf_default),
250 "rte_eth_tx_queue_setup for port %d failed", port_id);
253 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
254 "rte_eth_dev_start for port %d failed", port_id);
259 static int slaves_initialized;
261 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
262 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
268 int i, retval, nb_mbuf_per_pool;
269 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
271 /* Allocate ethernet packet header with space for VLAN header */
272 if (test_params->pkt_eth_hdr == NULL) {
273 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
274 sizeof(struct vlan_hdr));
276 if (test_params->pkt_eth_hdr == NULL) {
277 printf("ethernet header struct allocation failed!\n");
282 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
283 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
284 if (test_params->mbuf_pool == NULL) {
285 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
286 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
287 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
289 if (test_params->mbuf_pool == NULL) {
290 printf("rte_mempool_create failed\n");
295 /* Create / Initialize virtual eth devs */
296 if (!slaves_initialized) {
297 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
298 char pmd_name[RTE_ETH_NAME_MAX_LEN];
300 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
302 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
304 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
305 mac_addr, rte_socket_id(), 1);
306 if (test_params->slave_port_ids[i] < 0) {
307 printf("Failed to create virtual virtual ethdev %s\n", pmd_name);
311 printf("Created virtual ethdev %s\n", pmd_name);
313 retval = configure_ethdev(test_params->slave_port_ids[i], 1, 0);
315 printf("Failed to configure virtual ethdev %s\n", pmd_name);
319 printf("Configured virtual ethdev %s\n", pmd_name);
321 slaves_initialized = 1;
328 test_create_bonded_device(void)
330 int current_slave_count;
332 uint8_t slaves[RTE_MAX_ETHPORTS];
334 /* Don't try to recreate bonded device if re-running test suite*/
335 if (test_params->bonded_port_id == -1) {
336 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
337 test_params->bonding_mode, rte_socket_id());
339 TEST_ASSERT(test_params->bonded_port_id >= 0,
340 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
342 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
343 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
346 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
347 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
348 test_params->bonded_port_id, test_params->bonding_mode);
350 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
351 slaves, RTE_MAX_ETHPORTS);
353 TEST_ASSERT(current_slave_count == 0,
354 "Number of slaves %d is great than expected %d.",
355 current_slave_count, 0);
357 current_slave_count = rte_eth_bond_active_slaves_get(
358 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
360 TEST_ASSERT(current_slave_count == 0,
361 "Number of active slaves %d is great than expected %d.",
362 current_slave_count, 0);
369 test_create_bonded_device_with_invalid_params(void)
373 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
376 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
379 printf("Created bonded device unexpectedly.\n");
383 test_params->bonding_mode = INVALID_BONDING_MODE;
385 /* Invalid bonding mode */
386 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
389 printf("Created bonded device unexpectedly.\n");
393 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
395 /* Invalid socket id */
396 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
399 printf("Created bonded device unexpectedly.\n");
407 test_add_slave_to_bonded_device(void)
409 int current_slave_count;
411 uint8_t slaves[RTE_MAX_ETHPORTS];
413 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
414 test_params->slave_port_ids[test_params->bonded_slave_count]),
415 "Failed to add slave (%d) to bonded port (%d).",
416 test_params->slave_port_ids[test_params->bonded_slave_count],
417 test_params->bonded_port_id);
419 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
420 slaves, RTE_MAX_ETHPORTS);
421 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
422 "Number of slaves (%d) is greater than expected (%d).",
423 current_slave_count, test_params->bonded_slave_count + 1);
425 current_slave_count = rte_eth_bond_active_slaves_get(
426 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
427 TEST_ASSERT_EQUAL(current_slave_count, 0,
428 "Number of active slaves (%d) is not as expected (%d).\n",
429 current_slave_count, 0);
431 test_params->bonded_slave_count++;
437 test_add_slave_to_invalid_bonded_device(void)
441 /* Invalid port ID */
442 retval = rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
443 test_params->slave_port_ids[test_params->bonded_slave_count]);
445 printf("Expected call to failed as invalid port specified.\n");
449 /* Non bonded device */
450 retval = rte_eth_bond_slave_add(test_params->slave_port_ids[0],
451 test_params->slave_port_ids[test_params->bonded_slave_count]);
453 printf("Expected call to failed as invalid port specified.\n");
462 test_remove_slave_from_bonded_device(void)
464 int current_slave_count;
465 struct ether_addr read_mac_addr, *mac_addr;
466 uint8_t slaves[RTE_MAX_ETHPORTS];
468 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
469 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
470 "Failed to remove slave %d from bonded port (%d).",
471 test_params->slave_port_ids[test_params->bonded_slave_count-1],
472 test_params->bonded_port_id);
475 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
476 slaves, RTE_MAX_ETHPORTS);
478 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
479 "Number of slaves (%d) is great than expected (%d).\n",
480 current_slave_count, test_params->bonded_slave_count - 1);
483 mac_addr = (struct ether_addr *)slave_mac;
484 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
485 test_params->slave_port_ids[test_params->bonded_slave_count-1];
488 test_params->slave_port_ids[test_params->bonded_slave_count-1],
490 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
491 "bonded port mac address not set to that of primary port\n");
494 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
496 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
499 test_params->bonded_slave_count--;
505 test_remove_slave_from_invalid_bonded_device(void)
509 /* Invalid port ID */
510 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id + 5,
511 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
513 printf("Expected call to failed as invalid port specified.\n");
517 /* Non bonded device */
518 retval = rte_eth_bond_slave_remove(test_params->slave_port_ids[0],
519 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
521 printf("Expected call to failed as invalid port specified.\n");
528 static int bonded_id = 2;
531 test_add_already_bonded_slave_to_bonded_device(void)
533 int retval, port_id, current_slave_count;
534 uint8_t slaves[RTE_MAX_ETHPORTS];
535 char pmd_name[RTE_ETH_NAME_MAX_LEN];
537 test_add_slave_to_bonded_device();
539 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
540 slaves, RTE_MAX_ETHPORTS);
541 if (current_slave_count != 1) {
542 printf("Number of slaves (%d) is not that expected (%d).\n",
543 current_slave_count, 1);
547 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
549 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
552 printf("Failed to create bonded device.\n");
556 retval = rte_eth_bond_slave_add(port_id,
557 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
559 printf("Added slave (%d) to bonded port (%d) unexpectedly.\n",
560 test_params->slave_port_ids[test_params->bonded_slave_count-1],
565 return test_remove_slave_from_bonded_device();
570 test_get_slaves_from_bonded_device(void)
572 int retval, current_slave_count;
574 uint8_t slaves[RTE_MAX_ETHPORTS];
576 retval = test_add_slave_to_bonded_device();
580 /* Invalid port id */
581 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
583 if (current_slave_count >= 0)
586 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
587 slaves, RTE_MAX_ETHPORTS);
588 if (current_slave_count >= 0)
591 /* Invalid slaves pointer */
592 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
593 NULL, RTE_MAX_ETHPORTS);
594 if (current_slave_count >= 0)
597 current_slave_count = rte_eth_bond_active_slaves_get(
598 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
599 if (current_slave_count >= 0)
602 /* non bonded device*/
603 current_slave_count = rte_eth_bond_slaves_get(
604 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
605 if (current_slave_count >= 0)
608 current_slave_count = rte_eth_bond_active_slaves_get(
609 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
610 if (current_slave_count >= 0)
613 retval = test_remove_slave_from_bonded_device();
622 test_add_remove_multiple_slaves_to_from_bonded_device(void)
626 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
627 if (test_add_slave_to_bonded_device() != 0)
631 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
632 if (test_remove_slave_from_bonded_device() != 0)
640 enable_bonded_slaves(void)
644 for (i = 0; i < test_params->bonded_slave_count; i++) {
645 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
648 virtual_ethdev_simulate_link_status_interrupt(
649 test_params->slave_port_ids[i], 1);
654 test_start_bonded_device(void)
656 struct rte_eth_link link_status;
658 int current_slave_count, current_bonding_mode, primary_port;
659 uint8_t slaves[RTE_MAX_ETHPORTS];
661 /* Add slave to bonded device*/
662 if (test_add_slave_to_bonded_device() != 0)
665 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
666 "Failed to start bonded pmd eth device %d.",
667 test_params->bonded_port_id);
669 /* Change link status of virtual pmd so it will be added to the active
670 * slave list of the bonded device*/
671 virtual_ethdev_simulate_link_status_interrupt(
672 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
674 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
675 slaves, RTE_MAX_ETHPORTS);
676 if (current_slave_count != test_params->bonded_slave_count) {
677 printf("Number of slaves (%d) is not expected value (%d).\n",
678 current_slave_count, test_params->bonded_slave_count);
682 current_slave_count = rte_eth_bond_active_slaves_get(
683 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
684 if (current_slave_count != test_params->bonded_slave_count) {
685 printf("Number of active slaves (%d) is not expected value (%d).\n",
686 current_slave_count, test_params->bonded_slave_count);
690 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
691 if (current_bonding_mode != test_params->bonding_mode) {
692 printf("Bonded device mode (%d) is not expected value (%d).\n",
693 current_bonding_mode, test_params->bonding_mode);
698 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
699 if (primary_port != test_params->slave_port_ids[0]) {
700 printf("Primary port (%d) is not expected value (%d).\n",
701 primary_port, test_params->slave_port_ids[0]);
706 rte_eth_link_get(test_params->bonded_port_id, &link_status);
707 if (!link_status.link_status) {
708 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
709 test_params->bonded_port_id, link_status.link_status, 1);
718 test_stop_bonded_device(void)
720 int current_slave_count;
721 uint8_t slaves[RTE_MAX_ETHPORTS];
723 struct rte_eth_link link_status;
725 rte_eth_dev_stop(test_params->bonded_port_id);
727 rte_eth_link_get(test_params->bonded_port_id, &link_status);
728 if (link_status.link_status) {
729 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
730 test_params->bonded_port_id, link_status.link_status, 0);
734 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
735 slaves, RTE_MAX_ETHPORTS);
736 if (current_slave_count != test_params->bonded_slave_count) {
737 printf("Number of slaves (%d) is not expected value (%d).\n",
738 current_slave_count, test_params->bonded_slave_count);
742 current_slave_count = rte_eth_bond_active_slaves_get(
743 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
744 if (current_slave_count != 0) {
745 printf("Number of active slaves (%d) is not expected value (%d).\n",
746 current_slave_count, 0);
753 static int remove_slaves_and_stop_bonded_device(void)
755 /* Clean up and remove slaves from bonded device */
756 while (test_params->bonded_slave_count > 0) {
757 if (test_remove_slave_from_bonded_device() != 0) {
758 printf("test_remove_slave_from_bonded_device failed\n");
763 rte_eth_dev_stop(test_params->bonded_port_id);
764 rte_eth_stats_reset(test_params->bonded_port_id);
765 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
771 test_set_bonding_mode(void)
774 int retval, bonding_mode;
776 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
777 BONDING_MODE_ACTIVE_BACKUP,
778 BONDING_MODE_BALANCE,
779 #ifdef RTE_MBUF_REFCNT
780 BONDING_MODE_BROADCAST
784 /* Test supported link bonding modes */
785 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
786 /* Invalid port ID */
787 retval = rte_eth_bond_mode_set(INVALID_PORT_ID, bonding_modes[i]);
789 printf("Expected call to failed as invalid port (%d) specified.\n",
794 /* Non bonded device */
795 retval = rte_eth_bond_mode_set(test_params->slave_port_ids[0],
798 printf("Expected call to failed as invalid port (%d) specified.\n",
799 test_params->slave_port_ids[0]);
803 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
806 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
807 test_params->bonded_port_id, bonding_modes[i]);
811 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
812 if (bonding_mode != bonding_modes[i]) {
813 printf("Link bonding mode (%d) of port (%d) is not expected value (%d).\n",
814 bonding_mode, test_params->bonded_port_id,
820 /* Invalid port ID */
821 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
822 if (bonding_mode >= 0) {
823 printf("Expected call to failed as invalid port (%d) specified.\n",
829 /* Non bonded device */
830 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
831 if (bonding_mode >= 0) {
832 printf("Expected call to failed as invalid port (%d) specified.\n",
833 test_params->slave_port_ids[0]);
839 return remove_slaves_and_stop_bonded_device();
843 test_set_primary_slave(void)
846 struct ether_addr read_mac_addr;
847 struct ether_addr *expected_mac_addr;
849 /* Add 4 slaves to bonded device */
850 for (i = test_params->bonded_slave_count; i < 4; i++) {
851 retval = test_add_slave_to_bonded_device();
853 printf("Failed to add slave to bonded device.\n");
857 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
858 BONDING_MODE_ROUND_ROBIN);
860 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
861 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
865 /* Invalid port ID */
866 retval = rte_eth_bond_primary_set(INVALID_PORT_ID,
867 test_params->slave_port_ids[i]);
869 printf("Expected call to failed as invalid port specified.\n");
873 /* Non bonded device */
874 retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
875 test_params->slave_port_ids[i]);
877 printf("Expected call to failed as invalid port specified.\n");
881 /* Set slave as primary
882 * Verify slave it is now primary slave
883 * Verify that MAC address of bonded device is that of primary slave
884 * Verify that MAC address of all bonded slaves are that of primary slave
886 for (i = 0; i < 4; i++) {
887 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
888 test_params->slave_port_ids[i]);
890 printf("Failed to set bonded port (%d) primary port to (%d)\n",
891 test_params->bonded_port_id,
892 test_params->slave_port_ids[i]);
896 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
898 printf("Failed to read primary port from bonded port (%d)\n",
899 test_params->bonded_port_id);
901 } else if (retval != test_params->slave_port_ids[i]) {
902 printf("Bonded port (%d) primary port (%d) not expected value (%d)\n",
903 test_params->bonded_port_id, retval,
904 test_params->slave_port_ids[i]);
908 /* stop/start bonded eth dev to apply new MAC */
909 rte_eth_dev_stop(test_params->bonded_port_id);
911 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
914 expected_mac_addr = (struct ether_addr *)&slave_mac;
915 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
916 test_params->slave_port_ids[i];
918 /* Check primary slave MAC */
919 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
920 if (memcmp(expected_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
921 printf("bonded port mac address not set to that of primary port\n");
925 /* Check bonded MAC */
926 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
927 if (memcmp(&read_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
928 printf("bonded port mac address not set to that of primary port\n");
932 /* Check other slaves MACs */
933 for (j = 0; j < 4; j++) {
935 rte_eth_macaddr_get(test_params->slave_port_ids[j],
937 if (memcmp(expected_mac_addr, &read_mac_addr,
938 sizeof(read_mac_addr))) {
939 printf("slave port mac address not set to that of primary port\n");
947 /* Test with none existent port */
948 retval = rte_eth_bond_primary_get(test_params->bonded_port_id + 10);
950 printf("read primary port from expectedly\n");
954 /* Test with slave port */
955 retval = rte_eth_bond_primary_get(test_params->slave_port_ids[0]);
957 printf("read primary port from expectedly\n");
961 if (remove_slaves_and_stop_bonded_device() != 0)
965 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
967 printf("read primary port from expectedly\n");
975 test_set_explicit_bonded_mac(void)
978 struct ether_addr read_mac_addr;
979 struct ether_addr *mac_addr;
981 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
983 mac_addr = (struct ether_addr *)explicit_bonded_mac;
985 /* Invalid port ID */
986 retval = rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr);
988 printf("Expected call to failed as invalid port specified.\n");
992 /* Non bonded device */
993 retval = rte_eth_bond_mac_address_set(test_params->slave_port_ids[0],
996 printf("Expected call to failed as invalid port specified.\n");
1000 /* NULL MAC address */
1001 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id, NULL);
1003 printf("Expected call to failed as NULL MAC specified\n");
1007 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1010 printf("Failed to set MAC address on bonded port (%d)\n",
1011 test_params->bonded_port_id);
1015 /* Add 4 slaves to bonded device */
1016 for (i = test_params->bonded_slave_count; i < 4; i++) {
1017 retval = test_add_slave_to_bonded_device();
1019 printf("Failed to add slave to bonded device.\n");
1024 /* Check bonded MAC */
1025 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1026 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1027 printf("bonded port mac address not set to that of primary port\n");
1031 /* Check other slaves MACs */
1032 for (i = 0; i < 4; i++) {
1033 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1034 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1035 printf("slave port mac address not set to that of primary port\n");
1040 /* test resetting mac address on bonded device */
1041 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1042 printf("Failed to reset MAC address on bonded port (%d)\n",
1043 test_params->bonded_port_id);
1048 if (rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]) == 0) {
1049 printf("Reset MAC address on bonded port (%d) unexpectedly\n",
1050 test_params->slave_port_ids[1]);
1055 /* test resetting mac address on bonded device with no slaves */
1057 if (remove_slaves_and_stop_bonded_device() != 0)
1060 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1061 printf("Failed to reset MAC address on bonded port (%d)\n",
1062 test_params->bonded_port_id);
1072 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1073 uint8_t number_of_slaves, uint8_t enable_slave)
1075 /* Configure bonded device */
1076 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1077 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1078 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1081 /* Add slaves to bonded device */
1082 while (number_of_slaves > test_params->bonded_slave_count)
1083 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1084 "Failed to add slave (%d to bonding port (%d).",
1085 test_params->bonded_slave_count - 1,
1086 test_params->bonded_port_id);
1088 /* Set link bonding mode */
1089 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1091 "Failed to set link bonding mode on port (%d) to (%d).",
1092 test_params->bonded_port_id, bonding_mode);
1094 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1095 "Failed to start bonded pmd eth device %d.",
1096 test_params->bonded_port_id);
1099 enable_bonded_slaves();
1105 test_adding_slave_after_bonded_device_started(void)
1109 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1110 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1111 "Failed to add slaves to bonded device");
1113 /* Enabled slave devices */
1114 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1115 virtual_ethdev_simulate_link_status_interrupt(
1116 test_params->slave_port_ids[i], 1);
1119 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1120 test_params->slave_port_ids[test_params->bonded_slave_count]),
1121 "Failed to add slave to bonded port.\n");
1123 rte_eth_stats_reset(
1124 test_params->slave_port_ids[test_params->bonded_slave_count]);
1126 test_params->bonded_slave_count++;
1128 return remove_slaves_and_stop_bonded_device();
1131 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1132 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1134 int test_lsc_interrupt_count;
1138 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1139 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1141 pthread_mutex_lock(&mutex);
1142 test_lsc_interrupt_count++;
1144 pthread_cond_signal(&cvar);
1145 pthread_mutex_unlock(&mutex);
1149 lsc_timeout(int wait_us)
1156 gettimeofday(&tp, NULL);
1158 /* Convert from timeval to timespec */
1159 ts.tv_sec = tp.tv_sec;
1160 ts.tv_nsec = tp.tv_usec * 1000;
1161 ts.tv_nsec += wait_us * 1000;
1163 pthread_mutex_lock(&mutex);
1164 if (test_lsc_interrupt_count < 1)
1165 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1167 pthread_mutex_unlock(&mutex);
1169 if (retval == 0 && test_lsc_interrupt_count < 1)
1176 test_status_interrupt(void)
1179 uint8_t slaves[RTE_MAX_ETHPORTS];
1181 /* initialized bonding device with T slaves */
1182 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 1,
1183 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1) != 0)
1186 test_lsc_interrupt_count = 0;
1188 /* register link status change interrupt callback */
1189 rte_eth_dev_callback_register(test_params->bonded_port_id,
1190 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1191 &test_params->bonded_port_id);
1193 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1194 slaves, RTE_MAX_ETHPORTS);
1196 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1197 "Number of active slaves (%d) is not as expected (%d)",
1198 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1200 /* Bring all 4 slaves link status to down and test that we have received a
1202 virtual_ethdev_simulate_link_status_interrupt(
1203 test_params->slave_port_ids[0], 0);
1204 virtual_ethdev_simulate_link_status_interrupt(
1205 test_params->slave_port_ids[1], 0);
1206 virtual_ethdev_simulate_link_status_interrupt(
1207 test_params->slave_port_ids[2], 0);
1209 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1210 "Received a link status change interrupt unexpectedly");
1212 virtual_ethdev_simulate_link_status_interrupt(
1213 test_params->slave_port_ids[3], 0);
1215 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1216 "timed out waiting for interrupt");
1218 TEST_ASSERT(test_lsc_interrupt_count > 0,
1219 "Did not receive link status change interrupt");
1221 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1222 slaves, RTE_MAX_ETHPORTS);
1224 TEST_ASSERT_EQUAL(slave_count, 0,
1225 "Number of active slaves (%d) is not as expected (%d)",
1228 /* bring one slave port up so link status will change */
1229 test_lsc_interrupt_count = 0;
1231 virtual_ethdev_simulate_link_status_interrupt(
1232 test_params->slave_port_ids[0], 1);
1234 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1235 "timed out waiting for interrupt");
1237 /* test that we have received another lsc interrupt */
1238 TEST_ASSERT(test_lsc_interrupt_count > 0,
1239 "Did not receive link status change interrupt");
1241 /* Verify that calling the same slave lsc interrupt doesn't cause another
1242 * lsc interrupt from bonded device */
1243 test_lsc_interrupt_count = 0;
1245 virtual_ethdev_simulate_link_status_interrupt(
1246 test_params->slave_port_ids[0], 1);
1248 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1249 "received unexpected interrupt");
1251 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1252 "Did not receive link status change interrupt");
1255 /* unregister lsc callback before exiting */
1256 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1257 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1258 &test_params->bonded_port_id);
1260 /* Clean up and remove slaves from bonded device */
1261 return remove_slaves_and_stop_bonded_device();
1265 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1266 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1267 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1269 uint16_t pktlen, generated_burst_size;
1273 initialize_eth_header(test_params->pkt_eth_hdr,
1274 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1277 initialize_eth_header(test_params->pkt_eth_hdr,
1278 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1282 if (toggle_udp_port)
1283 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1286 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1291 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1292 dst_addr_1, pktlen);
1294 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1295 dst_addr_0, pktlen);
1297 ip_hdr = test_params->pkt_ipv4_hdr;
1300 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1301 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1304 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1305 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1308 ip_hdr = test_params->pkt_ipv6_hdr;
1311 /* Generate burst of packets to transmit */
1312 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1313 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1314 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1316 if (generated_burst_size != burst_size) {
1317 printf("Failed to generate packet burst");
1321 return generated_burst_size;
1324 /** Round Robin Mode Tests */
1327 test_roundrobin_tx_burst(void)
1329 int i, burst_size, nb_tx;
1330 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1331 struct rte_eth_stats port_stats;
1333 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 2, 1)
1337 burst_size = 20 * test_params->bonded_slave_count;
1339 if (burst_size > MAX_PKT_BURST) {
1340 printf("Burst size specified is greater than supported.\n");
1344 /* Generate test bursts of packets to transmit */
1345 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size)
1348 /* Send burst on bonded port */
1349 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1351 if (nb_tx != burst_size)
1354 /* Verify bonded port tx stats */
1355 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1356 if (port_stats.opackets != (uint64_t)burst_size) {
1357 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1358 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1363 /* Verify slave ports tx stats */
1364 for (i = 0; i < test_params->bonded_slave_count; i++) {
1365 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1366 if (port_stats.opackets !=
1367 (uint64_t)burst_size / test_params->bonded_slave_count) {
1368 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1369 test_params->bonded_port_id,
1370 (unsigned int)port_stats.opackets,
1371 burst_size / test_params->bonded_slave_count);
1376 /* Put all slaves down and try and transmit */
1377 for (i = 0; i < test_params->bonded_slave_count; i++) {
1378 virtual_ethdev_simulate_link_status_interrupt(
1379 test_params->slave_port_ids[i], 0);
1382 /* Send burst on bonded port */
1383 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1388 /* Clean up and remove slaves from bonded device */
1389 return remove_slaves_and_stop_bonded_device();
1392 #ifdef RTE_MBUF_REFCNT
1394 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1398 for (i = 0; i < nb_mbufs; i++) {
1399 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1400 TEST_ASSERT_EQUAL(refcnt, val,
1401 "mbuf ref count (%d)is not the expected value (%d)",
1410 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1414 for (i = 0; i < nb_mbufs; i++)
1415 rte_pktmbuf_free(mbufs[i]);
1418 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1419 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1420 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1421 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1424 test_roundrobin_tx_burst_slave_tx_fail(void)
1426 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1427 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1429 struct rte_eth_stats port_stats;
1431 int i, first_fail_idx, tx_count;
1433 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1434 BONDING_MODE_ROUND_ROBIN, 0,
1435 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1436 "Failed to intialise bonded device");
1438 /* Generate test bursts of packets to transmit */
1439 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1440 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1441 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1442 "Failed to generate test packet burst");
1444 /* Copy references to packets which we expect not to be transmitted */
1445 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1446 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1447 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1448 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1450 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1451 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1452 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1455 /* Set virtual slave to only fail transmission of
1456 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1457 virtual_ethdev_tx_burst_fn_set_success(
1458 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1461 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1462 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1463 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1465 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1466 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1468 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1469 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1470 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1471 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1472 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1474 /* Verify that failed packet are expected failed packets */
1475 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1476 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1477 "expected mbuf (%d) pointer %p not expected pointer %p",
1478 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1481 /* Verify bonded port tx stats */
1482 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1484 TEST_ASSERT_EQUAL(port_stats.opackets,
1485 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1486 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1487 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1488 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1489 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1490 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1492 /* Verify slave ports tx stats */
1493 for (i = 0; i < test_params->bonded_slave_count; i++) {
1494 int slave_expected_tx_count;
1496 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1498 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1499 test_params->bonded_slave_count;
1501 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1502 slave_expected_tx_count = slave_expected_tx_count -
1503 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1505 TEST_ASSERT_EQUAL(port_stats.opackets,
1506 (uint64_t)slave_expected_tx_count,
1507 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1508 test_params->slave_port_ids[i],
1509 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1512 #ifdef RTE_MBUF_REFCNT
1513 /* Verify that all mbufs have a ref value of zero */
1514 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1515 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1516 "mbufs refcnts not as expected");
1518 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1520 /* Clean up and remove slaves from bonded device */
1521 return remove_slaves_and_stop_bonded_device();
1525 test_roundrobin_rx_burst_on_single_slave(void)
1527 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1528 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1530 struct rte_eth_stats port_stats;
1532 int i, j, nb_rx, burst_size = 25;
1534 /* Initialize bonded device with 4 slaves in round robin mode */
1535 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1539 /* Generate test bursts of packets to transmit */
1540 if (generate_test_burst(gen_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1544 for (i = 0; i < test_params->bonded_slave_count; i++) {
1545 /* Add rx data to slave */
1546 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1547 &gen_pkt_burst[0], burst_size);
1549 /* Call rx burst on bonded device */
1550 /* Send burst on bonded port */
1551 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1553 if (nb_rx != burst_size) {
1554 printf("round-robin rx burst failed");
1558 /* Verify bonded device rx count */
1559 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1560 if (port_stats.ipackets != (uint64_t)burst_size) {
1561 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1562 test_params->bonded_port_id,
1563 (unsigned int)port_stats.ipackets, burst_size);
1568 /* Verify bonded slave devices rx count */
1569 /* Verify slave ports tx stats */
1570 for (j = 0; j < test_params->bonded_slave_count; j++) {
1571 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1574 if (port_stats.ipackets != (uint64_t)burst_size) {
1575 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1576 test_params->slave_port_ids[i],
1577 (unsigned int)port_stats.ipackets, burst_size);
1581 if (port_stats.ipackets != 0) {
1582 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1583 test_params->slave_port_ids[i],
1584 (unsigned int)port_stats.ipackets, 0);
1589 /* Reset bonded slaves stats */
1590 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1592 /* reset bonded device stats */
1593 rte_eth_stats_reset(test_params->bonded_port_id);
1597 for (i = 0; i < MAX_PKT_BURST; i++) {
1598 if (gen_pkt_burst[i] != NULL)
1599 rte_pktmbuf_free(gen_pkt_burst[i]);
1601 if (rx_pkt_burst[i] != NULL)
1602 rte_pktmbuf_free(rx_pkt_burst[i]);
1606 /* Clean up and remove slaves from bonded device */
1607 return remove_slaves_and_stop_bonded_device();
1610 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1613 test_roundrobin_rx_burst_on_multiple_slaves(void)
1615 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1617 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1618 struct rte_eth_stats port_stats;
1620 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1624 /* Initialize bonded device with 4 slaves in round robin mode */
1625 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1629 /* Generate test bursts of packets to transmit */
1630 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1631 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0,
1632 0) != burst_size[i])
1636 /* Add rx data to slaves */
1637 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1638 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1639 &gen_pkt_burst[i][0], burst_size[i]);
1642 /* Call rx burst on bonded device */
1643 /* Send burst on bonded port */
1644 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1646 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
1647 printf("round-robin rx burst failed (%d != %d)\n", nb_rx,
1648 burst_size[0] + burst_size[1] + burst_size[2]);
1652 /* Verify bonded device rx count */
1653 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1654 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
1656 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1657 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1658 burst_size[0] + burst_size[1] + burst_size[2]);
1663 /* Verify bonded slave devices rx counts */
1664 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1665 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
1666 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1667 test_params->slave_port_ids[0],
1668 (unsigned int)port_stats.ipackets, burst_size[0]);
1672 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1673 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
1674 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1675 test_params->slave_port_ids[1],
1676 (unsigned int)port_stats.ipackets, burst_size[1]);
1680 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1681 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
1682 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1683 test_params->slave_port_ids[2],
1684 (unsigned int)port_stats.ipackets, burst_size[2]);
1688 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1689 if (port_stats.ipackets != 0) {
1690 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1691 test_params->slave_port_ids[3],
1692 (unsigned int)port_stats.ipackets, 0);
1697 for (i = 0; i < MAX_PKT_BURST; i++) {
1698 if (rx_pkt_burst[i] != NULL)
1699 rte_pktmbuf_free(rx_pkt_burst[i]);
1702 /* Clean up and remove slaves from bonded device */
1703 return remove_slaves_and_stop_bonded_device();
1707 test_roundrobin_verify_mac_assignment(void)
1709 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1713 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1714 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1716 /* Initialize bonded device with 4 slaves in round robin mode */
1717 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1)
1721 /* Verify that all MACs are the same as first slave added to bonded dev */
1722 for (i = 0; i < test_params->bonded_slave_count; i++) {
1723 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1724 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1725 sizeof(read_mac_addr))) {
1726 printf("slave port (%d) mac address not set to that of primary port\n",
1727 test_params->slave_port_ids[i]);
1732 /* change primary and verify that MAC addresses haven't changed */
1733 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
1734 test_params->slave_port_ids[2]);
1736 printf("Failed to set bonded port (%d) primary port to (%d)\n",
1737 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1741 for (i = 0; i < test_params->bonded_slave_count; i++) {
1742 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1743 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1744 sizeof(read_mac_addr))) {
1745 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
1746 test_params->slave_port_ids[i]);
1751 /* stop / start bonded device and verify that primary MAC address is
1752 * propagate to bonded device and slaves */
1754 rte_eth_dev_stop(test_params->bonded_port_id);
1756 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
1759 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1760 if (memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr))) {
1761 printf("bonded port (%d) mac address not set to that of new primary port\n",
1762 test_params->slave_port_ids[i]);
1766 for (i = 0; i < test_params->bonded_slave_count; i++) {
1767 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1768 if (memcmp(&expected_mac_addr_2, &read_mac_addr,
1769 sizeof(read_mac_addr))) {
1770 printf("slave port (%d) mac address not set to that of new primary port\n",
1771 test_params->slave_port_ids[i]);
1776 /* Set explicit MAC address */
1777 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1778 (struct ether_addr *)bonded_mac) != 0) {
1782 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1783 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1784 printf("bonded port (%d) mac address not set to that of new primary port\n",
1785 test_params->slave_port_ids[i]);
1789 for (i = 0; i < test_params->bonded_slave_count; i++) {
1790 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1791 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1792 printf("slave port (%d) mac address not set to that of new primary port\n",
1793 test_params->slave_port_ids[i]);
1798 /* Clean up and remove slaves from bonded device */
1799 return remove_slaves_and_stop_bonded_device();
1803 test_roundrobin_verify_promiscuous_enable_disable(void)
1805 int i, promiscuous_en;
1807 /* Initialize bonded device with 4 slaves in round robin mode */
1808 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1812 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1814 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1815 if (promiscuous_en != 1) {
1816 printf("Port (%d) promiscuous mode not enabled\n",
1817 test_params->bonded_port_id);
1821 for (i = 0; i < test_params->bonded_slave_count; i++) {
1822 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1823 if (promiscuous_en != 1) {
1824 printf("slave port (%d) promiscuous mode not enabled\n",
1825 test_params->slave_port_ids[i]);
1830 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1832 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1833 if (promiscuous_en != 0) {
1834 printf("Port (%d) promiscuous mode not disabled\n",
1835 test_params->bonded_port_id);
1839 for (i = 0; i < test_params->bonded_slave_count; i++) {
1840 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1841 if (promiscuous_en != 0) {
1842 printf("slave port (%d) promiscuous mode not disabled\n",
1843 test_params->slave_port_ids[i]);
1848 /* Clean up and remove slaves from bonded device */
1849 return remove_slaves_and_stop_bonded_device();
1852 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1853 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1856 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1858 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1859 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1860 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1862 struct rte_eth_stats port_stats;
1863 uint8_t slaves[RTE_MAX_ETHPORTS];
1865 int i, burst_size, slave_count;
1867 /* NULL all pointers in array to simplify cleanup */
1868 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1870 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1871 * in round robin mode */
1872 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0,
1873 TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
1876 /* Verify Current Slaves Count /Active Slave Count is */
1877 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1879 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1880 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
1881 TEST_RR_LINK_STATUS_SLAVE_COUNT);
1885 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1886 slaves, RTE_MAX_ETHPORTS);
1887 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1888 printf("Number of active slaves (%d) is not as expected (%d).\n",
1889 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1893 /* Set 2 slaves eth_devs link status to down */
1894 virtual_ethdev_simulate_link_status_interrupt(
1895 test_params->slave_port_ids[1], 0);
1896 virtual_ethdev_simulate_link_status_interrupt(
1897 test_params->slave_port_ids[3], 0);
1899 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1900 slaves, RTE_MAX_ETHPORTS) !=
1901 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) {
1902 printf("Number of active slaves (%d) is not as expected (%d).\n",
1903 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1909 /* Verify that pkts are not sent on slaves with link status down:
1911 * 1. Generate test burst of traffic
1912 * 2. Transmit burst on bonded eth_dev
1913 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1914 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1916 if (generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1918 printf("generate_test_burst failed\n");
1922 rte_eth_stats_reset(test_params->bonded_port_id);
1924 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1925 burst_size) != burst_size) {
1926 printf("rte_eth_tx_burst failed\n");
1930 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1931 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1932 "Port (%d) opackets stats (%d) not expected (%d) value",
1933 test_params->bonded_port_id, (int)port_stats.opackets,
1936 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1937 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1938 "Port (%d) opackets stats (%d) not expected (%d) value",
1939 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1941 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1942 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1943 "Port (%d) opackets stats (%d) not expected (%d) value",
1944 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1946 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1947 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1948 "Port (%d) opackets stats (%d) not expected (%d) value",
1949 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1951 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1952 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1953 "Port (%d) opackets stats (%d) not expected (%d) value",
1954 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1956 /* Verify that pkts are not sent on slaves with link status down:
1958 * 1. Generate test bursts of traffic
1959 * 2. Add bursts on to virtual eth_devs
1960 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1961 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1962 * 4. Verify stats for bonded eth_dev
1963 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1965 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1966 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0)
1970 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1971 &gen_pkt_burst[i][0], burst_size);
1974 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1975 MAX_PKT_BURST) != burst_size + burst_size) {
1976 printf("rte_eth_rx_burst\n");
1980 /* Verify bonded device rx count */
1981 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1982 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
1983 printf("(%d) port_stats.ipackets not as expected\n",
1984 test_params->bonded_port_id);
1989 for (i = 0; i < MAX_PKT_BURST; i++) {
1990 if (rx_pkt_burst[i] != NULL)
1991 rte_pktmbuf_free(rx_pkt_burst[i]);
1993 if (gen_pkt_burst[1][i] != NULL)
1994 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1996 if (gen_pkt_burst[3][i] != NULL)
1997 rte_pktmbuf_free(gen_pkt_burst[1][i]);
2000 /* Clean up and remove slaves from bonded device */
2001 return remove_slaves_and_stop_bonded_device();
2004 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
2006 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
2010 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2013 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2015 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
2016 char slave_name[RTE_ETH_NAME_MAX_LEN];
2020 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2021 /* Generate slave name / MAC address */
2022 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2023 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2025 /* Create slave devices with no ISR Support */
2026 if (polling_test_slaves[i] == -1) {
2027 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2028 rte_socket_id(), 0);
2029 TEST_ASSERT(polling_test_slaves[i] >= 0,
2030 "Failed to create virtual virtual ethdev %s\n", slave_name);
2032 /* Configure slave */
2033 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2034 "Failed to configure virtual ethdev %s(%d)", slave_name,
2035 polling_test_slaves[i]);
2038 /* Add slave to bonded device */
2039 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2040 polling_test_slaves[i]),
2041 "Failed to add slave %s(%d) to bonded device %d",
2042 slave_name, polling_test_slaves[i], test_params->bonded_port_id);
2045 /* Initialize bonded device */
2046 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2047 "Failed to configure bonded device %d",
2048 test_params->bonded_port_id);
2051 /* Register link status change interrupt callback */
2052 rte_eth_dev_callback_register(test_params->bonded_port_id,
2053 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2054 &test_params->bonded_port_id);
2056 /* link status change callback for first slave link up */
2057 test_lsc_interrupt_count = 0;
2059 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2061 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2064 /* no link status change callback for second slave link up */
2065 test_lsc_interrupt_count = 0;
2067 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2069 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2071 /* link status change callback for both slave links down */
2072 test_lsc_interrupt_count = 0;
2074 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2075 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2077 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2079 /* Un-Register link status change interrupt callback */
2080 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2081 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2082 &test_params->bonded_port_id);
2085 /* Clean up and remove slaves from bonded device */
2086 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2088 TEST_ASSERT_SUCCESS(
2089 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2090 polling_test_slaves[i]),
2091 "Failed to remove slave %d from bonded port (%d)",
2092 polling_test_slaves[i], test_params->bonded_port_id);
2095 return remove_slaves_and_stop_bonded_device();
2099 /** Active Backup Mode Tests */
2102 test_activebackup_tx_burst(void)
2104 int i, retval, pktlen, primary_port, burst_size, generated_burst_size, nb_tx;
2105 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2106 struct rte_eth_stats port_stats;
2108 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1);
2110 printf("Failed to initialize_bonded_device_with_slaves.\n");
2114 initialize_eth_header(test_params->pkt_eth_hdr,
2115 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2116 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2118 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2119 dst_addr_0, pktlen);
2121 burst_size = 20 * test_params->bonded_slave_count;
2123 if (burst_size > MAX_PKT_BURST) {
2124 printf("Burst size specified is greater than supported.\n");
2128 /* Generate a burst of packets to transmit */
2129 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
2130 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
2131 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1);
2132 if (generated_burst_size != burst_size)
2135 /* Send burst on bonded port */
2136 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2138 if (nb_tx != burst_size)
2141 /* Verify bonded port tx stats */
2142 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2143 if (port_stats.opackets != (uint64_t)burst_size) {
2144 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2145 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2150 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2152 /* Verify slave ports tx stats */
2153 for (i = 0; i < test_params->bonded_slave_count; i++) {
2154 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2155 if (test_params->slave_port_ids[i] == primary_port) {
2156 if (port_stats.opackets != (uint64_t)burst_size) {
2157 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2158 test_params->bonded_port_id,
2159 (unsigned int)port_stats.opackets,
2160 burst_size / test_params->bonded_slave_count);
2164 if (port_stats.opackets != 0) {
2165 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2166 test_params->bonded_port_id,
2167 (unsigned int)port_stats.opackets, 0);
2173 /* Put all slaves down and try and transmit */
2174 for (i = 0; i < test_params->bonded_slave_count; i++) {
2176 virtual_ethdev_simulate_link_status_interrupt(
2177 test_params->slave_port_ids[i], 0);
2180 /* Send burst on bonded port */
2181 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2186 /* Clean up and remove slaves from bonded device */
2187 return remove_slaves_and_stop_bonded_device();
2190 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2193 test_activebackup_rx_burst(void)
2195 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2196 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2198 struct rte_eth_stats port_stats;
2202 int i, j, nb_rx, burst_size = 17;
2204 /* Initialize bonded device with 4 slaves in round robin mode */
2205 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2206 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2211 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2212 if (primary_port < 0) {
2213 printf("failed to get primary slave for bonded port (%d)",
2214 test_params->bonded_port_id);
2217 for (i = 0; i < test_params->bonded_slave_count; i++) {
2218 /* Generate test bursts of packets to transmit */
2219 if (generate_test_burst(&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0)
2224 /* Add rx data to slave */
2225 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2226 &gen_pkt_burst[0], burst_size);
2228 /* Call rx burst on bonded device */
2229 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
2230 &rx_pkt_burst[0], MAX_PKT_BURST);
2232 printf("rte_eth_rx_burst failed\n");
2236 if (test_params->slave_port_ids[i] == primary_port) {
2237 /* Verify bonded device rx count */
2238 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2239 if (port_stats.ipackets != (uint64_t)burst_size) {
2240 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2241 test_params->bonded_port_id,
2242 (unsigned int)port_stats.ipackets, burst_size);
2246 /* Verify bonded slave devices rx count */
2247 for (j = 0; j < test_params->bonded_slave_count; j++) {
2248 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2250 if (port_stats.ipackets != (uint64_t)burst_size) {
2251 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2252 test_params->slave_port_ids[i],
2253 (unsigned int)port_stats.ipackets, burst_size);
2257 if (port_stats.ipackets != 0) {
2258 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2259 test_params->slave_port_ids[i],
2260 (unsigned int)port_stats.ipackets, 0);
2266 for (j = 0; j < test_params->bonded_slave_count; j++) {
2267 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2268 if (port_stats.ipackets != 0) {
2269 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2270 test_params->slave_port_ids[i],
2271 (unsigned int)port_stats.ipackets, 0);
2278 for (i = 0; i < MAX_PKT_BURST; i++) {
2279 if (rx_pkt_burst[i] != NULL) {
2280 rte_pktmbuf_free(rx_pkt_burst[i]);
2281 rx_pkt_burst[i] = NULL;
2285 /* reset bonded device stats */
2286 rte_eth_stats_reset(test_params->bonded_port_id);
2289 /* Clean up and remove slaves from bonded device */
2290 return remove_slaves_and_stop_bonded_device();
2294 test_activebackup_verify_promiscuous_enable_disable(void)
2296 int i, primary_port, promiscuous_en;
2298 /* Initialize bonded device with 4 slaves in round robin mode */
2299 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1)
2303 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2304 if (primary_port < 0) {
2305 printf("failed to get primary slave for bonded port (%d)",
2306 test_params->bonded_port_id);
2309 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2311 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2312 if (promiscuous_en != 1) {
2313 printf("Port (%d) promiscuous mode not enabled\n",
2314 test_params->bonded_port_id);
2318 for (i = 0; i < test_params->bonded_slave_count; i++) {
2319 promiscuous_en = rte_eth_promiscuous_get(
2320 test_params->slave_port_ids[i]);
2321 if (primary_port == test_params->slave_port_ids[i]) {
2322 if (promiscuous_en != 1) {
2323 printf("slave port (%d) promiscuous mode not enabled\n",
2324 test_params->slave_port_ids[i]);
2328 if (promiscuous_en != 0) {
2329 printf("slave port (%d) promiscuous mode enabled\n",
2330 test_params->slave_port_ids[i]);
2337 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2339 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2340 if (promiscuous_en != 0) {
2341 printf("Port (%d) promiscuous mode not disabled\n",
2342 test_params->bonded_port_id);
2346 for (i = 0; i < test_params->bonded_slave_count; i++) {
2347 promiscuous_en = rte_eth_promiscuous_get(
2348 test_params->slave_port_ids[i]);
2349 if (promiscuous_en != 0) {
2350 printf("slave port (%d) promiscuous mode not disabled\n",
2351 test_params->slave_port_ids[i]);
2356 /* Clean up and remove slaves from bonded device */
2357 return remove_slaves_and_stop_bonded_device();
2361 test_activebackup_verify_mac_assignment(void)
2363 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2365 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2366 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2368 /* Initialize bonded device with 2 slaves in active backup mode */
2369 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1)
2373 /* Verify that bonded MACs is that of first slave and that the other slave
2374 * MAC hasn't been changed */
2375 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2376 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2377 printf("bonded port (%d) mac address not set to that of primary port\n",
2378 test_params->bonded_port_id);
2382 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2383 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2384 printf("slave port (%d) mac address not set to that of primary port\n",
2385 test_params->slave_port_ids[0]);
2389 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2390 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2391 printf("slave port (%d) mac address not as expected\n",
2392 test_params->slave_port_ids[1]);
2396 /* change primary and verify that MAC addresses haven't changed */
2397 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2398 test_params->slave_port_ids[1]) != 0) {
2399 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2400 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2404 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2405 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2406 printf("bonded port (%d) mac address not set to that of primary port\n",
2407 test_params->bonded_port_id);
2411 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2412 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2413 printf("slave port (%d) mac address not set to that of primary port\n",
2414 test_params->slave_port_ids[0]);
2418 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2419 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2420 printf("slave port (%d) mac address not as expected\n",
2421 test_params->slave_port_ids[1]);
2425 /* stop / start bonded device and verify that primary MAC address is
2426 * propagated to bonded device and slaves */
2428 rte_eth_dev_stop(test_params->bonded_port_id);
2430 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2433 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2434 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2435 printf("bonded port (%d) mac address not set to that of primary port\n",
2436 test_params->bonded_port_id);
2440 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2441 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2442 printf("slave port (%d) mac address not as expected\n",
2443 test_params->slave_port_ids[0]);
2447 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2448 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2449 printf("slave port (%d) mac address not set to that of primary port\n",
2450 test_params->slave_port_ids[1]);
2454 /* Set explicit MAC address */
2455 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
2456 (struct ether_addr *)bonded_mac) != 0) {
2460 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2461 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2462 printf("bonded port (%d) mac address not set to that of bonded port\n",
2463 test_params->bonded_port_id);
2467 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2468 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2469 printf("slave port (%d) mac address not as expected\n",
2470 test_params->slave_port_ids[0]);
2474 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2475 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2476 printf("slave port (%d) mac address not set to that of bonded port\n",
2477 test_params->slave_port_ids[1]);
2481 /* Clean up and remove slaves from bonded device */
2482 return remove_slaves_and_stop_bonded_device();
2486 test_activebackup_verify_slave_link_status_change_failover(void)
2488 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2489 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2490 struct rte_eth_stats port_stats;
2492 uint8_t slaves[RTE_MAX_ETHPORTS];
2494 int i, j, burst_size, slave_count, primary_port;
2498 memset(pkt_burst, 0, sizeof(pkt_burst));
2500 /* Generate packet burst for testing */
2501 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
2503 printf("generate_test_burst failed\n");
2507 /* Initialize bonded device with 4 slaves in round robin mode */
2508 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2509 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2513 /* Verify Current Slaves Count /Active Slave Count is */
2514 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2516 if (slave_count != 4) {
2517 printf("Number of slaves (%d) is not as expected (%d).\n",
2522 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2523 slaves, RTE_MAX_ETHPORTS);
2524 if (slave_count != 4) {
2525 printf("Number of active slaves (%d) is not as expected (%d).\n",
2530 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2531 if (primary_port != test_params->slave_port_ids[0])
2532 printf("Primary port not as expected");
2534 /* Bring 2 slaves down and verify active slave count */
2535 virtual_ethdev_simulate_link_status_interrupt(
2536 test_params->slave_port_ids[1], 0);
2537 virtual_ethdev_simulate_link_status_interrupt(
2538 test_params->slave_port_ids[3], 0);
2540 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2541 RTE_MAX_ETHPORTS) != 2) {
2542 printf("Number of active slaves (%d) is not as expected (%d).\n",
2547 virtual_ethdev_simulate_link_status_interrupt(
2548 test_params->slave_port_ids[1], 1);
2549 virtual_ethdev_simulate_link_status_interrupt(
2550 test_params->slave_port_ids[3], 1);
2553 /* Bring primary port down, verify that active slave count is 3 and primary
2555 virtual_ethdev_simulate_link_status_interrupt(
2556 test_params->slave_port_ids[0], 0);
2558 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2559 RTE_MAX_ETHPORTS) != 3) {
2560 printf("Number of active slaves (%d) is not as expected (%d).\n",
2565 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2566 if (primary_port != test_params->slave_port_ids[2])
2567 printf("Primary port not as expected");
2569 /* Verify that pkts are sent on new primary slave */
2571 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size)
2573 printf("rte_eth_tx_burst failed\n");
2577 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2578 if (port_stats.opackets != (uint64_t)burst_size) {
2579 printf("(%d) port_stats.opackets not as expected\n",
2580 test_params->slave_port_ids[2]);
2584 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2585 if (port_stats.opackets != 0) {
2586 printf("(%d) port_stats.opackets not as expected\n",
2587 test_params->slave_port_ids[0]);
2590 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2591 if (port_stats.opackets != 0) {
2592 printf("(%d) port_stats.opackets not as expected\n",
2593 test_params->slave_port_ids[1]);
2596 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2597 if (port_stats.opackets != 0) {
2598 printf("(%d) port_stats.opackets not as expected\n",
2599 test_params->slave_port_ids[3]);
2603 /* Generate packet burst for testing */
2605 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2606 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
2610 virtual_ethdev_add_mbufs_to_rx_queue(
2611 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2614 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2615 MAX_PKT_BURST) != burst_size) {
2616 printf("rte_eth_rx_burst\n");
2620 /* Verify bonded device rx count */
2621 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2622 if (port_stats.ipackets != (uint64_t)burst_size) {
2623 printf("(%d) port_stats.ipackets not as expected\n",
2624 test_params->bonded_port_id);
2628 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2629 if (port_stats.opackets != (uint64_t)burst_size) {
2630 printf("(%d) port_stats.opackets not as expected\n",
2631 test_params->slave_port_ids[2]);
2635 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2636 if (port_stats.opackets != 0) {
2637 printf("(%d) port_stats.opackets not as expected\n",
2638 test_params->slave_port_ids[0]);
2642 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2643 if (port_stats.opackets != 0) {
2644 printf("(%d) port_stats.opackets not as expected\n",
2645 test_params->slave_port_ids[1]);
2649 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2650 if (port_stats.opackets != 0) {
2651 printf("(%d) port_stats.opackets not as expected\n",
2652 test_params->slave_port_ids[3]);
2658 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2659 for (j = 0; j < MAX_PKT_BURST; j++) {
2660 if (pkt_burst[i][j] != NULL) {
2661 rte_pktmbuf_free(pkt_burst[i][j]);
2662 pkt_burst[i][j] = NULL;
2668 /* Clean up and remove slaves from bonded device */
2669 return remove_slaves_and_stop_bonded_device();
2672 /** Balance Mode Tests */
2675 test_balance_xmit_policy_configuration(void)
2679 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2682 printf("Failed to initialize_bonded_device_with_slaves.\n");
2686 /* Invalid port id */
2687 retval = rte_eth_bond_xmit_policy_set(INVALID_PORT_ID,
2688 BALANCE_XMIT_POLICY_LAYER2);
2690 printf("Expected call to failed as invalid port specified.\n");
2694 /* Set xmit policy on non bonded device */
2695 retval = rte_eth_bond_xmit_policy_set(test_params->slave_port_ids[0],
2696 BALANCE_XMIT_POLICY_LAYER2);
2698 printf("Expected call to failed as invalid port specified.\n");
2702 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2703 BALANCE_XMIT_POLICY_LAYER2);
2705 printf("Failed to set balance xmit policy.\n");
2708 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2709 BALANCE_XMIT_POLICY_LAYER2) {
2710 printf("balance xmit policy not as expected.\n");
2714 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2715 BALANCE_XMIT_POLICY_LAYER23);
2717 printf("Failed to set balance xmit policy.\n");
2720 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2721 BALANCE_XMIT_POLICY_LAYER23) {
2722 printf("balance xmit policy not as expected.\n");
2726 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2727 BALANCE_XMIT_POLICY_LAYER34);
2729 printf("Failed to set balance xmit policy.\n");
2732 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2733 BALANCE_XMIT_POLICY_LAYER34) {
2734 printf("balance xmit policy not as expected.\n");
2738 /* Invalid port id */
2739 if (rte_eth_bond_xmit_policy_get(INVALID_PORT_ID) >= 0)
2742 /* Clean up and remove slaves from bonded device */
2743 return remove_slaves_and_stop_bonded_device();
2746 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2749 test_balance_l2_tx_burst(void)
2751 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2752 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2757 struct rte_eth_stats port_stats;
2759 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
2760 TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1);
2762 printf("Failed to initialize_bonded_device_with_slaves.\n");
2766 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2767 BALANCE_XMIT_POLICY_LAYER2);
2769 printf("Failed to set balance xmit policy.\n");
2774 initialize_eth_header(test_params->pkt_eth_hdr,
2775 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2776 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2778 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2779 dst_addr_0, pktlen);
2781 /* Generate a burst 1 of packets to transmit */
2782 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2783 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2784 test_params->pkt_udp_hdr, burst_size[0],
2785 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[0])
2788 initialize_eth_header(test_params->pkt_eth_hdr,
2789 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2791 /* Generate a burst 2 of packets to transmit */
2792 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2793 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2794 test_params->pkt_udp_hdr, burst_size[1],
2795 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[1])
2798 /* Send burst 1 on bonded port */
2799 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2800 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[i][0],
2801 burst_size[i]) != burst_size[i])
2804 /* Verify bonded port tx stats */
2805 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2806 if (port_stats.opackets != (uint64_t)(burst_size[0] + burst_size[1])) {
2807 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2808 test_params->bonded_port_id,
2809 (unsigned int)port_stats.opackets, burst_size[0] + burst_size[1]);
2814 /* Verify slave ports tx stats */
2815 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2816 if (port_stats.opackets != (uint64_t)burst_size[0]) {
2817 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2818 test_params->slave_port_ids[0],
2819 (unsigned int)port_stats.opackets, burst_size[0]);
2823 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2824 if (port_stats.opackets != (uint64_t)burst_size[1]) {
2825 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2826 test_params->slave_port_ids[1], (
2827 unsigned int)port_stats.opackets, burst_size[1]);
2831 /* Put all slaves down and try and transmit */
2832 for (i = 0; i < test_params->bonded_slave_count; i++) {
2834 virtual_ethdev_simulate_link_status_interrupt(
2835 test_params->slave_port_ids[i], 0);
2838 /* Send burst on bonded port */
2839 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[0][0],
2840 burst_size[0]) != 0)
2843 /* Clean up and remove slaves from bonded device */
2844 return remove_slaves_and_stop_bonded_device();
2848 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2849 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2852 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2854 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2855 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2857 struct rte_eth_stats port_stats;
2859 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1);
2861 printf("Failed to initialize_bonded_device_with_slaves.\n");
2865 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2866 BALANCE_XMIT_POLICY_LAYER23);
2868 printf("Failed to set balance xmit policy.\n");
2875 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2876 printf("Burst size specified is greater than supported.\n");
2880 /* Generate test bursts of packets to transmit */
2881 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4,
2882 0, 0, 0) != burst_size_1)
2885 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2886 toggle_mac_addr, toggle_ip_addr, 0) != burst_size_2)
2889 /* Send burst 1 on bonded port */
2890 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2892 if (nb_tx_1 != burst_size_1)
2895 /* Send burst 2 on bonded port */
2896 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2898 if (nb_tx_2 != burst_size_2)
2901 /* Verify bonded port tx stats */
2902 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2903 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2904 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2905 test_params->bonded_port_id,
2906 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2910 /* Verify slave ports tx stats */
2911 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2912 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2913 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2914 test_params->slave_port_ids[0],
2915 (unsigned int)port_stats.opackets, nb_tx_1);
2919 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2920 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2921 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2922 test_params->slave_port_ids[1],
2923 (unsigned int)port_stats.opackets, nb_tx_2);
2927 /* Put all slaves down and try and transmit */
2928 for (i = 0; i < test_params->bonded_slave_count; i++) {
2930 virtual_ethdev_simulate_link_status_interrupt(
2931 test_params->slave_port_ids[i], 0);
2934 /* Send burst on bonded port */
2935 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2940 /* Clean up and remove slaves from bonded device */
2941 return remove_slaves_and_stop_bonded_device();
2945 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2947 return balance_l23_tx_burst(0, 1, 1, 0);
2951 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2953 return balance_l23_tx_burst(1, 1, 0, 1);
2957 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2959 return balance_l23_tx_burst(0, 0, 0, 1);
2963 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2965 return balance_l23_tx_burst(1, 0, 0, 1);
2969 test_balance_l23_tx_burst_toggle_mac_addr(void)
2971 return balance_l23_tx_burst(0, 0, 1, 0);
2975 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2976 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2977 uint8_t toggle_udp_port)
2980 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2982 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2983 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2985 struct rte_eth_stats port_stats;
2987 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1);
2989 printf("Failed to initialize_bonded_device_with_slaves.\n");
2993 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2994 BALANCE_XMIT_POLICY_LAYER34);
2996 printf("Failed to set balance xmit policy.\n");
3003 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
3004 printf("Burst size specified is greater than supported.\n");
3008 /* Generate test bursts of packets to transmit */
3009 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0,
3010 0, 0) != burst_size_1)
3013 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
3014 toggle_mac_addr, toggle_ip_addr, toggle_udp_port) != burst_size_2)
3017 /* Send burst 1 on bonded port */
3018 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3020 if (nb_tx_1 != burst_size_1)
3023 /* Send burst 2 on bonded port */
3024 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3026 if (nb_tx_2 != burst_size_2)
3030 /* Verify bonded port tx stats */
3031 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3032 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
3033 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3034 test_params->bonded_port_id,
3035 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
3039 /* Verify slave ports tx stats */
3040 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3041 if (port_stats.opackets != (uint64_t)nb_tx_1) {
3042 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3043 test_params->slave_port_ids[0],
3044 (unsigned int)port_stats.opackets, nb_tx_1);
3048 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3049 if (port_stats.opackets != (uint64_t)nb_tx_2) {
3050 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3051 test_params->slave_port_ids[1],
3052 (unsigned int)port_stats.opackets, nb_tx_2);
3056 /* Put all slaves down and try and transmit */
3057 for (i = 0; i < test_params->bonded_slave_count; i++) {
3059 virtual_ethdev_simulate_link_status_interrupt(
3060 test_params->slave_port_ids[i], 0);
3063 /* Send burst on bonded port */
3064 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3069 /* Clean up and remove slaves from bonded device */
3070 return remove_slaves_and_stop_bonded_device();
3074 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
3076 return balance_l34_tx_burst(0, 1, 0, 1, 0);
3080 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
3082 return balance_l34_tx_burst(0, 1, 0, 0, 1);
3086 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
3088 return balance_l34_tx_burst(1, 1, 0, 1, 0);
3092 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
3094 return balance_l34_tx_burst(0, 0, 0, 1, 0);
3098 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
3100 return balance_l34_tx_burst(1, 0, 0, 1, 0);
3104 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
3106 return balance_l34_tx_burst(0, 0, 0, 0, 1);
3109 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
3110 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
3111 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
3112 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
3113 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
3116 test_balance_tx_burst_slave_tx_fail(void)
3118 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
3119 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
3121 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
3123 struct rte_eth_stats port_stats;
3125 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
3127 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3128 BONDING_MODE_BALANCE, 0,
3129 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3130 "Failed to intialise bonded device");
3132 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3133 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3134 "Failed to set balance xmit policy.");
3137 /* Generate test bursts for transmission */
3138 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
3139 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
3140 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
3141 "Failed to generate test packet burst 1");
3143 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3144 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
3146 /* copy mbuf referneces for expected transmission failures */
3147 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
3148 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
3150 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
3151 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
3152 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3153 "Failed to generate test packet burst 2");
3156 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3157 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3158 virtual_ethdev_tx_burst_fn_set_success(
3159 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3162 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3163 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3164 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3167 /* Transmit burst 1 */
3168 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3169 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3171 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3172 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3173 "Transmitted (%d) packets, expected to transmit (%d) packets",
3174 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3175 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3177 /* Verify that failed packet are expected failed packets */
3178 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3179 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3180 "expected mbuf (%d) pointer %p not expected pointer %p",
3181 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3184 /* Transmit burst 2 */
3185 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3186 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3188 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3189 "Transmitted (%d) packets, expected to transmit (%d) packets",
3190 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3193 /* Verify bonded port tx stats */
3194 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3196 TEST_ASSERT_EQUAL(port_stats.opackets,
3197 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3198 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3199 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3200 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3201 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3202 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3203 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3204 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3206 /* Verify slave ports tx stats */
3208 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3210 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3211 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3212 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3213 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3214 test_params->slave_port_ids[0],
3215 (unsigned int)port_stats.opackets,
3216 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3217 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3222 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3224 TEST_ASSERT_EQUAL(port_stats.opackets,
3225 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3226 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3227 test_params->slave_port_ids[1],
3228 (unsigned int)port_stats.opackets,
3229 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3231 #ifdef RTE_MBUF_REFCNT
3232 /* Verify that all mbufs have a ref value of zero */
3233 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3234 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3235 "mbufs refcnts not as expected");
3238 free_mbufs(&pkts_burst_1[tx_count_1],
3239 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3241 /* Clean up and remove slaves from bonded device */
3242 return remove_slaves_and_stop_bonded_device();
3245 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3248 test_balance_rx_burst(void)
3250 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3252 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3253 struct rte_eth_stats port_stats;
3255 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3258 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3260 /* Initialize bonded device with 4 slaves in round robin mode */
3261 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 3, 1)
3265 /* Generate test bursts of packets to transmit */
3266 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3267 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3268 0, 0) != burst_size[i])
3271 /* Add rx data to slaves */
3272 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3273 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3274 &gen_pkt_burst[i][0], burst_size[i]);
3277 /* Call rx burst on bonded device */
3278 /* Send burst on bonded port */
3279 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3281 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3282 printf("balance rx burst failed\n");
3286 /* Verify bonded device rx count */
3287 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3288 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3290 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3291 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3292 burst_size[0] + burst_size[1] + burst_size[2]);
3297 /* Verify bonded slave devices rx counts */
3298 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3299 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3300 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3301 test_params->slave_port_ids[0],
3302 (unsigned int)port_stats.ipackets, burst_size[0]);
3306 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3307 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3308 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3309 test_params->slave_port_ids[1],
3310 (unsigned int)port_stats.ipackets, burst_size[1]);
3314 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3315 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3316 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3317 test_params->slave_port_ids[2],
3318 (unsigned int)port_stats.ipackets, burst_size[2]);
3322 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3323 if (port_stats.ipackets != 0) {
3324 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3325 test_params->slave_port_ids[3],
3326 (unsigned int)port_stats.ipackets, 0);
3331 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3332 for (j = 0; j < MAX_PKT_BURST; j++) {
3333 if (gen_pkt_burst[i][j] != NULL) {
3334 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3335 gen_pkt_burst[i][j] = NULL;
3340 /* Clean up and remove slaves from bonded device */
3341 return remove_slaves_and_stop_bonded_device();
3345 test_balance_verify_promiscuous_enable_disable(void)
3347 int i, promiscuous_en;
3349 /* Initialize bonded device with 4 slaves in round robin mode */
3350 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) != 0)
3353 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3355 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3356 if (promiscuous_en != 1) {
3357 printf("Port (%d) promiscuous mode not enabled\n",
3358 test_params->bonded_port_id);
3362 for (i = 0; i < test_params->bonded_slave_count; i++) {
3363 promiscuous_en = rte_eth_promiscuous_get(
3364 test_params->slave_port_ids[i]);
3365 if (promiscuous_en != 1) {
3366 printf("slave port (%d) promiscuous mode not enabled\n",
3367 test_params->slave_port_ids[i]);
3372 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3374 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3375 if (promiscuous_en != 0) {
3376 printf("Port (%d) promiscuous mode not disabled\n",
3377 test_params->bonded_port_id);
3381 for (i = 0; i < test_params->bonded_slave_count; i++) {
3382 promiscuous_en = rte_eth_promiscuous_get(
3383 test_params->slave_port_ids[i]);
3384 if (promiscuous_en != 0) {
3385 printf("slave port (%d) promiscuous mode not disabled\n",
3386 test_params->slave_port_ids[i]);
3391 /* Clean up and remove slaves from bonded device */
3392 return remove_slaves_and_stop_bonded_device();
3396 test_balance_verify_mac_assignment(void)
3398 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3400 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3401 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3403 /* Initialize bonded device with 2 slaves in active backup mode */
3404 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1) != 0)
3407 /* Verify that bonded MACs is that of first slave and that the other slave
3408 * MAC hasn't been changed */
3409 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3410 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3411 printf("bonded port (%d) mac address not set to that of primary port\n",
3412 test_params->bonded_port_id);
3416 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3417 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3418 printf("slave port (%d) mac address not set to that of primary port\n",
3419 test_params->slave_port_ids[0]);
3423 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3424 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3425 printf("slave port (%d) mac address not set to that of primary port\n",
3426 test_params->slave_port_ids[1]);
3430 /* change primary and verify that MAC addresses haven't changed */
3431 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
3432 test_params->slave_port_ids[1]) != 0) {
3433 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3434 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3438 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3439 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3440 printf("bonded port (%d) mac address not set to that of primary port\n",
3441 test_params->bonded_port_id);
3445 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3446 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3447 printf("slave port (%d) mac address not set to that of primary port\n",
3448 test_params->slave_port_ids[0]);
3452 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3453 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3454 printf("slave port (%d) mac address not set to that of primary port\n",
3455 test_params->slave_port_ids[1]);
3459 /* stop / start bonded device and verify that primary MAC address is
3460 * propagated to bonded device and slaves */
3462 rte_eth_dev_stop(test_params->bonded_port_id);
3464 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3467 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3468 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3469 printf("bonded port (%d) mac address not set to that of primary port\n",
3470 test_params->bonded_port_id);
3474 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3475 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3476 printf("slave port (%d) mac address not set to that of primary port\n",
3477 test_params->slave_port_ids[0]);
3481 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3482 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3483 printf("slave port (%d) mac address not set to that of primary port\n",
3484 test_params->slave_port_ids[1]);
3488 /* Set explicit MAC address */
3489 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3490 (struct ether_addr *)bonded_mac) != 0)
3493 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3494 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3495 printf("bonded port (%d) mac address not set to that of bonded port\n",
3496 test_params->bonded_port_id);
3500 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3501 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3502 printf("slave port (%d) mac address not as expected\n",
3503 test_params->slave_port_ids[0]);
3507 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3508 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3509 printf("slave port (%d) mac address not set to that of bonded port\n",
3510 test_params->slave_port_ids[1]);
3514 /* Clean up and remove slaves from bonded device */
3515 return remove_slaves_and_stop_bonded_device();
3518 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3521 test_balance_verify_slave_link_status_change_behaviour(void)
3523 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3524 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3525 struct rte_eth_stats port_stats;
3527 uint8_t slaves[RTE_MAX_ETHPORTS];
3529 int i, j, burst_size, slave_count;
3531 memset(pkt_burst, 0, sizeof(pkt_burst));
3533 /* Initialize bonded device with 4 slaves in round robin mode */
3534 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
3535 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
3538 if (rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
3539 BALANCE_XMIT_POLICY_LAYER2)) {
3540 printf("Failed to set balance xmit policy.\n");
3544 /* Verify Current Slaves Count /Active Slave Count is */
3545 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3547 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3548 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
3549 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3553 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3554 slaves, RTE_MAX_ETHPORTS);
3555 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3556 printf("Number of active slaves (%d) is not as expected (%d).\n",
3557 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3561 /* Set 2 slaves link status to down */
3562 virtual_ethdev_simulate_link_status_interrupt(
3563 test_params->slave_port_ids[1], 0);
3564 virtual_ethdev_simulate_link_status_interrupt(
3565 test_params->slave_port_ids[3], 0);
3567 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3568 slaves, RTE_MAX_ETHPORTS) != 2) {
3569 printf("Number of active slaves (%d) is not as expected (%d).\n",
3574 /* Send to sets of packet burst and verify that they are balanced across
3578 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
3580 printf("generate_test_burst failed\n");
3584 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3586 printf("generate_test_burst failed\n");
3590 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3591 burst_size) != burst_size) {
3592 printf("rte_eth_tx_burst failed\n");
3596 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3597 burst_size) != burst_size) {
3598 printf("rte_eth_tx_burst failed\n");
3602 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3603 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3604 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3605 test_params->bonded_port_id, (int)port_stats.opackets,
3606 burst_size + burst_size);
3610 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3611 if (port_stats.opackets != (uint64_t)burst_size) {
3612 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3613 test_params->slave_port_ids[0], (int)port_stats.opackets,
3618 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3619 if (port_stats.opackets != (uint64_t)burst_size) {
3620 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3621 test_params->slave_port_ids[2], (int)port_stats.opackets,
3626 /* verify that all packets get send on primary slave when no other slaves
3628 virtual_ethdev_simulate_link_status_interrupt(
3629 test_params->slave_port_ids[2], 0);
3631 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
3632 RTE_MAX_ETHPORTS) != 1) {
3633 printf("Number of active slaves (%d) is not as expected (%d).\n",
3638 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3640 printf("generate_test_burst failed\n");
3644 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3645 burst_size) != burst_size) {
3646 printf("rte_eth_tx_burst failed\n");
3650 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3651 if (port_stats.opackets != (uint64_t)(burst_size + burst_size +
3653 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3654 test_params->bonded_port_id, (int)port_stats.opackets,
3655 burst_size + burst_size + burst_size);
3659 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3660 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3661 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3662 test_params->slave_port_ids[0], (int)port_stats.opackets,
3663 burst_size + burst_size);
3668 virtual_ethdev_simulate_link_status_interrupt(
3669 test_params->slave_port_ids[0], 0);
3670 virtual_ethdev_simulate_link_status_interrupt(
3671 test_params->slave_port_ids[1], 1);
3672 virtual_ethdev_simulate_link_status_interrupt(
3673 test_params->slave_port_ids[2], 1);
3674 virtual_ethdev_simulate_link_status_interrupt(
3675 test_params->slave_port_ids[3], 1);
3677 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3678 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
3682 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3683 &pkt_burst[i][0], burst_size);
3688 /* Verify that pkts are not received on slaves with link status down */
3690 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3693 /* Verify bonded device rx count */
3694 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3695 if (port_stats.ipackets != (uint64_t)(burst_size * 3)) {
3696 printf("(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3697 test_params->bonded_port_id, (int)port_stats.ipackets,
3702 /* free mbufs allocate for rx testing */
3703 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3704 for (j = 0; j < MAX_PKT_BURST; j++) {
3705 if (pkt_burst[i][j] != NULL) {
3706 rte_pktmbuf_free(pkt_burst[i][j]);
3707 pkt_burst[i][j] = NULL;
3712 /* Clean up and remove slaves from bonded device */
3713 return remove_slaves_and_stop_bonded_device();
3716 #ifdef RTE_MBUF_REFCNT
3717 /** Broadcast Mode Tests */
3720 test_broadcast_tx_burst(void)
3722 int i, pktlen, retval, burst_size, generated_burst_size, nb_tx;
3723 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3725 struct rte_eth_stats port_stats;
3727 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 2, 1);
3729 printf("Failed to initialize_bonded_device_with_slaves.\n");
3733 initialize_eth_header(test_params->pkt_eth_hdr,
3734 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3736 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3738 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3739 dst_addr_0, pktlen);
3741 burst_size = 20 * test_params->bonded_slave_count;
3743 if (burst_size > MAX_PKT_BURST) {
3744 printf("Burst size specified is greater than supported.\n");
3748 /* Generate a burst of packets to transmit */
3749 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
3750 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3751 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3753 if (generated_burst_size != burst_size)
3756 /* Send burst on bonded port */
3757 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3759 if (nb_tx != burst_size) {
3760 printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
3761 test_params->bonded_port_id,
3766 /* Verify bonded port tx stats */
3767 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3768 if (port_stats.opackets != (uint64_t)burst_size *
3769 test_params->bonded_slave_count) {
3770 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3771 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3775 /* Verify slave ports tx stats */
3776 for (i = 0; i < test_params->bonded_slave_count; i++) {
3777 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3778 if (port_stats.opackets != (uint64_t)burst_size) {
3779 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3780 test_params->bonded_port_id,
3781 (unsigned int)port_stats.opackets, burst_size);
3785 /* Put all slaves down and try and transmit */
3786 for (i = 0; i < test_params->bonded_slave_count; i++) {
3788 virtual_ethdev_simulate_link_status_interrupt(
3789 test_params->slave_port_ids[i], 0);
3792 /* Send burst on bonded port */
3793 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3798 /* Clean up and remove slaves from bonded device */
3799 return remove_slaves_and_stop_bonded_device();
3803 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3804 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3805 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3806 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3809 test_broadcast_tx_burst_slave_tx_fail(void)
3811 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3812 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3814 struct rte_eth_stats port_stats;
3818 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3819 BONDING_MODE_BROADCAST, 0,
3820 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3821 "Failed to intialise bonded device");
3823 /* Generate test bursts for transmission */
3824 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3825 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3826 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3827 "Failed to generate test packet burst");
3829 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3830 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3831 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3834 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3835 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3836 virtual_ethdev_tx_burst_fn_set_success(
3837 test_params->slave_port_ids[0],
3839 virtual_ethdev_tx_burst_fn_set_success(
3840 test_params->slave_port_ids[1],
3842 virtual_ethdev_tx_burst_fn_set_success(
3843 test_params->slave_port_ids[2],
3846 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3847 test_params->slave_port_ids[0],
3848 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3850 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3851 test_params->slave_port_ids[1],
3852 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3854 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3855 test_params->slave_port_ids[2],
3856 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3858 /* Transmit burst */
3859 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3860 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3862 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3863 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3864 "Transmitted (%d) packets, expected to transmit (%d) packets",
3865 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3866 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3868 /* Verify that failed packet are expected failed packets */
3869 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3870 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3871 "expected mbuf (%d) pointer %p not expected pointer %p",
3872 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3875 /* Verify slave ports tx stats */
3877 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3879 TEST_ASSERT_EQUAL(port_stats.opackets,
3880 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3881 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3882 "Port (%d) opackets value (%u) not as expected (%d)",
3883 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3884 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3885 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3888 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3890 TEST_ASSERT_EQUAL(port_stats.opackets,
3891 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3892 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3893 "Port (%d) opackets value (%u) not as expected (%d)",
3894 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3895 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3896 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3898 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3900 TEST_ASSERT_EQUAL(port_stats.opackets,
3901 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3902 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3903 "Port (%d) opackets value (%u) not as expected (%d)",
3904 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3905 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3906 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3909 /* Verify that all mbufs who transmission failed have a ref value of one */
3910 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3911 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3912 "mbufs refcnts not as expected");
3914 free_mbufs(&pkts_burst[tx_count],
3915 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3917 /* Clean up and remove slaves from bonded device */
3918 return remove_slaves_and_stop_bonded_device();
3921 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3924 test_broadcast_rx_burst(void)
3926 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3928 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3929 struct rte_eth_stats port_stats;
3931 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3934 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3936 /* Initialize bonded device with 4 slaves in round robin mode */
3937 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 3, 1) != 0)
3941 /* Generate test bursts of packets to transmit */
3942 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3943 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0,
3944 0) != burst_size[i])
3948 /* Add rx data to slave 0 */
3949 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3950 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3951 &gen_pkt_burst[i][0], burst_size[i]);
3955 /* Call rx burst on bonded device */
3956 /* Send burst on bonded port */
3957 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3959 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3960 printf("round-robin rx burst failed");
3964 /* Verify bonded device rx count */
3965 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3966 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3968 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3969 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3970 burst_size[0] + burst_size[1] + burst_size[2]);
3975 /* Verify bonded slave devices rx counts */
3976 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3977 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3978 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3979 test_params->slave_port_ids[0],
3980 (unsigned int)port_stats.ipackets, burst_size[0]);
3984 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3985 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3986 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3987 test_params->slave_port_ids[1],
3988 (unsigned int)port_stats.ipackets, burst_size[1]);
3992 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3993 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3994 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3995 test_params->slave_port_ids[2],
3996 (unsigned int)port_stats.ipackets,
4001 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4002 if (port_stats.ipackets != 0) {
4003 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4004 test_params->slave_port_ids[3],
4005 (unsigned int)port_stats.ipackets, 0);
4009 /* free mbufs allocate for rx testing */
4010 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
4011 for (j = 0; j < MAX_PKT_BURST; j++) {
4012 if (gen_pkt_burst[i][j] != NULL) {
4013 rte_pktmbuf_free(gen_pkt_burst[i][j]);
4014 gen_pkt_burst[i][j] = NULL;
4019 /* Clean up and remove slaves from bonded device */
4020 return remove_slaves_and_stop_bonded_device();
4024 test_broadcast_verify_promiscuous_enable_disable(void)
4026 int i, promiscuous_en;
4028 /* Initialize bonded device with 4 slaves in round robin mode */
4029 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) != 0)
4032 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4034 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4035 if (promiscuous_en != 1) {
4036 printf("Port (%d) promiscuous mode not enabled\n",
4037 test_params->bonded_port_id);
4041 for (i = 0; i < test_params->bonded_slave_count; i++) {
4042 promiscuous_en = rte_eth_promiscuous_get(
4043 test_params->slave_port_ids[i]);
4044 if (promiscuous_en != 1) {
4045 printf("slave port (%d) promiscuous mode not enabled\n",
4046 test_params->slave_port_ids[i]);
4051 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4053 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4054 if (promiscuous_en != 0) {
4055 printf("Port (%d) promiscuous mode not disabled\n",
4056 test_params->bonded_port_id);
4060 for (i = 0; i < test_params->bonded_slave_count; i++) {
4061 promiscuous_en = rte_eth_promiscuous_get(
4062 test_params->slave_port_ids[i]);
4063 if (promiscuous_en != 0) {
4064 printf("slave port (%d) promiscuous mode not disabled\n",
4065 test_params->slave_port_ids[i]);
4070 /* Clean up and remove slaves from bonded device */
4071 return remove_slaves_and_stop_bonded_device();
4075 test_broadcast_verify_mac_assignment(void)
4077 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4081 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4082 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
4084 /* Initialize bonded device with 4 slaves in round robin mode */
4085 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 4, 1) != 0)
4088 /* Verify that all MACs are the same as first slave added to bonded
4090 for (i = 0; i < test_params->bonded_slave_count; i++) {
4091 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4092 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
4093 sizeof(read_mac_addr))) {
4094 printf("slave port (%d) mac address not set to that of primary port\n",
4095 test_params->slave_port_ids[i]);
4100 /* change primary and verify that MAC addresses haven't changed */
4101 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
4102 test_params->slave_port_ids[2]);
4104 printf("Failed to set bonded port (%d) primary port to (%d)\n",
4105 test_params->bonded_port_id, test_params->slave_port_ids[i]);
4109 for (i = 0; i < test_params->bonded_slave_count; i++) {
4110 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4111 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
4112 sizeof(read_mac_addr))) {
4113 printf("slave port (%d) mac address has changed to that of primary"
4114 "port without stop/start toggle of bonded device\n",
4115 test_params->slave_port_ids[i]);
4120 /* stop / start bonded device and verify that primary MAC address is
4121 * propagated to bonded device and slaves */
4123 rte_eth_dev_stop(test_params->bonded_port_id);
4125 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
4128 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4129 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
4130 printf("bonded port (%d) mac address not set to that of new primary"
4131 " port\n", test_params->slave_port_ids[i]);
4135 for (i = 0; i < test_params->bonded_slave_count; i++) {
4136 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4137 if (memcmp(&expected_mac_addr_1, &read_mac_addr,
4138 sizeof(read_mac_addr))) {
4139 printf("slave port (%d) mac address not set to that of new primary"
4140 "port\n", test_params->slave_port_ids[i]);
4145 /* Set explicit MAC address */
4146 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
4147 (struct ether_addr *)bonded_mac) != 0)
4150 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4151 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
4152 printf("bonded port (%d) mac address not set to that of new primary port\n",
4153 test_params->slave_port_ids[i]);
4157 for (i = 0; i < test_params->bonded_slave_count; i++) {
4158 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4159 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
4160 printf("slave port (%d) mac address not set to that of new primary port\n",
4161 test_params->slave_port_ids[i]);
4166 /* Clean up and remove slaves from bonded device */
4167 return remove_slaves_and_stop_bonded_device();
4170 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
4172 test_broadcast_verify_slave_link_status_change_behaviour(void)
4174 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
4175 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4176 struct rte_eth_stats port_stats;
4178 uint8_t slaves[RTE_MAX_ETHPORTS];
4180 int i, j, burst_size, slave_count;
4182 memset(pkt_burst, 0, sizeof(pkt_burst));
4184 /* Initialize bonded device with 4 slaves in round robin mode */
4185 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0,
4186 BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
4189 /* Verify Current Slaves Count /Active Slave Count is */
4190 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4192 if (slave_count != 4) {
4193 printf("Number of slaves (%d) is not as expected (%d).\n",
4198 slave_count = rte_eth_bond_active_slaves_get(
4199 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
4200 if (slave_count != 4) {
4201 printf("Number of active slaves (%d) is not as expected (%d).\n",
4206 /* Set 2 slaves link status to down */
4207 virtual_ethdev_simulate_link_status_interrupt(
4208 test_params->slave_port_ids[1], 0);
4209 virtual_ethdev_simulate_link_status_interrupt(
4210 test_params->slave_port_ids[3], 0);
4212 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4213 slaves, RTE_MAX_ETHPORTS);
4214 if (slave_count != 2) {
4215 printf("Number of active slaves (%d) is not as expected (%d).\n",
4220 for (i = 0; i < test_params->bonded_slave_count; i++)
4221 rte_eth_stats_reset(test_params->slave_port_ids[i]);
4223 /* Verify that pkts are not sent on slaves with link status down */
4226 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0) !=
4228 printf("generate_test_burst failed\n");
4232 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
4233 burst_size) != burst_size) {
4234 printf("rte_eth_tx_burst failed\n");
4238 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4239 if (port_stats.opackets != (uint64_t)(burst_size * slave_count)) {
4240 printf("(%d) port_stats.opackets (%d) not as expected (%d)\n",
4241 test_params->bonded_port_id, (int)port_stats.opackets,
4242 burst_size * slave_count);
4246 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4247 if (port_stats.opackets != (uint64_t)burst_size) {
4248 printf("(%d) port_stats.opackets not as expected\n",
4249 test_params->slave_port_ids[0]);
4253 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4254 if (port_stats.opackets != 0) {
4255 printf("(%d) port_stats.opackets not as expected\n",
4256 test_params->slave_port_ids[1]);
4260 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4261 if (port_stats.opackets != (uint64_t)burst_size) {
4262 printf("(%d) port_stats.opackets not as expected\n",
4263 test_params->slave_port_ids[2]);
4267 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4268 if (port_stats.opackets != 0) {
4269 printf("(%d) port_stats.opackets not as expected\n",
4270 test_params->slave_port_ids[3]);
4274 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4275 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0) !=
4280 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4281 &pkt_burst[i][0], burst_size);
4284 /* Verify that pkts are not received on slaves with link status down */
4286 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4288 burst_size + burst_size) {
4289 printf("rte_eth_rx_burst\n");
4293 /* Verify bonded device rx count */
4294 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4295 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
4296 printf("(%d) port_stats.ipackets not as expected\n",
4297 test_params->bonded_port_id);
4301 /* free mbufs allocate for rx testing */
4302 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4303 for (j = 0; j < MAX_PKT_BURST; j++) {
4304 if (pkt_burst[i][j] != NULL) {
4305 rte_pktmbuf_free(pkt_burst[i][j]);
4306 pkt_burst[i][j] = NULL;
4311 /* Clean up and remove slaves from bonded device */
4312 return remove_slaves_and_stop_bonded_device();
4317 test_reconfigure_bonded_device(void)
4319 test_params->nb_rx_q = 4;
4320 test_params->nb_tx_q = 4;
4322 if (configure_ethdev(test_params->bonded_port_id, 0, 0) != 0) {
4323 printf("failed to reconfigure bonded device");
4328 test_params->nb_rx_q = 2;
4329 test_params->nb_tx_q = 2;
4331 if (configure_ethdev(test_params->bonded_port_id, 0, 0) != 0) {
4332 printf("failed to reconfigure bonded device with less rx/tx queues");
4341 test_close_bonded_device(void)
4343 rte_eth_dev_close(test_params->bonded_port_id);
4348 testsuite_teardown(void)
4350 if (test_params->pkt_eth_hdr != NULL) {
4351 free(test_params->pkt_eth_hdr);
4352 test_params->pkt_eth_hdr = NULL;
4355 /* Clean up and remove slaves from bonded device */
4356 return remove_slaves_and_stop_bonded_device();
4360 static struct unit_test_suite link_bonding_test_suite = {
4361 .suite_name = "Link Bonding Unit Test Suite",
4362 .setup = test_setup,
4363 .teardown = testsuite_teardown,
4364 .unit_test_cases = {
4365 TEST_CASE(test_create_bonded_device),
4366 TEST_CASE(test_create_bonded_device_with_invalid_params),
4367 TEST_CASE(test_add_slave_to_bonded_device),
4368 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4369 TEST_CASE(test_remove_slave_from_bonded_device),
4370 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4371 TEST_CASE(test_get_slaves_from_bonded_device),
4372 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4373 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4374 TEST_CASE(test_start_bonded_device),
4375 TEST_CASE(test_stop_bonded_device),
4376 TEST_CASE(test_set_bonding_mode),
4377 TEST_CASE(test_set_primary_slave),
4378 TEST_CASE(test_set_explicit_bonded_mac),
4379 TEST_CASE(test_status_interrupt),
4380 TEST_CASE(test_adding_slave_after_bonded_device_started),
4381 TEST_CASE(test_roundrobin_tx_burst),
4382 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4383 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4384 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4385 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4386 TEST_CASE(test_roundrobin_verify_mac_assignment),
4387 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4388 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4389 TEST_CASE(test_activebackup_tx_burst),
4390 TEST_CASE(test_activebackup_rx_burst),
4391 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4392 TEST_CASE(test_activebackup_verify_mac_assignment),
4393 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4394 TEST_CASE(test_balance_xmit_policy_configuration),
4395 TEST_CASE(test_balance_l2_tx_burst),
4396 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4397 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4398 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4399 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4400 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4401 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4402 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4403 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4404 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4405 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4406 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4407 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4408 TEST_CASE(test_balance_rx_burst),
4409 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4410 TEST_CASE(test_balance_verify_mac_assignment),
4411 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4412 #ifdef RTE_MBUF_REFCNT
4413 TEST_CASE(test_broadcast_tx_burst),
4414 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4415 TEST_CASE(test_broadcast_rx_burst),
4416 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4417 TEST_CASE(test_broadcast_verify_mac_assignment),
4418 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4420 TEST_CASE(test_reconfigure_bonded_device),
4421 TEST_CASE(test_close_bonded_device),
4423 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
4429 test_link_bonding(void)
4431 return unit_test_suite_runner(&link_bonding_test_suite);
4434 static struct test_command link_bonding_cmd = {
4435 .command = "link_bonding_autotest",
4436 .callback = test_link_bonding,
4438 REGISTER_TEST_COMMAND(link_bonding_cmd);