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 if (rte_eth_dev_configure(port_id, test_params->nb_rx_q,
238 test_params->nb_tx_q, &default_pmd_conf) != 0) {
242 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++) {
243 if (rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
244 rte_eth_dev_socket_id(port_id), &rx_conf_default,
245 test_params->mbuf_pool) < 0) {
250 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++) {
251 if (rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
252 rte_eth_dev_socket_id(port_id), &tx_conf_default) < 0) {
253 printf("Failed to setup tx queue (%d).\n", q_id);
259 if (rte_eth_dev_start(port_id) < 0) {
260 printf("Failed to start device (%d).\n", port_id);
267 printf("Failed to configure ethdev %d\n", port_id);
271 static int slaves_initialized;
276 int i, retval, nb_mbuf_per_pool;
277 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
279 /* Allocate ethernet packet header with space for VLAN header */
280 if (test_params->pkt_eth_hdr == NULL) {
281 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
282 sizeof(struct vlan_hdr));
284 if (test_params->pkt_eth_hdr == NULL) {
285 printf("ethernet header struct allocation failed!\n");
290 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
291 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
292 if (test_params->mbuf_pool == NULL) {
293 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
294 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
295 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
297 if (test_params->mbuf_pool == NULL) {
298 printf("rte_mempool_create failed\n");
303 /* Create / Initialize virtual eth devs */
304 if (!slaves_initialized) {
305 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
306 char pmd_name[RTE_ETH_NAME_MAX_LEN];
308 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
310 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
312 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
313 mac_addr, rte_socket_id());
314 if (test_params->slave_port_ids[i] < 0) {
315 printf("Failed to create virtual virtual ethdev %s\n", pmd_name);
319 printf("Created virtual ethdev %s\n", pmd_name);
321 retval = configure_ethdev(test_params->slave_port_ids[i], 1, 0);
323 printf("Failed to configure virtual ethdev %s\n", pmd_name);
327 printf("Configured virtual ethdev %s\n", pmd_name);
329 slaves_initialized = 1;
336 test_create_bonded_device(void)
338 int current_slave_count;
340 uint8_t slaves[RTE_MAX_ETHPORTS];
342 /* Don't try to recreate bonded device if re-running test suite*/
343 if (test_params->bonded_port_id == -1) {
344 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
345 test_params->bonding_mode, rte_socket_id());
347 TEST_ASSERT(test_params->bonded_port_id >= 0,
348 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
350 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
351 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
354 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
355 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
356 test_params->bonded_port_id, test_params->bonding_mode);
358 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
359 slaves, RTE_MAX_ETHPORTS);
361 TEST_ASSERT(current_slave_count == 0,
362 "Number of slaves %d is great than expected %d.",
363 current_slave_count, 0);
365 current_slave_count = rte_eth_bond_active_slaves_get(
366 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
368 TEST_ASSERT(current_slave_count == 0,
369 "Number of active slaves %d is great than expected %d.",
370 current_slave_count, 0);
377 test_create_bonded_device_with_invalid_params(void)
381 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
384 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
387 printf("Created bonded device unexpectedly.\n");
391 test_params->bonding_mode = INVALID_BONDING_MODE;
393 /* Invalid bonding mode */
394 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
397 printf("Created bonded device unexpectedly.\n");
401 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
403 /* Invalid socket id */
404 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
407 printf("Created bonded device unexpectedly.\n");
415 test_add_slave_to_bonded_device(void)
417 int retval, current_slave_count;
419 uint8_t slaves[RTE_MAX_ETHPORTS];
421 retval = rte_eth_bond_slave_add(test_params->bonded_port_id,
422 test_params->slave_port_ids[test_params->bonded_slave_count]);
424 printf("Failed to add slave (%d) to bonded port (%d).\n",
425 test_params->bonded_port_id,
426 test_params->slave_port_ids[test_params->bonded_slave_count]);
430 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
431 slaves, RTE_MAX_ETHPORTS);
432 if (current_slave_count != test_params->bonded_slave_count + 1) {
433 printf("Number of slaves (%d) is greater than expected (%d).\n",
434 current_slave_count, test_params->bonded_slave_count + 1);
438 current_slave_count = rte_eth_bond_active_slaves_get(
439 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
440 if (current_slave_count != 0) {
441 printf("Number of active slaves (%d) is not as expected (%d).\n",
442 current_slave_count, 0);
446 test_params->bonded_slave_count++;
452 test_add_slave_to_invalid_bonded_device(void)
456 /* Invalid port ID */
457 retval = rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
458 test_params->slave_port_ids[test_params->bonded_slave_count]);
460 printf("Expected call to failed as invalid port specified.\n");
464 /* Non bonded device */
465 retval = rte_eth_bond_slave_add(test_params->slave_port_ids[0],
466 test_params->slave_port_ids[test_params->bonded_slave_count]);
468 printf("Expected call to failed as invalid port specified.\n");
477 test_remove_slave_from_bonded_device(void)
479 int retval, current_slave_count;
480 struct ether_addr read_mac_addr, *mac_addr;
481 uint8_t slaves[RTE_MAX_ETHPORTS];
483 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id,
484 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
486 printf("\t Failed to remove slave %d from bonded port (%d).\n",
487 test_params->slave_port_ids[test_params->bonded_slave_count-1],
488 test_params->bonded_port_id);
493 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
494 slaves, RTE_MAX_ETHPORTS);
495 if (current_slave_count != test_params->bonded_slave_count - 1) {
496 printf("Number of slaves (%d) is great than expected (%d).\n",
497 current_slave_count, 0);
502 mac_addr = (struct ether_addr *)slave_mac;
503 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
504 test_params->slave_port_ids[test_params->bonded_slave_count-1];
507 test_params->slave_port_ids[test_params->bonded_slave_count-1],
509 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
510 printf("bonded port mac address not set to that of primary port\n");
515 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
517 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
520 test_params->bonded_slave_count--;
526 test_remove_slave_from_invalid_bonded_device(void)
530 /* Invalid port ID */
531 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id + 5,
532 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
534 printf("Expected call to failed as invalid port specified.\n");
538 /* Non bonded device */
539 retval = rte_eth_bond_slave_remove(test_params->slave_port_ids[0],
540 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
542 printf("Expected call to failed as invalid port specified.\n");
549 static int bonded_id = 2;
552 test_add_already_bonded_slave_to_bonded_device(void)
554 int retval, port_id, current_slave_count;
555 uint8_t slaves[RTE_MAX_ETHPORTS];
556 char pmd_name[RTE_ETH_NAME_MAX_LEN];
558 test_add_slave_to_bonded_device();
560 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
561 slaves, RTE_MAX_ETHPORTS);
562 if (current_slave_count != 1) {
563 printf("Number of slaves (%d) is not that expected (%d).\n",
564 current_slave_count, 1);
568 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
570 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
573 printf("Failed to create bonded device.\n");
577 retval = rte_eth_bond_slave_add(port_id,
578 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
580 printf("Added slave (%d) to bonded port (%d) unexpectedly.\n",
581 test_params->slave_port_ids[test_params->bonded_slave_count-1],
586 return test_remove_slave_from_bonded_device();
591 test_get_slaves_from_bonded_device(void)
593 int retval, current_slave_count;
595 uint8_t slaves[RTE_MAX_ETHPORTS];
597 retval = test_add_slave_to_bonded_device();
601 /* Invalid port id */
602 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
604 if (current_slave_count >= 0)
607 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
608 slaves, RTE_MAX_ETHPORTS);
609 if (current_slave_count >= 0)
612 /* Invalid slaves pointer */
613 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
614 NULL, RTE_MAX_ETHPORTS);
615 if (current_slave_count >= 0)
618 current_slave_count = rte_eth_bond_active_slaves_get(
619 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
620 if (current_slave_count >= 0)
623 /* non bonded device*/
624 current_slave_count = rte_eth_bond_slaves_get(
625 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
626 if (current_slave_count >= 0)
629 current_slave_count = rte_eth_bond_active_slaves_get(
630 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
631 if (current_slave_count >= 0)
634 retval = test_remove_slave_from_bonded_device();
643 test_add_remove_multiple_slaves_to_from_bonded_device(void)
647 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
648 if (test_add_slave_to_bonded_device() != 0)
652 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
653 if (test_remove_slave_from_bonded_device() != 0)
661 enable_bonded_slaves(void)
665 for (i = 0; i < test_params->bonded_slave_count; i++) {
666 virtual_ethdev_simulate_link_status_interrupt(
667 test_params->slave_port_ids[i], 1);
672 test_start_bonded_device(void)
674 struct rte_eth_link link_status;
676 int current_slave_count, current_bonding_mode, primary_port;
677 uint8_t slaves[RTE_MAX_ETHPORTS];
679 /* Add slave to bonded device*/
680 if (test_add_slave_to_bonded_device() != 0)
683 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
684 "Failed to start bonded pmd eth device %d.",
685 test_params->bonded_port_id);
687 /* Change link status of virtual pmd so it will be added to the active
688 * slave list of the bonded device*/
689 virtual_ethdev_simulate_link_status_interrupt(
690 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
692 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
693 slaves, RTE_MAX_ETHPORTS);
694 if (current_slave_count != test_params->bonded_slave_count) {
695 printf("Number of slaves (%d) is not expected value (%d).\n",
696 current_slave_count, test_params->bonded_slave_count);
700 current_slave_count = rte_eth_bond_active_slaves_get(
701 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
702 if (current_slave_count != test_params->bonded_slave_count) {
703 printf("Number of active slaves (%d) is not expected value (%d).\n",
704 current_slave_count, test_params->bonded_slave_count);
708 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
709 if (current_bonding_mode != test_params->bonding_mode) {
710 printf("Bonded device mode (%d) is not expected value (%d).\n",
711 current_bonding_mode, test_params->bonding_mode);
716 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
717 if (primary_port != test_params->slave_port_ids[0]) {
718 printf("Primary port (%d) is not expected value (%d).\n",
719 primary_port, test_params->slave_port_ids[0]);
724 rte_eth_link_get(test_params->bonded_port_id, &link_status);
725 if (!link_status.link_status) {
726 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
727 test_params->bonded_port_id, link_status.link_status, 1);
736 test_stop_bonded_device(void)
738 int current_slave_count;
739 uint8_t slaves[RTE_MAX_ETHPORTS];
741 struct rte_eth_link link_status;
743 rte_eth_dev_stop(test_params->bonded_port_id);
745 rte_eth_link_get(test_params->bonded_port_id, &link_status);
746 if (link_status.link_status) {
747 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
748 test_params->bonded_port_id, link_status.link_status, 0);
752 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
753 slaves, RTE_MAX_ETHPORTS);
754 if (current_slave_count != test_params->bonded_slave_count) {
755 printf("Number of slaves (%d) is not expected value (%d).\n",
756 current_slave_count, test_params->bonded_slave_count);
760 current_slave_count = rte_eth_bond_active_slaves_get(
761 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
762 if (current_slave_count != 0) {
763 printf("Number of active slaves (%d) is not expected value (%d).\n",
764 current_slave_count, 0);
771 static int remove_slaves_and_stop_bonded_device(void)
773 /* Clean up and remove slaves from bonded device */
774 while (test_params->bonded_slave_count > 0) {
775 if (test_remove_slave_from_bonded_device() != 0) {
776 printf("test_remove_slave_from_bonded_device failed\n");
781 rte_eth_dev_stop(test_params->bonded_port_id);
782 rte_eth_stats_reset(test_params->bonded_port_id);
783 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
789 test_set_bonding_mode(void)
792 int retval, bonding_mode;
794 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
795 BONDING_MODE_ACTIVE_BACKUP,
796 BONDING_MODE_BALANCE,
797 #ifdef RTE_MBUF_REFCNT
798 BONDING_MODE_BROADCAST
802 /* Test supported link bonding modes */
803 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
804 /* Invalid port ID */
805 retval = rte_eth_bond_mode_set(INVALID_PORT_ID, bonding_modes[i]);
807 printf("Expected call to failed as invalid port (%d) specified.\n",
812 /* Non bonded device */
813 retval = rte_eth_bond_mode_set(test_params->slave_port_ids[0],
816 printf("Expected call to failed as invalid port (%d) specified.\n",
817 test_params->slave_port_ids[0]);
821 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
824 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
825 test_params->bonded_port_id, bonding_modes[i]);
829 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
830 if (bonding_mode != bonding_modes[i]) {
831 printf("Link bonding mode (%d) of port (%d) is not expected value (%d).\n",
832 bonding_mode, test_params->bonded_port_id,
838 /* Invalid port ID */
839 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
840 if (bonding_mode >= 0) {
841 printf("Expected call to failed as invalid port (%d) specified.\n",
847 /* Non bonded device */
848 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
849 if (bonding_mode >= 0) {
850 printf("Expected call to failed as invalid port (%d) specified.\n",
851 test_params->slave_port_ids[0]);
857 return remove_slaves_and_stop_bonded_device();
861 test_set_primary_slave(void)
864 struct ether_addr read_mac_addr;
865 struct ether_addr *expected_mac_addr;
867 /* Add 4 slaves to bonded device */
868 for (i = test_params->bonded_slave_count; i < 4; i++) {
869 retval = test_add_slave_to_bonded_device();
871 printf("Failed to add slave to bonded device.\n");
875 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
876 BONDING_MODE_ROUND_ROBIN);
878 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
879 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
883 /* Invalid port ID */
884 retval = rte_eth_bond_primary_set(INVALID_PORT_ID,
885 test_params->slave_port_ids[i]);
887 printf("Expected call to failed as invalid port specified.\n");
891 /* Set slave as primary
892 * Verify slave it is now primary slave
893 * Verify that MAC address of bonded device is that of primary slave
894 * Verify that MAC address of all bonded slaves are that of primary slave
896 for (i = 0; i < 4; i++) {
898 /* Non bonded device */
899 retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
900 test_params->slave_port_ids[i]);
902 printf("Expected call to failed as invalid port specified.\n");
906 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
907 test_params->slave_port_ids[i]);
909 printf("Failed to set bonded port (%d) primary port to (%d)\n",
910 test_params->bonded_port_id,
911 test_params->slave_port_ids[i]);
915 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
917 printf("Failed to read primary port from bonded port (%d)\n",
918 test_params->bonded_port_id);
920 } else if (retval != test_params->slave_port_ids[i]) {
921 printf("Bonded port (%d) primary port (%d) not expected value (%d)\n",
922 test_params->bonded_port_id, retval,
923 test_params->slave_port_ids[i]);
927 /* stop/start bonded eth dev to apply new MAC */
928 rte_eth_dev_stop(test_params->bonded_port_id);
929 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
932 expected_mac_addr = (struct ether_addr *)&slave_mac;
933 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
934 test_params->slave_port_ids[i];
936 /* Check primary slave MAC */
937 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
938 if (memcmp(expected_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
939 printf("bonded port mac address not set to that of primary port\n");
943 /* Check bonded MAC */
944 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
945 if (memcmp(&read_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
946 printf("bonded port mac address not set to that of primary port\n");
950 /* Check other slaves MACs */
951 for (j = 0; j < 4; j++) {
953 rte_eth_macaddr_get(test_params->slave_port_ids[j],
955 if (memcmp(expected_mac_addr, &read_mac_addr,
956 sizeof(read_mac_addr))) {
957 printf("slave port mac address not set to that of primary port\n");
965 /* Test with none existent port */
966 retval = rte_eth_bond_primary_get(test_params->bonded_port_id + 10);
968 printf("read primary port from expectedly\n");
972 /* Test with slave port */
973 retval = rte_eth_bond_primary_get(test_params->slave_port_ids[0]);
975 printf("read primary port from expectedly\n");
979 if (remove_slaves_and_stop_bonded_device() != 0)
983 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
985 printf("read primary port from expectedly\n");
993 test_set_explicit_bonded_mac(void)
996 struct ether_addr read_mac_addr;
997 struct ether_addr *mac_addr;
999 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
1001 mac_addr = (struct ether_addr *)explicit_bonded_mac;
1003 /* Invalid port ID */
1004 retval = rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr);
1006 printf("Expected call to failed as invalid port specified.\n");
1010 /* Non bonded device */
1011 retval = rte_eth_bond_mac_address_set(test_params->slave_port_ids[0],
1014 printf("Expected call to failed as invalid port specified.\n");
1018 /* NULL MAC address */
1019 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id, NULL);
1021 printf("Expected call to failed as NULL MAC specified\n");
1025 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1028 printf("Failed to set MAC address on bonded port (%d)\n",
1029 test_params->bonded_port_id);
1033 /* Add 4 slaves to bonded device */
1034 for (i = test_params->bonded_slave_count; i < 4; i++) {
1035 retval = test_add_slave_to_bonded_device();
1037 printf("Failed to add slave to bonded device.\n");
1042 /* Check bonded MAC */
1043 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1044 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1045 printf("bonded port mac address not set to that of primary port\n");
1049 /* Check other slaves MACs */
1050 for (i = 0; i < 4; i++) {
1051 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1052 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1053 printf("slave port mac address not set to that of primary port\n");
1058 /* test resetting mac address on bonded device */
1059 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1060 printf("Failed to reset MAC address on bonded port (%d)\n",
1061 test_params->bonded_port_id);
1066 if (rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]) == 0) {
1067 printf("Reset MAC address on bonded port (%d) unexpectedly\n",
1068 test_params->slave_port_ids[1]);
1073 /* test resetting mac address on bonded device with no slaves */
1075 if (remove_slaves_and_stop_bonded_device() != 0)
1078 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1079 printf("Failed to reset MAC address on bonded port (%d)\n",
1080 test_params->bonded_port_id);
1090 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1091 uint8_t number_of_slaves, uint8_t enable_slave)
1093 /* configure bonded device */
1094 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1095 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1096 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1099 while (number_of_slaves > test_params->bonded_slave_count) {
1100 /* Add slaves to bonded device */
1101 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1102 "Failed to add slave (%d to bonding port (%d).",
1103 test_params->bonded_slave_count - 1,
1104 test_params->bonded_port_id);
1107 /* Set link bonding mode */
1108 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1110 "Failed to set link bonding mode on port (%d) to (%d).",
1111 test_params->bonded_port_id, bonding_mode);
1113 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1114 "Failed to start bonded pmd eth device %d.",
1115 test_params->bonded_port_id);
1118 enable_bonded_slaves();
1124 test_adding_slave_after_bonded_device_started(void)
1128 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 0)
1132 /* Enabled slave devices */
1133 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1134 virtual_ethdev_simulate_link_status_interrupt(
1135 test_params->slave_port_ids[i], 1);
1138 if (rte_eth_bond_slave_add(test_params->bonded_port_id,
1139 test_params->slave_port_ids[test_params->bonded_slave_count]) !=
1141 printf("\t Failed to add slave to bonded port.\n");
1145 rte_eth_stats_reset(
1146 test_params->slave_port_ids[test_params->bonded_slave_count]);
1148 test_params->bonded_slave_count++;
1150 return remove_slaves_and_stop_bonded_device();
1153 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1154 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1156 int test_lsc_interrupt_count;
1158 static pthread_mutex_t mutex;
1159 static pthread_cond_t cvar;
1162 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1163 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1165 pthread_mutex_lock(&mutex);
1166 test_lsc_interrupt_count++;
1168 pthread_cond_signal(&cvar);
1169 pthread_mutex_unlock(&mutex);
1173 lsc_timeout(int wait_us)
1180 gettimeofday(&tp, NULL);
1182 /* Convert from timeval to timespec */
1183 ts.tv_sec = tp.tv_sec;
1184 ts.tv_nsec = tp.tv_usec * 1000;
1185 ts.tv_nsec += wait_us * 1000;
1187 pthread_mutex_lock(&mutex);
1188 if (test_lsc_interrupt_count < 1)
1189 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1191 pthread_mutex_unlock(&mutex);
1197 test_status_interrupt(void)
1200 uint8_t slaves[RTE_MAX_ETHPORTS];
1202 pthread_mutex_init(&mutex, NULL);
1203 pthread_cond_init(&cvar, NULL);
1205 /* initialized bonding device with T slaves */
1206 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 1,
1207 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1) != 0)
1210 test_lsc_interrupt_count = 0;
1212 /* register link status change interrupt callback */
1213 rte_eth_dev_callback_register(test_params->bonded_port_id,
1214 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1215 &test_params->bonded_port_id);
1217 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1218 slaves, RTE_MAX_ETHPORTS);
1220 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1221 "Number of active slaves (%d) is not as expected (%d)",
1222 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1224 /* Bring all 4 slaves link status to down and test that we have received a
1226 virtual_ethdev_simulate_link_status_interrupt(
1227 test_params->slave_port_ids[0], 0);
1228 virtual_ethdev_simulate_link_status_interrupt(
1229 test_params->slave_port_ids[1], 0);
1230 virtual_ethdev_simulate_link_status_interrupt(
1231 test_params->slave_port_ids[2], 0);
1233 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1234 "Received a link status change interrupt unexpectedly");
1236 virtual_ethdev_simulate_link_status_interrupt(
1237 test_params->slave_port_ids[3], 0);
1239 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1240 "timed out waiting for interrupt");
1242 TEST_ASSERT(test_lsc_interrupt_count > 0,
1243 "Did not receive link status change interrupt");
1245 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1246 slaves, RTE_MAX_ETHPORTS);
1248 TEST_ASSERT_EQUAL(slave_count, 0,
1249 "Number of active slaves (%d) is not as expected (%d)",
1252 /* bring one slave port up so link status will change */
1253 test_lsc_interrupt_count = 0;
1255 virtual_ethdev_simulate_link_status_interrupt(
1256 test_params->slave_port_ids[0], 1);
1258 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1259 "timed out waiting for interrupt");
1261 /* test that we have received another lsc interrupt */
1262 TEST_ASSERT(test_lsc_interrupt_count > 0,
1263 "Did not receive link status change interrupt");
1265 /* Verify that calling the same slave lsc interrupt doesn't cause another
1266 * lsc interrupt from bonded device */
1267 test_lsc_interrupt_count = 0;
1269 virtual_ethdev_simulate_link_status_interrupt(
1270 test_params->slave_port_ids[0], 1);
1272 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1273 "received unexpected interrupt");
1275 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1276 "Did not receive link status change interrupt");
1279 /* unregister lsc callback before exiting */
1280 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1281 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1282 &test_params->bonded_port_id);
1284 pthread_mutex_destroy(&mutex);
1285 pthread_cond_destroy(&cvar);
1287 /* Clean up and remove slaves from bonded device */
1288 return remove_slaves_and_stop_bonded_device();
1292 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1293 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1294 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1296 uint16_t pktlen, generated_burst_size;
1300 initialize_eth_header(test_params->pkt_eth_hdr,
1301 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1304 initialize_eth_header(test_params->pkt_eth_hdr,
1305 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1309 if (toggle_udp_port)
1310 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1313 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1318 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1319 dst_addr_1, pktlen);
1321 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1322 dst_addr_0, pktlen);
1324 ip_hdr = test_params->pkt_ipv4_hdr;
1327 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1328 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1331 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1332 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1335 ip_hdr = test_params->pkt_ipv6_hdr;
1338 /* Generate burst of packets to transmit */
1339 generated_burst_size =
1340 generate_packet_burst(test_params->mbuf_pool,
1341 pkts_burst, test_params->pkt_eth_hdr,
1343 test_params->pkt_udp_hdr, burst_size,
1344 PACKET_BURST_GEN_PKT_LEN_128, 1);
1345 if (generated_burst_size != burst_size) {
1346 printf("Failed to generate packet burst");
1350 return generated_burst_size;
1353 /** Round Robin Mode Tests */
1356 test_roundrobin_tx_burst(void)
1358 int i, burst_size, nb_tx;
1359 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1360 struct rte_eth_stats port_stats;
1362 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 2, 1)
1366 burst_size = 20 * test_params->bonded_slave_count;
1368 if (burst_size > MAX_PKT_BURST) {
1369 printf("Burst size specified is greater than supported.\n");
1373 /* Generate test bursts of packets to transmit */
1374 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size)
1377 /* Send burst on bonded port */
1378 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1380 if (nb_tx != burst_size)
1383 /* Verify bonded port tx stats */
1384 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1385 if (port_stats.opackets != (uint64_t)burst_size) {
1386 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1387 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1392 /* Verify slave ports tx stats */
1393 for (i = 0; i < test_params->bonded_slave_count; i++) {
1394 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1395 if (port_stats.opackets !=
1396 (uint64_t)burst_size / test_params->bonded_slave_count) {
1397 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1398 test_params->bonded_port_id,
1399 (unsigned int)port_stats.opackets,
1400 burst_size / test_params->bonded_slave_count);
1405 /* Put all slaves down and try and transmit */
1406 for (i = 0; i < test_params->bonded_slave_count; i++) {
1407 virtual_ethdev_simulate_link_status_interrupt(
1408 test_params->slave_port_ids[i], 0);
1411 /* Send burst on bonded port */
1412 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1417 /* Clean up and remove slaves from bonded device */
1418 return remove_slaves_and_stop_bonded_device();
1422 test_roundrobin_rx_burst_on_single_slave(void)
1424 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1425 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1427 struct rte_eth_stats port_stats;
1429 int i, j, nb_rx, burst_size = 25;
1431 /* Initialize bonded device with 4 slaves in round robin mode */
1432 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1436 /* Generate test bursts of packets to transmit */
1437 if (generate_test_burst(gen_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1441 for (i = 0; i < test_params->bonded_slave_count; i++) {
1442 /* Add rx data to slave */
1443 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1444 &gen_pkt_burst[0], burst_size);
1446 /* Call rx burst on bonded device */
1447 /* Send burst on bonded port */
1448 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1450 if (nb_rx != burst_size) {
1451 printf("round-robin rx burst failed");
1455 /* Verify bonded device rx count */
1456 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1457 if (port_stats.ipackets != (uint64_t)burst_size) {
1458 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1459 test_params->bonded_port_id,
1460 (unsigned int)port_stats.ipackets, burst_size);
1465 /* Verify bonded slave devices rx count */
1466 /* Verify slave ports tx stats */
1467 for (j = 0; j < test_params->bonded_slave_count; j++) {
1468 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1471 if (port_stats.ipackets != (uint64_t)burst_size) {
1472 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1473 test_params->slave_port_ids[i],
1474 (unsigned int)port_stats.ipackets, burst_size);
1478 if (port_stats.ipackets != 0) {
1479 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1480 test_params->slave_port_ids[i],
1481 (unsigned int)port_stats.ipackets, 0);
1486 /* Reset bonded slaves stats */
1487 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1489 /* reset bonded device stats */
1490 rte_eth_stats_reset(test_params->bonded_port_id);
1494 for (i = 0; i < MAX_PKT_BURST; i++) {
1495 if (gen_pkt_burst[i] != NULL)
1496 rte_pktmbuf_free(gen_pkt_burst[i]);
1498 if (rx_pkt_burst[i] != NULL)
1499 rte_pktmbuf_free(rx_pkt_burst[i]);
1503 /* Clean up and remove slaves from bonded device */
1504 return remove_slaves_and_stop_bonded_device();
1507 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1510 test_roundrobin_rx_burst_on_multiple_slaves(void)
1512 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1514 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1515 struct rte_eth_stats port_stats;
1517 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1521 /* Initialize bonded device with 4 slaves in round robin mode */
1522 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1526 /* Generate test bursts of packets to transmit */
1527 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1528 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0,
1529 0) != burst_size[i])
1533 /* Add rx data to slaves */
1534 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1535 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1536 &gen_pkt_burst[i][0], burst_size[i]);
1539 /* Call rx burst on bonded device */
1540 /* Send burst on bonded port */
1541 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1543 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
1544 printf("round-robin rx burst failed (%d != %d)\n", nb_rx,
1545 burst_size[0] + burst_size[1] + burst_size[2]);
1549 /* Verify bonded device rx count */
1550 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1551 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
1553 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1554 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1555 burst_size[0] + burst_size[1] + burst_size[2]);
1560 /* Verify bonded slave devices rx counts */
1561 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1562 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
1563 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1564 test_params->slave_port_ids[0],
1565 (unsigned int)port_stats.ipackets, burst_size[0]);
1569 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1570 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
1571 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1572 test_params->slave_port_ids[1],
1573 (unsigned int)port_stats.ipackets, burst_size[1]);
1577 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1578 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
1579 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1580 test_params->slave_port_ids[2],
1581 (unsigned int)port_stats.ipackets, burst_size[2]);
1585 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1586 if (port_stats.ipackets != 0) {
1587 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1588 test_params->slave_port_ids[3],
1589 (unsigned int)port_stats.ipackets, 0);
1594 for (i = 0; i < MAX_PKT_BURST; i++) {
1595 if (rx_pkt_burst[i] != NULL)
1596 rte_pktmbuf_free(rx_pkt_burst[i]);
1599 /* Clean up and remove slaves from bonded device */
1600 return remove_slaves_and_stop_bonded_device();
1604 test_roundrobin_verify_mac_assignment(void)
1606 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1610 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1611 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1613 /* Initialize bonded device with 4 slaves in round robin mode */
1614 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1)
1618 /* Verify that all MACs are the same as first slave added to bonded dev */
1619 for (i = 0; i < test_params->bonded_slave_count; i++) {
1620 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1621 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1622 sizeof(read_mac_addr))) {
1623 printf("slave port (%d) mac address not set to that of primary port\n",
1624 test_params->slave_port_ids[i]);
1629 /* change primary and verify that MAC addresses haven't changed */
1630 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
1631 test_params->slave_port_ids[2]);
1633 printf("Failed to set bonded port (%d) primary port to (%d)\n",
1634 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1638 for (i = 0; i < test_params->bonded_slave_count; i++) {
1639 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1640 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1641 sizeof(read_mac_addr))) {
1642 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
1643 test_params->slave_port_ids[i]);
1648 /* stop / start bonded device and verify that primary MAC address is
1649 * propagate to bonded device and slaves */
1651 rte_eth_dev_stop(test_params->bonded_port_id);
1653 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
1656 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1657 if (memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr))) {
1658 printf("bonded port (%d) mac address not set to that of new primary port\n",
1659 test_params->slave_port_ids[i]);
1663 for (i = 0; i < test_params->bonded_slave_count; i++) {
1664 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1665 if (memcmp(&expected_mac_addr_2, &read_mac_addr,
1666 sizeof(read_mac_addr))) {
1667 printf("slave port (%d) mac address not set to that of new primary port\n",
1668 test_params->slave_port_ids[i]);
1673 /* Set explicit MAC address */
1674 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1675 (struct ether_addr *)bonded_mac) != 0) {
1679 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1680 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1681 printf("bonded port (%d) mac address not set to that of new primary port\n",
1682 test_params->slave_port_ids[i]);
1686 for (i = 0; i < test_params->bonded_slave_count; i++) {
1687 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1688 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1689 printf("slave port (%d) mac address not set to that of new primary port\n",
1690 test_params->slave_port_ids[i]);
1695 /* Clean up and remove slaves from bonded device */
1696 return remove_slaves_and_stop_bonded_device();
1700 test_roundrobin_verify_promiscuous_enable_disable(void)
1702 int i, promiscuous_en;
1704 /* Initialize bonded device with 4 slaves in round robin mode */
1705 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1709 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1711 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1712 if (promiscuous_en != 1) {
1713 printf("Port (%d) promiscuous mode not enabled\n",
1714 test_params->bonded_port_id);
1718 for (i = 0; i < test_params->bonded_slave_count; i++) {
1719 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1720 if (promiscuous_en != 1) {
1721 printf("slave port (%d) promiscuous mode not enabled\n",
1722 test_params->slave_port_ids[i]);
1727 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1729 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1730 if (promiscuous_en != 0) {
1731 printf("Port (%d) promiscuous mode not disabled\n",
1732 test_params->bonded_port_id);
1736 for (i = 0; i < test_params->bonded_slave_count; i++) {
1737 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1738 if (promiscuous_en != 0) {
1739 printf("slave port (%d) promiscuous mode not disabled\n",
1740 test_params->slave_port_ids[i]);
1745 /* Clean up and remove slaves from bonded device */
1746 return remove_slaves_and_stop_bonded_device();
1749 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1750 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1753 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1755 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1756 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1757 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1759 struct rte_eth_stats port_stats;
1760 uint8_t slaves[RTE_MAX_ETHPORTS];
1762 int i, burst_size, slave_count;
1764 /* NULL all pointers in array to simplify cleanup */
1765 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1767 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1768 * in round robin mode */
1769 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0,
1770 TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
1773 /* Verify Current Slaves Count /Active Slave Count is */
1774 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1776 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1777 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
1778 TEST_RR_LINK_STATUS_SLAVE_COUNT);
1782 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1783 slaves, RTE_MAX_ETHPORTS);
1784 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1785 printf("Number of active slaves (%d) is not as expected (%d).\n",
1786 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1790 /* Set 2 slaves eth_devs link status to down */
1791 virtual_ethdev_simulate_link_status_interrupt(
1792 test_params->slave_port_ids[1], 0);
1793 virtual_ethdev_simulate_link_status_interrupt(
1794 test_params->slave_port_ids[3], 0);
1796 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1797 slaves, RTE_MAX_ETHPORTS) !=
1798 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) {
1799 printf("Number of active slaves (%d) is not as expected (%d).\n",
1800 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1806 /* Verify that pkts are not sent on slaves with link status down:
1808 * 1. Generate test burst of traffic
1809 * 2. Transmit burst on bonded eth_dev
1810 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1811 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1813 if (generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1815 printf("generate_test_burst failed\n");
1819 rte_eth_stats_reset(test_params->bonded_port_id);
1821 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1822 burst_size) != burst_size) {
1823 printf("rte_eth_tx_burst failed\n");
1827 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1828 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1829 "Port (%d) opackets stats (%d) not expected (%d) value",
1830 test_params->bonded_port_id, (int)port_stats.opackets,
1833 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1834 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1835 "Port (%d) opackets stats (%d) not expected (%d) value",
1836 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1838 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1839 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1840 "Port (%d) opackets stats (%d) not expected (%d) value",
1841 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1843 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1844 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1845 "Port (%d) opackets stats (%d) not expected (%d) value",
1846 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1848 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1849 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1850 "Port (%d) opackets stats (%d) not expected (%d) value",
1851 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1853 /* Verify that pkts are not sent on slaves with link status down:
1855 * 1. Generate test bursts of traffic
1856 * 2. Add bursts on to virtual eth_devs
1857 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1858 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1859 * 4. Verify stats for bonded eth_dev
1860 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1862 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1863 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0)
1867 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1868 &gen_pkt_burst[i][0], burst_size);
1871 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1872 MAX_PKT_BURST) != burst_size + burst_size) {
1873 printf("rte_eth_rx_burst\n");
1877 /* Verify bonded device rx count */
1878 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1879 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
1880 printf("(%d) port_stats.ipackets not as expected\n",
1881 test_params->bonded_port_id);
1886 for (i = 0; i < MAX_PKT_BURST; i++) {
1887 if (rx_pkt_burst[i] != NULL)
1888 rte_pktmbuf_free(rx_pkt_burst[i]);
1890 if (gen_pkt_burst[1][i] != NULL)
1891 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1893 if (gen_pkt_burst[3][i] != NULL)
1894 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1897 /* Clean up and remove slaves from bonded device */
1898 return remove_slaves_and_stop_bonded_device();
1901 /** Active Backup Mode Tests */
1904 test_activebackup_tx_burst(void)
1906 int i, retval, pktlen, primary_port, burst_size, generated_burst_size, nb_tx;
1907 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1908 struct rte_eth_stats port_stats;
1910 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1);
1912 printf("Failed to initialize_bonded_device_with_slaves.\n");
1916 initialize_eth_header(test_params->pkt_eth_hdr,
1917 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
1918 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1920 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1921 dst_addr_0, pktlen);
1923 burst_size = 20 * test_params->bonded_slave_count;
1925 if (burst_size > MAX_PKT_BURST) {
1926 printf("Burst size specified is greater than supported.\n");
1930 /* Generate a burst of packets to transmit */
1931 generated_burst_size =
1932 generate_packet_burst(test_params->mbuf_pool,
1933 pkts_burst, test_params->pkt_eth_hdr, 0,
1934 test_params->pkt_ipv4_hdr, 1,
1935 test_params->pkt_udp_hdr, burst_size,
1936 PACKET_BURST_GEN_PKT_LEN, 1);
1937 if (generated_burst_size != burst_size)
1940 /* Send burst on bonded port */
1941 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1943 if (nb_tx != burst_size)
1946 /* Verify bonded port tx stats */
1947 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1948 if (port_stats.opackets != (uint64_t)burst_size) {
1949 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1950 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1955 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1957 /* Verify slave ports tx stats */
1958 for (i = 0; i < test_params->bonded_slave_count; i++) {
1959 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1960 if (test_params->slave_port_ids[i] == primary_port) {
1961 if (port_stats.opackets != (uint64_t)burst_size) {
1962 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1963 test_params->bonded_port_id,
1964 (unsigned int)port_stats.opackets,
1965 burst_size / test_params->bonded_slave_count);
1969 if (port_stats.opackets != 0) {
1970 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1971 test_params->bonded_port_id,
1972 (unsigned int)port_stats.opackets, 0);
1978 /* Put all slaves down and try and transmit */
1979 for (i = 0; i < test_params->bonded_slave_count; i++) {
1981 virtual_ethdev_simulate_link_status_interrupt(
1982 test_params->slave_port_ids[i], 0);
1985 /* Send burst on bonded port */
1986 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1991 /* Clean up and remove slaves from bonded device */
1992 return remove_slaves_and_stop_bonded_device();
1995 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
1998 test_activebackup_rx_burst(void)
2000 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2001 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2003 struct rte_eth_stats port_stats;
2007 int i, j, nb_rx, burst_size = 17;
2009 /* Initialize bonded device with 4 slaves in round robin mode */
2010 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2011 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2016 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2017 if (primary_port < 0) {
2018 printf("failed to get primary slave for bonded port (%d)",
2019 test_params->bonded_port_id);
2022 for (i = 0; i < test_params->bonded_slave_count; i++) {
2023 /* Generate test bursts of packets to transmit */
2024 if (generate_test_burst(&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0)
2029 /* Add rx data to slave */
2030 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2031 &gen_pkt_burst[0], burst_size);
2033 /* Call rx burst on bonded device */
2034 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
2035 &rx_pkt_burst[0], MAX_PKT_BURST);
2037 printf("rte_eth_rx_burst failed\n");
2041 if (test_params->slave_port_ids[i] == primary_port) {
2042 /* Verify bonded device rx count */
2043 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2044 if (port_stats.ipackets != (uint64_t)burst_size) {
2045 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2046 test_params->bonded_port_id,
2047 (unsigned int)port_stats.ipackets, burst_size);
2051 /* Verify bonded slave devices rx count */
2052 for (j = 0; j < test_params->bonded_slave_count; j++) {
2053 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2055 if (port_stats.ipackets != (uint64_t)burst_size) {
2056 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2057 test_params->slave_port_ids[i],
2058 (unsigned int)port_stats.ipackets, burst_size);
2062 if (port_stats.ipackets != 0) {
2063 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2064 test_params->slave_port_ids[i],
2065 (unsigned int)port_stats.ipackets, 0);
2071 for (j = 0; j < test_params->bonded_slave_count; j++) {
2072 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2073 if (port_stats.ipackets != 0) {
2074 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2075 test_params->slave_port_ids[i],
2076 (unsigned int)port_stats.ipackets, 0);
2083 for (i = 0; i < MAX_PKT_BURST; i++) {
2084 if (rx_pkt_burst[i] != NULL) {
2085 rte_pktmbuf_free(rx_pkt_burst[i]);
2086 rx_pkt_burst[i] = NULL;
2090 /* reset bonded device stats */
2091 rte_eth_stats_reset(test_params->bonded_port_id);
2094 /* Clean up and remove slaves from bonded device */
2095 return remove_slaves_and_stop_bonded_device();
2099 test_activebackup_verify_promiscuous_enable_disable(void)
2101 int i, primary_port, promiscuous_en;
2103 /* Initialize bonded device with 4 slaves in round robin mode */
2104 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1)
2108 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2109 if (primary_port < 0) {
2110 printf("failed to get primary slave for bonded port (%d)",
2111 test_params->bonded_port_id);
2114 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2116 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2117 if (promiscuous_en != 1) {
2118 printf("Port (%d) promiscuous mode not enabled\n",
2119 test_params->bonded_port_id);
2123 for (i = 0; i < test_params->bonded_slave_count; i++) {
2124 promiscuous_en = rte_eth_promiscuous_get(
2125 test_params->slave_port_ids[i]);
2126 if (primary_port == test_params->slave_port_ids[i]) {
2127 if (promiscuous_en != 1) {
2128 printf("slave port (%d) promiscuous mode not enabled\n",
2129 test_params->slave_port_ids[i]);
2133 if (promiscuous_en != 0) {
2134 printf("slave port (%d) promiscuous mode enabled\n",
2135 test_params->slave_port_ids[i]);
2142 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2144 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2145 if (promiscuous_en != 0) {
2146 printf("Port (%d) promiscuous mode not disabled\n",
2147 test_params->bonded_port_id);
2151 for (i = 0; i < test_params->bonded_slave_count; i++) {
2152 promiscuous_en = rte_eth_promiscuous_get(
2153 test_params->slave_port_ids[i]);
2154 if (promiscuous_en != 0) {
2155 printf("slave port (%d) promiscuous mode not disabled\n",
2156 test_params->slave_port_ids[i]);
2161 /* Clean up and remove slaves from bonded device */
2162 return remove_slaves_and_stop_bonded_device();
2166 test_activebackup_verify_mac_assignment(void)
2168 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2170 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2171 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2173 /* Initialize bonded device with 2 slaves in active backup mode */
2174 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1)
2178 /* Verify that bonded MACs is that of first slave and that the other slave
2179 * MAC hasn't been changed */
2180 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2181 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2182 printf("bonded port (%d) mac address not set to that of primary port\n",
2183 test_params->bonded_port_id);
2187 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2188 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2189 printf("slave port (%d) mac address not set to that of primary port\n",
2190 test_params->slave_port_ids[0]);
2194 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2195 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2196 printf("slave port (%d) mac address not as expected\n",
2197 test_params->slave_port_ids[1]);
2201 /* change primary and verify that MAC addresses haven't changed */
2202 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2203 test_params->slave_port_ids[1]) != 0) {
2204 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2205 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2209 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2210 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2211 printf("bonded port (%d) mac address not set to that of primary port\n",
2212 test_params->bonded_port_id);
2216 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2217 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2218 printf("slave port (%d) mac address not set to that of primary port\n",
2219 test_params->slave_port_ids[0]);
2223 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2224 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2225 printf("slave port (%d) mac address not as expected\n",
2226 test_params->slave_port_ids[1]);
2230 /* stop / start bonded device and verify that primary MAC address is
2231 * propagated to bonded device and slaves */
2233 rte_eth_dev_stop(test_params->bonded_port_id);
2235 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2238 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2239 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2240 printf("bonded port (%d) mac address not set to that of primary port\n",
2241 test_params->bonded_port_id);
2245 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2246 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2247 printf("slave port (%d) mac address not as expected\n",
2248 test_params->slave_port_ids[0]);
2252 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2253 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2254 printf("slave port (%d) mac address not set to that of primary port\n",
2255 test_params->slave_port_ids[1]);
2259 /* Set explicit MAC address */
2260 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
2261 (struct ether_addr *)bonded_mac) != 0) {
2265 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2266 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2267 printf("bonded port (%d) mac address not set to that of bonded port\n",
2268 test_params->bonded_port_id);
2272 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2273 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2274 printf("slave port (%d) mac address not as expected\n",
2275 test_params->slave_port_ids[0]);
2279 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2280 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2281 printf("slave port (%d) mac address not set to that of bonded port\n",
2282 test_params->slave_port_ids[1]);
2286 /* Clean up and remove slaves from bonded device */
2287 return remove_slaves_and_stop_bonded_device();
2291 test_activebackup_verify_slave_link_status_change_failover(void)
2293 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2294 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2295 struct rte_eth_stats port_stats;
2297 uint8_t slaves[RTE_MAX_ETHPORTS];
2299 int i, j, burst_size, slave_count, primary_port;
2303 memset(pkt_burst, 0, sizeof(pkt_burst));
2305 /* Generate packet burst for testing */
2306 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
2308 printf("generate_test_burst failed\n");
2312 /* Initialize bonded device with 4 slaves in round robin mode */
2313 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2314 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2318 /* Verify Current Slaves Count /Active Slave Count is */
2319 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2321 if (slave_count != 4) {
2322 printf("Number of slaves (%d) is not as expected (%d).\n",
2327 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2328 slaves, RTE_MAX_ETHPORTS);
2329 if (slave_count != 4) {
2330 printf("Number of active slaves (%d) is not as expected (%d).\n",
2335 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2336 if (primary_port != test_params->slave_port_ids[0])
2337 printf("Primary port not as expected");
2339 /* Bring 2 slaves down and verify active slave count */
2340 virtual_ethdev_simulate_link_status_interrupt(
2341 test_params->slave_port_ids[1], 0);
2342 virtual_ethdev_simulate_link_status_interrupt(
2343 test_params->slave_port_ids[3], 0);
2345 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2346 RTE_MAX_ETHPORTS) != 2) {
2347 printf("Number of active slaves (%d) is not as expected (%d).\n",
2352 virtual_ethdev_simulate_link_status_interrupt(
2353 test_params->slave_port_ids[1], 1);
2354 virtual_ethdev_simulate_link_status_interrupt(
2355 test_params->slave_port_ids[3], 1);
2358 /* Bring primary port down, verify that active slave count is 3 and primary
2360 virtual_ethdev_simulate_link_status_interrupt(
2361 test_params->slave_port_ids[0], 0);
2363 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2364 RTE_MAX_ETHPORTS) != 3) {
2365 printf("Number of active slaves (%d) is not as expected (%d).\n",
2370 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2371 if (primary_port != test_params->slave_port_ids[2])
2372 printf("Primary port not as expected");
2374 /* Verify that pkts are sent on new primary slave */
2376 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size)
2378 printf("rte_eth_tx_burst failed\n");
2382 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2383 if (port_stats.opackets != (uint64_t)burst_size) {
2384 printf("(%d) port_stats.opackets not as expected\n",
2385 test_params->slave_port_ids[2]);
2389 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2390 if (port_stats.opackets != 0) {
2391 printf("(%d) port_stats.opackets not as expected\n",
2392 test_params->slave_port_ids[0]);
2395 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2396 if (port_stats.opackets != 0) {
2397 printf("(%d) port_stats.opackets not as expected\n",
2398 test_params->slave_port_ids[1]);
2401 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2402 if (port_stats.opackets != 0) {
2403 printf("(%d) port_stats.opackets not as expected\n",
2404 test_params->slave_port_ids[3]);
2408 /* Generate packet burst for testing */
2410 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2411 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
2415 virtual_ethdev_add_mbufs_to_rx_queue(
2416 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2419 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2420 MAX_PKT_BURST) != burst_size) {
2421 printf("rte_eth_rx_burst\n");
2425 /* Verify bonded device rx count */
2426 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2427 if (port_stats.ipackets != (uint64_t)burst_size) {
2428 printf("(%d) port_stats.ipackets not as expected\n",
2429 test_params->bonded_port_id);
2433 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2434 if (port_stats.opackets != (uint64_t)burst_size) {
2435 printf("(%d) port_stats.opackets not as expected\n",
2436 test_params->slave_port_ids[2]);
2440 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2441 if (port_stats.opackets != 0) {
2442 printf("(%d) port_stats.opackets not as expected\n",
2443 test_params->slave_port_ids[0]);
2447 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2448 if (port_stats.opackets != 0) {
2449 printf("(%d) port_stats.opackets not as expected\n",
2450 test_params->slave_port_ids[1]);
2454 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2455 if (port_stats.opackets != 0) {
2456 printf("(%d) port_stats.opackets not as expected\n",
2457 test_params->slave_port_ids[3]);
2463 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2464 for (j = 0; j < MAX_PKT_BURST; j++) {
2465 if (pkt_burst[i][j] != NULL) {
2466 rte_pktmbuf_free(pkt_burst[i][j]);
2467 pkt_burst[i][j] = NULL;
2473 /* Clean up and remove slaves from bonded device */
2474 return remove_slaves_and_stop_bonded_device();
2477 /** Balance Mode Tests */
2480 test_balance_xmit_policy_configuration(void)
2484 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2487 printf("Failed to initialize_bonded_device_with_slaves.\n");
2491 /* Invalid port id */
2492 retval = rte_eth_bond_xmit_policy_set(INVALID_PORT_ID,
2493 BALANCE_XMIT_POLICY_LAYER2);
2495 printf("Expected call to failed as invalid port specified.\n");
2499 /* Set xmit policy on non bonded device */
2500 retval = rte_eth_bond_xmit_policy_set(test_params->slave_port_ids[0],
2501 BALANCE_XMIT_POLICY_LAYER2);
2503 printf("Expected call to failed as invalid port specified.\n");
2507 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2508 BALANCE_XMIT_POLICY_LAYER2);
2510 printf("Failed to set balance xmit policy.\n");
2513 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2514 BALANCE_XMIT_POLICY_LAYER2) {
2515 printf("balance xmit policy not as expected.\n");
2519 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2520 BALANCE_XMIT_POLICY_LAYER23);
2522 printf("Failed to set balance xmit policy.\n");
2525 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2526 BALANCE_XMIT_POLICY_LAYER23) {
2527 printf("balance xmit policy not as expected.\n");
2531 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2532 BALANCE_XMIT_POLICY_LAYER34);
2534 printf("Failed to set balance xmit policy.\n");
2537 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2538 BALANCE_XMIT_POLICY_LAYER34) {
2539 printf("balance xmit policy not as expected.\n");
2543 /* Invalid port id */
2544 if (rte_eth_bond_xmit_policy_get(INVALID_PORT_ID) >= 0)
2547 /* Clean up and remove slaves from bonded device */
2548 return remove_slaves_and_stop_bonded_device();
2551 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2554 test_balance_l2_tx_burst(void)
2556 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2557 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2562 struct rte_eth_stats port_stats;
2564 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
2565 TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1);
2567 printf("Failed to initialize_bonded_device_with_slaves.\n");
2571 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2572 BALANCE_XMIT_POLICY_LAYER2);
2574 printf("Failed to set balance xmit policy.\n");
2579 initialize_eth_header(test_params->pkt_eth_hdr,
2580 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2581 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2583 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2584 dst_addr_0, pktlen);
2586 /* Generate a burst 1 of packets to transmit */
2587 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2588 test_params->pkt_eth_hdr, 0,
2589 test_params->pkt_ipv4_hdr, 1,
2590 test_params->pkt_udp_hdr, burst_size[0],
2591 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[0])
2594 initialize_eth_header(test_params->pkt_eth_hdr,
2595 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2597 /* Generate a burst 2 of packets to transmit */
2598 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2599 test_params->pkt_eth_hdr, 0,
2600 test_params->pkt_ipv4_hdr, 1,
2601 test_params->pkt_udp_hdr, burst_size[1],
2602 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[1])
2605 /* Send burst 1 on bonded port */
2606 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2607 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[i][0],
2608 burst_size[i]) != burst_size[i])
2611 /* Verify bonded port tx stats */
2612 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2613 if (port_stats.opackets != (uint64_t)(burst_size[0] + burst_size[1])) {
2614 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2615 test_params->bonded_port_id,
2616 (unsigned int)port_stats.opackets, burst_size[0] + burst_size[1]);
2621 /* Verify slave ports tx stats */
2622 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2623 if (port_stats.opackets != (uint64_t)burst_size[0]) {
2624 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2625 test_params->slave_port_ids[0],
2626 (unsigned int)port_stats.opackets, burst_size[0]);
2630 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2631 if (port_stats.opackets != (uint64_t)burst_size[1]) {
2632 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2633 test_params->slave_port_ids[1], (
2634 unsigned int)port_stats.opackets, burst_size[1]);
2638 /* Put all slaves down and try and transmit */
2639 for (i = 0; i < test_params->bonded_slave_count; i++) {
2641 virtual_ethdev_simulate_link_status_interrupt(
2642 test_params->slave_port_ids[i], 0);
2645 /* Send burst on bonded port */
2646 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[0][0],
2647 burst_size[0]) != 0)
2650 /* Clean up and remove slaves from bonded device */
2651 return remove_slaves_and_stop_bonded_device();
2655 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2656 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2659 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2661 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2662 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2664 struct rte_eth_stats port_stats;
2666 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1);
2668 printf("Failed to initialize_bonded_device_with_slaves.\n");
2672 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2673 BALANCE_XMIT_POLICY_LAYER23);
2675 printf("Failed to set balance xmit policy.\n");
2682 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2683 printf("Burst size specified is greater than supported.\n");
2687 /* Generate test bursts of packets to transmit */
2688 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4,
2689 0, 0, 0) != burst_size_1)
2692 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2693 toggle_mac_addr, toggle_ip_addr, 0) != burst_size_2)
2696 /* Send burst 1 on bonded port */
2697 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2699 if (nb_tx_1 != burst_size_1)
2702 /* Send burst 2 on bonded port */
2703 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2705 if (nb_tx_2 != burst_size_2)
2708 /* Verify bonded port tx stats */
2709 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2710 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2711 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2712 test_params->bonded_port_id,
2713 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2717 /* Verify slave ports tx stats */
2718 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2719 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2720 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2721 test_params->slave_port_ids[0],
2722 (unsigned int)port_stats.opackets, nb_tx_1);
2726 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2727 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2728 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2729 test_params->slave_port_ids[1],
2730 (unsigned int)port_stats.opackets, nb_tx_2);
2734 /* Put all slaves down and try and transmit */
2735 for (i = 0; i < test_params->bonded_slave_count; i++) {
2737 virtual_ethdev_simulate_link_status_interrupt(
2738 test_params->slave_port_ids[i], 0);
2741 /* Send burst on bonded port */
2742 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2747 /* Clean up and remove slaves from bonded device */
2748 return remove_slaves_and_stop_bonded_device();
2752 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2754 return balance_l23_tx_burst(0, 1, 1, 0);
2758 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2760 return balance_l23_tx_burst(1, 1, 0, 1);
2764 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2766 return balance_l23_tx_burst(0, 0, 0, 1);
2770 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2772 return balance_l23_tx_burst(1, 0, 0, 1);
2776 test_balance_l23_tx_burst_toggle_mac_addr(void)
2778 return balance_l23_tx_burst(0, 0, 1, 0);
2782 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2783 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2784 uint8_t toggle_udp_port)
2787 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2789 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2790 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2792 struct rte_eth_stats port_stats;
2794 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1);
2796 printf("Failed to initialize_bonded_device_with_slaves.\n");
2800 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2801 BALANCE_XMIT_POLICY_LAYER34);
2803 printf("Failed to set balance xmit policy.\n");
2810 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2811 printf("Burst size specified is greater than supported.\n");
2815 /* Generate test bursts of packets to transmit */
2816 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0,
2817 0, 0) != burst_size_1)
2820 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2821 toggle_mac_addr, toggle_ip_addr, toggle_udp_port) != burst_size_2)
2824 /* Send burst 1 on bonded port */
2825 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2827 if (nb_tx_1 != burst_size_1)
2830 /* Send burst 2 on bonded port */
2831 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2833 if (nb_tx_2 != burst_size_2)
2837 /* Verify bonded port tx stats */
2838 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2839 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2840 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2841 test_params->bonded_port_id,
2842 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2846 /* Verify slave ports tx stats */
2847 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2848 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2849 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2850 test_params->slave_port_ids[0],
2851 (unsigned int)port_stats.opackets, nb_tx_1);
2855 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2856 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2857 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2858 test_params->slave_port_ids[1],
2859 (unsigned int)port_stats.opackets, nb_tx_2);
2863 /* Put all slaves down and try and transmit */
2864 for (i = 0; i < test_params->bonded_slave_count; i++) {
2866 virtual_ethdev_simulate_link_status_interrupt(
2867 test_params->slave_port_ids[i], 0);
2870 /* Send burst on bonded port */
2871 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2876 /* Clean up and remove slaves from bonded device */
2877 return remove_slaves_and_stop_bonded_device();
2881 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2883 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2887 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2889 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2893 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2895 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2899 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2901 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2905 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2907 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2911 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2913 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2916 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
2919 test_balance_rx_burst(void)
2921 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2923 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2924 struct rte_eth_stats port_stats;
2926 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
2929 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
2931 /* Initialize bonded device with 4 slaves in round robin mode */
2932 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 3, 1)
2936 /* Generate test bursts of packets to transmit */
2937 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2938 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
2939 0, 0) != burst_size[i])
2942 /* Add rx data to slaves */
2943 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2944 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2945 &gen_pkt_burst[i][0], burst_size[i]);
2948 /* Call rx burst on bonded device */
2949 /* Send burst on bonded port */
2950 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2952 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
2953 printf("balance rx burst failed\n");
2957 /* Verify bonded device rx count */
2958 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2959 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
2961 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2962 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
2963 burst_size[0] + burst_size[1] + burst_size[2]);
2968 /* Verify bonded slave devices rx counts */
2969 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2970 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
2971 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2972 test_params->slave_port_ids[0],
2973 (unsigned int)port_stats.ipackets, burst_size[0]);
2977 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2978 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
2979 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2980 test_params->slave_port_ids[1],
2981 (unsigned int)port_stats.ipackets, burst_size[1]);
2985 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2986 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
2987 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2988 test_params->slave_port_ids[2],
2989 (unsigned int)port_stats.ipackets, burst_size[2]);
2993 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2994 if (port_stats.ipackets != 0) {
2995 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2996 test_params->slave_port_ids[3],
2997 (unsigned int)port_stats.ipackets, 0);
3002 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3003 for (j = 0; j < MAX_PKT_BURST; j++) {
3004 if (gen_pkt_burst[i][j] != NULL) {
3005 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3006 gen_pkt_burst[i][j] = NULL;
3011 /* Clean up and remove slaves from bonded device */
3012 return remove_slaves_and_stop_bonded_device();
3016 test_balance_verify_promiscuous_enable_disable(void)
3018 int i, promiscuous_en;
3020 /* Initialize bonded device with 4 slaves in round robin mode */
3021 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) != 0)
3024 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3026 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3027 if (promiscuous_en != 1) {
3028 printf("Port (%d) promiscuous mode not enabled\n",
3029 test_params->bonded_port_id);
3033 for (i = 0; i < test_params->bonded_slave_count; i++) {
3034 promiscuous_en = rte_eth_promiscuous_get(
3035 test_params->slave_port_ids[i]);
3036 if (promiscuous_en != 1) {
3037 printf("slave port (%d) promiscuous mode not enabled\n",
3038 test_params->slave_port_ids[i]);
3043 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3045 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3046 if (promiscuous_en != 0) {
3047 printf("Port (%d) promiscuous mode not disabled\n",
3048 test_params->bonded_port_id);
3052 for (i = 0; i < test_params->bonded_slave_count; i++) {
3053 promiscuous_en = rte_eth_promiscuous_get(
3054 test_params->slave_port_ids[i]);
3055 if (promiscuous_en != 0) {
3056 printf("slave port (%d) promiscuous mode not disabled\n",
3057 test_params->slave_port_ids[i]);
3062 /* Clean up and remove slaves from bonded device */
3063 return remove_slaves_and_stop_bonded_device();
3067 test_balance_verify_mac_assignment(void)
3069 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3071 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3072 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3074 /* Initialize bonded device with 2 slaves in active backup mode */
3075 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1) != 0)
3078 /* Verify that bonded MACs is that of first slave and that the other slave
3079 * MAC hasn't been changed */
3080 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3081 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3082 printf("bonded port (%d) mac address not set to that of primary port\n",
3083 test_params->bonded_port_id);
3087 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3088 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3089 printf("slave port (%d) mac address not set to that of primary port\n",
3090 test_params->slave_port_ids[0]);
3094 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3095 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3096 printf("slave port (%d) mac address not set to that of primary port\n",
3097 test_params->slave_port_ids[1]);
3101 /* change primary and verify that MAC addresses haven't changed */
3102 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
3103 test_params->slave_port_ids[1]) != 0) {
3104 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3105 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3109 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3110 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3111 printf("bonded port (%d) mac address not set to that of primary port\n",
3112 test_params->bonded_port_id);
3116 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3117 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3118 printf("slave port (%d) mac address not set to that of primary port\n",
3119 test_params->slave_port_ids[0]);
3123 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3124 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3125 printf("slave port (%d) mac address not set to that of primary port\n",
3126 test_params->slave_port_ids[1]);
3130 /* stop / start bonded device and verify that primary MAC address is
3131 * propagated to bonded device and slaves */
3133 rte_eth_dev_stop(test_params->bonded_port_id);
3135 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3138 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3139 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3140 printf("bonded port (%d) mac address not set to that of primary port\n",
3141 test_params->bonded_port_id);
3145 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3146 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3147 printf("slave port (%d) mac address not set to that of primary port\n",
3148 test_params->slave_port_ids[0]);
3152 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3153 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3154 printf("slave port (%d) mac address not set to that of primary port\n",
3155 test_params->slave_port_ids[1]);
3159 /* Set explicit MAC address */
3160 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3161 (struct ether_addr *)bonded_mac) != 0)
3164 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3165 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3166 printf("bonded port (%d) mac address not set to that of bonded port\n",
3167 test_params->bonded_port_id);
3171 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3172 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3173 printf("slave port (%d) mac address not as expected\n",
3174 test_params->slave_port_ids[0]);
3178 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3179 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3180 printf("slave port (%d) mac address not set to that of bonded port\n",
3181 test_params->slave_port_ids[1]);
3185 /* Clean up and remove slaves from bonded device */
3186 return remove_slaves_and_stop_bonded_device();
3189 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3192 test_balance_verify_slave_link_status_change_behaviour(void)
3194 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3195 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3196 struct rte_eth_stats port_stats;
3198 uint8_t slaves[RTE_MAX_ETHPORTS];
3200 int i, j, burst_size, slave_count;
3202 memset(pkt_burst, 0, sizeof(pkt_burst));
3204 /* Initialize bonded device with 4 slaves in round robin mode */
3205 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
3206 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
3209 if (rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
3210 BALANCE_XMIT_POLICY_LAYER2)) {
3211 printf("Failed to set balance xmit policy.\n");
3215 /* Verify Current Slaves Count /Active Slave Count is */
3216 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3218 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3219 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
3220 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3224 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3225 slaves, RTE_MAX_ETHPORTS);
3226 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3227 printf("Number of active slaves (%d) is not as expected (%d).\n",
3228 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3232 /* Set 2 slaves link status to down */
3233 virtual_ethdev_simulate_link_status_interrupt(
3234 test_params->slave_port_ids[1], 0);
3235 virtual_ethdev_simulate_link_status_interrupt(
3236 test_params->slave_port_ids[3], 0);
3238 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3239 slaves, RTE_MAX_ETHPORTS) != 2) {
3240 printf("Number of active slaves (%d) is not as expected (%d).\n",
3245 /* Send to sets of packet burst and verify that they are balanced across
3249 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
3251 printf("generate_test_burst failed\n");
3255 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3257 printf("generate_test_burst failed\n");
3261 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3262 burst_size) != burst_size) {
3263 printf("rte_eth_tx_burst failed\n");
3267 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3268 burst_size) != burst_size) {
3269 printf("rte_eth_tx_burst failed\n");
3273 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3274 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3275 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3276 test_params->bonded_port_id, (int)port_stats.opackets,
3277 burst_size + burst_size);
3281 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3282 if (port_stats.opackets != (uint64_t)burst_size) {
3283 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3284 test_params->slave_port_ids[0], (int)port_stats.opackets,
3289 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3290 if (port_stats.opackets != (uint64_t)burst_size) {
3291 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3292 test_params->slave_port_ids[2], (int)port_stats.opackets,
3297 /* verify that all packets get send on primary slave when no other slaves
3299 virtual_ethdev_simulate_link_status_interrupt(
3300 test_params->slave_port_ids[2], 0);
3302 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
3303 RTE_MAX_ETHPORTS) != 1) {
3304 printf("Number of active slaves (%d) is not as expected (%d).\n",
3309 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3311 printf("generate_test_burst failed\n");
3315 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3316 burst_size) != burst_size) {
3317 printf("rte_eth_tx_burst failed\n");
3321 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3322 if (port_stats.opackets != (uint64_t)(burst_size + burst_size +
3324 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3325 test_params->bonded_port_id, (int)port_stats.opackets,
3326 burst_size + burst_size + burst_size);
3330 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3331 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3332 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3333 test_params->slave_port_ids[0], (int)port_stats.opackets,
3334 burst_size + burst_size);
3339 virtual_ethdev_simulate_link_status_interrupt(
3340 test_params->slave_port_ids[0], 0);
3341 virtual_ethdev_simulate_link_status_interrupt(
3342 test_params->slave_port_ids[1], 1);
3343 virtual_ethdev_simulate_link_status_interrupt(
3344 test_params->slave_port_ids[2], 1);
3345 virtual_ethdev_simulate_link_status_interrupt(
3346 test_params->slave_port_ids[3], 1);
3348 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3349 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
3353 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3354 &pkt_burst[i][0], burst_size);
3359 /* Verify that pkts are not received on slaves with link status down */
3361 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3364 /* Verify bonded device rx count */
3365 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3366 if (port_stats.ipackets != (uint64_t)(burst_size * 3)) {
3367 printf("(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3368 test_params->bonded_port_id, (int)port_stats.ipackets,
3373 /* free mbufs allocate for rx testing */
3374 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3375 for (j = 0; j < MAX_PKT_BURST; j++) {
3376 if (pkt_burst[i][j] != NULL) {
3377 rte_pktmbuf_free(pkt_burst[i][j]);
3378 pkt_burst[i][j] = NULL;
3383 /* Clean up and remove slaves from bonded device */
3384 return remove_slaves_and_stop_bonded_device();
3387 #ifdef RTE_MBUF_REFCNT
3388 /** Broadcast Mode Tests */
3391 test_broadcast_tx_burst(void)
3393 int i, pktlen, retval, burst_size, generated_burst_size, nb_tx;
3394 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3396 struct rte_eth_stats port_stats;
3398 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 2, 1);
3400 printf("Failed to initialize_bonded_device_with_slaves.\n");
3404 initialize_eth_header(test_params->pkt_eth_hdr,
3405 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3407 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3409 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3410 dst_addr_0, pktlen);
3412 burst_size = 20 * test_params->bonded_slave_count;
3414 if (burst_size > MAX_PKT_BURST) {
3415 printf("Burst size specified is greater than supported.\n");
3419 /* Generate a burst of packets to transmit */
3420 generated_burst_size =
3421 generate_packet_burst(test_params->mbuf_pool,
3422 pkts_burst, test_params->pkt_eth_hdr, 0,
3423 test_params->pkt_ipv4_hdr, 1,
3424 test_params->pkt_udp_hdr, burst_size,
3425 PACKET_BURST_GEN_PKT_LEN, 1);
3426 if (generated_burst_size != burst_size)
3429 /* Send burst on bonded port */
3430 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3432 if (nb_tx != burst_size * test_params->bonded_slave_count) {
3433 printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
3434 test_params->bonded_port_id,
3439 /* Verify bonded port tx stats */
3440 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3441 if (port_stats.opackets != (uint64_t)burst_size *
3442 test_params->bonded_slave_count) {
3443 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3444 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3448 /* Verify slave ports tx stats */
3449 for (i = 0; i < test_params->bonded_slave_count; i++) {
3450 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3451 if (port_stats.opackets != (uint64_t)burst_size) {
3452 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3453 test_params->bonded_port_id,
3454 (unsigned int)port_stats.opackets, burst_size);
3458 /* Put all slaves down and try and transmit */
3459 for (i = 0; i < test_params->bonded_slave_count; i++) {
3461 virtual_ethdev_simulate_link_status_interrupt(
3462 test_params->slave_port_ids[i], 0);
3465 /* Send burst on bonded port */
3466 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3471 /* Clean up and remove slaves from bonded device */
3472 return remove_slaves_and_stop_bonded_device();
3475 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3478 test_broadcast_rx_burst(void)
3480 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3482 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3483 struct rte_eth_stats port_stats;
3485 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3488 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3490 /* Initialize bonded device with 4 slaves in round robin mode */
3491 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 3, 1) != 0)
3495 /* Generate test bursts of packets to transmit */
3496 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3497 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0,
3498 0) != burst_size[i])
3502 /* Add rx data to slave 0 */
3503 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3504 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3505 &gen_pkt_burst[i][0], burst_size[i]);
3509 /* Call rx burst on bonded device */
3510 /* Send burst on bonded port */
3511 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3513 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3514 printf("round-robin rx burst failed");
3518 /* Verify bonded device rx count */
3519 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3520 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3522 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3523 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3524 burst_size[0] + burst_size[1] + burst_size[2]);
3529 /* Verify bonded slave devices rx counts */
3530 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3531 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3532 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3533 test_params->slave_port_ids[0],
3534 (unsigned int)port_stats.ipackets, burst_size[0]);
3538 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3539 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3540 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3541 test_params->slave_port_ids[1],
3542 (unsigned int)port_stats.ipackets, burst_size[1]);
3546 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3547 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3548 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3549 test_params->slave_port_ids[2],
3550 (unsigned int)port_stats.ipackets,
3555 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3556 if (port_stats.ipackets != 0) {
3557 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3558 test_params->slave_port_ids[3],
3559 (unsigned int)port_stats.ipackets, 0);
3563 /* free mbufs allocate for rx testing */
3564 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3565 for (j = 0; j < MAX_PKT_BURST; j++) {
3566 if (gen_pkt_burst[i][j] != NULL) {
3567 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3568 gen_pkt_burst[i][j] = NULL;
3573 /* Clean up and remove slaves from bonded device */
3574 return remove_slaves_and_stop_bonded_device();
3578 test_broadcast_verify_promiscuous_enable_disable(void)
3580 int i, promiscuous_en;
3582 /* Initialize bonded device with 4 slaves in round robin mode */
3583 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) != 0)
3586 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3588 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3589 if (promiscuous_en != 1) {
3590 printf("Port (%d) promiscuous mode not enabled\n",
3591 test_params->bonded_port_id);
3595 for (i = 0; i < test_params->bonded_slave_count; i++) {
3596 promiscuous_en = rte_eth_promiscuous_get(
3597 test_params->slave_port_ids[i]);
3598 if (promiscuous_en != 1) {
3599 printf("slave port (%d) promiscuous mode not enabled\n",
3600 test_params->slave_port_ids[i]);
3605 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3607 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3608 if (promiscuous_en != 0) {
3609 printf("Port (%d) promiscuous mode not disabled\n",
3610 test_params->bonded_port_id);
3614 for (i = 0; i < test_params->bonded_slave_count; i++) {
3615 promiscuous_en = rte_eth_promiscuous_get(
3616 test_params->slave_port_ids[i]);
3617 if (promiscuous_en != 0) {
3618 printf("slave port (%d) promiscuous mode not disabled\n",
3619 test_params->slave_port_ids[i]);
3624 /* Clean up and remove slaves from bonded device */
3625 return remove_slaves_and_stop_bonded_device();
3629 test_broadcast_verify_mac_assignment(void)
3631 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3635 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3636 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3638 /* Initialize bonded device with 4 slaves in round robin mode */
3639 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 4, 1) != 0)
3642 /* Verify that all MACs are the same as first slave added to bonded
3644 for (i = 0; i < test_params->bonded_slave_count; i++) {
3645 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3646 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3647 sizeof(read_mac_addr))) {
3648 printf("slave port (%d) mac address not set to that of primary port\n",
3649 test_params->slave_port_ids[i]);
3654 /* change primary and verify that MAC addresses haven't changed */
3655 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
3656 test_params->slave_port_ids[2]);
3658 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3659 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3663 for (i = 0; i < test_params->bonded_slave_count; i++) {
3664 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3665 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3666 sizeof(read_mac_addr))) {
3667 printf("slave port (%d) mac address has changed to that of primary"
3668 "port without stop/start toggle of bonded device\n",
3669 test_params->slave_port_ids[i]);
3674 /* stop / start bonded device and verify that primary MAC address is
3675 * propagated to bonded device and slaves */
3677 rte_eth_dev_stop(test_params->bonded_port_id);
3679 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3682 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3683 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3684 printf("bonded port (%d) mac address not set to that of new primary"
3685 " port\n", test_params->slave_port_ids[i]);
3689 for (i = 0; i < test_params->bonded_slave_count; i++) {
3690 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3691 if (memcmp(&expected_mac_addr_1, &read_mac_addr,
3692 sizeof(read_mac_addr))) {
3693 printf("slave port (%d) mac address not set to that of new primary"
3694 "port\n", test_params->slave_port_ids[i]);
3699 /* Set explicit MAC address */
3700 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3701 (struct ether_addr *)bonded_mac) != 0)
3704 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3705 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3706 printf("bonded port (%d) mac address not set to that of new primary port\n",
3707 test_params->slave_port_ids[i]);
3711 for (i = 0; i < test_params->bonded_slave_count; i++) {
3712 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3713 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3714 printf("slave port (%d) mac address not set to that of new primary port\n",
3715 test_params->slave_port_ids[i]);
3720 /* Clean up and remove slaves from bonded device */
3721 return remove_slaves_and_stop_bonded_device();
3724 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3726 test_broadcast_verify_slave_link_status_change_behaviour(void)
3728 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3729 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3730 struct rte_eth_stats port_stats;
3732 uint8_t slaves[RTE_MAX_ETHPORTS];
3734 int i, j, burst_size, slave_count;
3736 memset(pkt_burst, 0, sizeof(pkt_burst));
3738 /* Initialize bonded device with 4 slaves in round robin mode */
3739 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0,
3740 BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
3743 /* Verify Current Slaves Count /Active Slave Count is */
3744 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3746 if (slave_count != 4) {
3747 printf("Number of slaves (%d) is not as expected (%d).\n",
3752 slave_count = rte_eth_bond_active_slaves_get(
3753 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
3754 if (slave_count != 4) {
3755 printf("Number of active slaves (%d) is not as expected (%d).\n",
3760 /* Set 2 slaves link status to down */
3761 virtual_ethdev_simulate_link_status_interrupt(
3762 test_params->slave_port_ids[1], 0);
3763 virtual_ethdev_simulate_link_status_interrupt(
3764 test_params->slave_port_ids[3], 0);
3766 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3767 slaves, RTE_MAX_ETHPORTS);
3768 if (slave_count != 2) {
3769 printf("Number of active slaves (%d) is not as expected (%d).\n",
3774 for (i = 0; i < test_params->bonded_slave_count; i++)
3775 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3777 /* Verify that pkts are not sent on slaves with link status down */
3780 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0) !=
3782 printf("generate_test_burst failed\n");
3786 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3787 burst_size) != (burst_size * slave_count)) {
3788 printf("rte_eth_tx_burst failed\n");
3792 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3793 if (port_stats.opackets != (uint64_t)(burst_size * slave_count)) {
3794 printf("(%d) port_stats.opackets (%d) not as expected (%d)\n",
3795 test_params->bonded_port_id, (int)port_stats.opackets,
3796 burst_size * slave_count);
3800 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3801 if (port_stats.opackets != (uint64_t)burst_size) {
3802 printf("(%d) port_stats.opackets not as expected\n",
3803 test_params->slave_port_ids[0]);
3807 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3808 if (port_stats.opackets != 0) {
3809 printf("(%d) port_stats.opackets not as expected\n",
3810 test_params->slave_port_ids[1]);
3814 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3815 if (port_stats.opackets != (uint64_t)burst_size) {
3816 printf("(%d) port_stats.opackets not as expected\n",
3817 test_params->slave_port_ids[2]);
3821 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3822 if (port_stats.opackets != 0) {
3823 printf("(%d) port_stats.opackets not as expected\n",
3824 test_params->slave_port_ids[3]);
3828 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3829 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0) !=
3834 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3835 &pkt_burst[i][0], burst_size);
3838 /* Verify that pkts are not received on slaves with link status down */
3840 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3842 burst_size + burst_size) {
3843 printf("rte_eth_rx_burst\n");
3847 /* Verify bonded device rx count */
3848 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3849 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
3850 printf("(%d) port_stats.ipackets not as expected\n",
3851 test_params->bonded_port_id);
3855 /* free mbufs allocate for rx testing */
3856 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3857 for (j = 0; j < MAX_PKT_BURST; j++) {
3858 if (pkt_burst[i][j] != NULL) {
3859 rte_pktmbuf_free(pkt_burst[i][j]);
3860 pkt_burst[i][j] = NULL;
3865 /* Clean up and remove slaves from bonded device */
3866 return remove_slaves_and_stop_bonded_device();
3871 test_reconfigure_bonded_device(void)
3873 test_params->nb_rx_q = 4;
3874 test_params->nb_tx_q = 4;
3876 if (configure_ethdev(test_params->bonded_port_id, 0, 0) != 0) {
3877 printf("failed to reconfigure bonded device");
3882 test_params->nb_rx_q = 2;
3883 test_params->nb_tx_q = 2;
3885 if (configure_ethdev(test_params->bonded_port_id, 0, 0) != 0) {
3886 printf("failed to reconfigure bonded device with less rx/tx queues");
3895 test_close_bonded_device(void)
3897 rte_eth_dev_close(test_params->bonded_port_id);
3902 testsuite_teardown(void)
3904 if (test_params->pkt_eth_hdr != NULL) {
3905 free(test_params->pkt_eth_hdr);
3906 test_params->pkt_eth_hdr = NULL;
3909 /* Clean up and remove slaves from bonded device */
3910 return remove_slaves_and_stop_bonded_device();
3914 static struct unit_test_suite link_bonding_test_suite = {
3915 .suite_name = "Link Bonding Unit Test Suite",
3916 .setup = test_setup,
3917 .teardown = testsuite_teardown,
3918 .unit_test_cases = {
3919 TEST_CASE(test_create_bonded_device),
3920 TEST_CASE(test_create_bonded_device_with_invalid_params),
3921 TEST_CASE(test_add_slave_to_bonded_device),
3922 TEST_CASE(test_add_slave_to_invalid_bonded_device),
3923 TEST_CASE(test_remove_slave_from_bonded_device),
3924 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
3925 TEST_CASE(test_get_slaves_from_bonded_device),
3926 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
3927 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
3928 TEST_CASE(test_start_bonded_device),
3929 TEST_CASE(test_stop_bonded_device),
3930 TEST_CASE(test_set_bonding_mode),
3931 TEST_CASE(test_set_primary_slave),
3932 TEST_CASE(test_set_explicit_bonded_mac),
3933 TEST_CASE(test_status_interrupt),
3934 TEST_CASE(test_adding_slave_after_bonded_device_started),
3935 TEST_CASE(test_roundrobin_tx_burst),
3936 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
3937 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
3938 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
3939 TEST_CASE(test_roundrobin_verify_mac_assignment),
3940 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
3941 TEST_CASE(test_activebackup_tx_burst),
3942 TEST_CASE(test_activebackup_rx_burst),
3943 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
3944 TEST_CASE(test_activebackup_verify_mac_assignment),
3945 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
3946 TEST_CASE(test_balance_xmit_policy_configuration),
3947 TEST_CASE(test_balance_l2_tx_burst),
3948 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
3949 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
3950 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
3951 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
3952 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
3953 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
3954 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
3955 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
3956 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
3957 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
3958 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
3959 TEST_CASE(test_balance_rx_burst),
3960 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
3961 TEST_CASE(test_balance_verify_mac_assignment),
3962 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
3963 #ifdef RTE_MBUF_REFCNT
3964 TEST_CASE(test_broadcast_tx_burst),
3965 TEST_CASE(test_broadcast_rx_burst),
3966 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
3967 TEST_CASE(test_broadcast_verify_mac_assignment),
3968 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
3970 TEST_CASE(test_reconfigure_bonded_device),
3971 TEST_CASE(test_close_bonded_device),
3973 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
3979 test_link_bonding(void)
3981 return unit_test_suite_runner(&link_bonding_test_suite);
3984 static struct test_command link_bonding_cmd = {
3985 .command = "link_bonding_autotest",
3986 .callback = test_link_bonding,
3988 REGISTER_TEST_COMMAND(link_bonding_cmd);