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>
43 #include <rte_byteorder.h>
44 #include <rte_common.h>
45 #include <rte_debug.h>
46 #include <rte_ethdev.h>
48 #include <rte_lcore.h>
49 #include <rte_memory.h>
50 #include <rte_string_fns.h>
51 #include <rte_eth_bond.h>
53 #include "virtual_pmd.h"
54 #include "packet_burst_generator.h"
58 #define TEST_MAX_NUMBER_OF_PORTS (16)
60 #define RX_RING_SIZE 128
61 #define RX_FREE_THRESH 32
66 #define TX_RING_SIZE 512
67 #define TX_FREE_THRESH 32
71 #define TX_RSBIT_THRESH 32
72 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
73 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
74 ETH_TXQ_FLAGS_NOXSUMTCP)
76 #define MBUF_PAYLOAD_SIZE (2048)
77 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
78 #define MBUF_CACHE_SIZE (250)
79 #define BURST_SIZE (32)
81 #define DEFAULT_MBUF_DATA_SIZE (2048)
82 #define RTE_TEST_RX_DESC_MAX (2048)
83 #define RTE_TEST_TX_DESC_MAX (2048)
84 #define MAX_PKT_BURST (512)
85 #define DEF_PKT_BURST (16)
87 #define BONDED_DEV_NAME ("unit_test_bonded_device")
89 #define INVALID_SOCKET_ID (-1)
90 #define INVALID_PORT_ID (-1)
91 #define INVALID_BONDING_MODE (-1)
94 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
95 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
97 struct link_bonding_unittest_params {
98 int8_t bonded_port_id;
99 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
100 uint8_t bonded_slave_count;
101 uint8_t bonding_mode;
106 struct rte_mempool *mbuf_pool;
108 struct ether_addr *default_slave_mac;
109 struct ether_addr *default_bonded_mac;
112 struct ether_hdr *pkt_eth_hdr;
113 struct ipv4_hdr *pkt_ipv4_hdr;
114 struct ipv6_hdr *pkt_ipv6_hdr;
115 struct udp_hdr *pkt_udp_hdr;
119 static struct ipv4_hdr pkt_ipv4_hdr;
120 static struct ipv6_hdr pkt_ipv6_hdr;
121 static struct udp_hdr pkt_udp_hdr;
123 static struct link_bonding_unittest_params default_params = {
124 .bonded_port_id = -1,
125 .slave_port_ids = { 0 },
126 .bonded_slave_count = 0,
127 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
134 .default_slave_mac = (struct ether_addr *)slave_mac,
135 .default_bonded_mac = (struct ether_addr *)bonded_mac,
138 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
139 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
140 .pkt_udp_hdr = &pkt_udp_hdr
144 static struct link_bonding_unittest_params *test_params = &default_params;
146 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
147 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
148 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
150 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
151 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
152 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
154 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
155 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
156 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
157 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
158 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
159 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
161 static uint16_t src_port = 1024;
162 static uint16_t dst_port_0 = 1024;
163 static uint16_t dst_port_1 = 2024;
165 static uint16_t vlan_id = 0x100;
167 struct rte_eth_rxmode rx_mode = {
168 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
170 .header_split = 0, /**< Header Split disabled. */
171 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
172 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
173 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
174 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
175 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
176 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
179 struct rte_fdir_conf fdir_conf = {
180 .mode = RTE_FDIR_MODE_NONE,
181 .pballoc = RTE_FDIR_PBALLOC_64K,
182 .status = RTE_FDIR_REPORT_STATUS,
183 .flexbytes_offset = 0x6,
187 static struct rte_eth_conf default_pmd_conf = {
189 .mq_mode = ETH_MQ_RX_NONE,
190 .max_rx_pkt_len = ETHER_MAX_LEN,
192 .header_split = 0, /**< Header Split disabled */
193 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
194 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
195 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
196 .hw_strip_crc = 0, /**< CRC stripped by hardware */
199 .mq_mode = ETH_MQ_TX_NONE,
204 static const struct rte_eth_rxconf rx_conf_default = {
206 .pthresh = RX_PTHRESH,
207 .hthresh = RX_HTHRESH,
208 .wthresh = RX_WTHRESH,
210 .rx_free_thresh = RX_FREE_THRESH,
214 static struct rte_eth_txconf tx_conf_default = {
216 .pthresh = TX_PTHRESH,
217 .hthresh = TX_HTHRESH,
218 .wthresh = TX_WTHRESH,
220 .tx_free_thresh = TX_FREE_THRESH,
221 .tx_rs_thresh = TX_RSBIT_THRESH,
222 .txq_flags = TX_Q_FLAGS
227 configure_ethdev(uint8_t port_id, uint8_t start)
231 if (rte_eth_dev_configure(port_id, test_params->nb_rx_q,
232 test_params->nb_tx_q, &default_pmd_conf) != 0) {
236 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++) {
237 if (rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
238 rte_eth_dev_socket_id(port_id), &rx_conf_default,
239 test_params->mbuf_pool) < 0) {
244 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++) {
245 if (rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
246 rte_eth_dev_socket_id(port_id), &tx_conf_default) < 0) {
247 printf("Failed to setup tx queue (%d).\n", q_id);
253 if (rte_eth_dev_start(port_id) < 0) {
254 printf("Failed to start device (%d).\n", port_id);
261 printf("Failed to configure ethdev %d", port_id);
269 int i, retval, nb_mbuf_per_pool;
270 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
272 /* Allocate ethernet packet header with space for VLAN header */
273 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
274 sizeof(struct vlan_hdr));
275 if (test_params->pkt_eth_hdr == NULL) {
276 printf("ethernet header struct allocation failed!\n");
281 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
282 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
284 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
285 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
286 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
288 if (test_params->mbuf_pool == NULL) {
289 printf("rte_mempool_create failed\n");
293 /* Create / Initialize virtual eth devs */
294 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
295 char pmd_name[RTE_ETH_NAME_MAX_LEN];
297 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
299 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "test_slave_pmd_%d", i);
301 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
302 mac_addr, rte_socket_id());
303 if (test_params->slave_port_ids[i] < 0) {
304 printf("Failed to create virtual pmd eth device.\n");
308 retval = configure_ethdev(test_params->slave_port_ids[i], 1);
310 printf("Failed to configure virtual pmd eth device.\n");
319 test_create_bonded_device(void)
321 int retval, current_slave_count;
323 uint8_t slaves[RTE_MAX_ETHPORTS];
325 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
326 test_params->bonding_mode, rte_socket_id());
327 if (test_params->bonded_port_id < 0) {
328 printf("\t Failed to create bonded device.\n");
332 retval = configure_ethdev(test_params->bonded_port_id, 0);
334 printf("Failed to configure bonded pmd eth device.\n");
338 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
339 slaves, RTE_MAX_ETHPORTS);
340 if (current_slave_count > 0) {
341 printf("Number of slaves is great than expected.\n");
345 current_slave_count = rte_eth_bond_active_slaves_get(
346 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
347 if (current_slave_count > 0) {
348 printf("Number of active slaves is great than expected.\n");
353 if (rte_eth_bond_mode_get(test_params->bonded_port_id) !=
354 test_params->bonding_mode) {
355 printf("Bonded device mode not as expected.\n");
365 test_create_bonded_device_with_invalid_params(void)
369 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
372 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
375 printf("Created bonded device unexpectedly.\n");
379 test_params->bonding_mode = INVALID_BONDING_MODE;
381 /* Invalid bonding mode */
382 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
385 printf("Created bonded device unexpectedly.\n");
389 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
391 /* Invalid socket id */
392 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
395 printf("Created bonded device unexpectedly.\n");
403 test_add_slave_to_bonded_device(void)
405 int retval, current_slave_count;
407 uint8_t slaves[RTE_MAX_ETHPORTS];
409 retval = rte_eth_bond_slave_add(test_params->bonded_port_id,
410 test_params->slave_port_ids[test_params->bonded_slave_count]);
412 printf("Failed to add slave (%d) to bonded port (%d).\n",
413 test_params->bonded_port_id,
414 test_params->slave_port_ids[test_params->bonded_slave_count]);
418 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
419 slaves, RTE_MAX_ETHPORTS);
420 if (current_slave_count != test_params->bonded_slave_count + 1) {
421 printf("Number of slaves (%d) is greater than expected (%d).\n",
422 current_slave_count, test_params->bonded_slave_count + 1);
426 current_slave_count = rte_eth_bond_active_slaves_get(
427 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
428 if (current_slave_count != 0) {
429 printf("Number of active slaves (%d) is not as expected (%d).\n",
430 current_slave_count, 0);
434 test_params->bonded_slave_count++;
440 test_add_slave_to_invalid_bonded_device(void)
444 /* Invalid port ID */
445 retval = rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
446 test_params->slave_port_ids[test_params->bonded_slave_count]);
448 printf("Expected call to failed as invalid port specified.\n");
452 /* Non bonded device */
453 retval = rte_eth_bond_slave_add(test_params->slave_port_ids[0],
454 test_params->slave_port_ids[test_params->bonded_slave_count]);
456 printf("Expected call to failed as invalid port specified.\n");
465 test_remove_slave_from_bonded_device(void)
467 int retval, current_slave_count;
468 struct ether_addr read_mac_addr, *mac_addr;
469 uint8_t slaves[RTE_MAX_ETHPORTS];
471 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id,
472 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
474 printf("\t Failed to remove slave %d from bonded port (%d).\n",
475 test_params->slave_port_ids[test_params->bonded_slave_count-1],
476 test_params->bonded_port_id);
481 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
482 slaves, RTE_MAX_ETHPORTS);
483 if (current_slave_count != test_params->bonded_slave_count - 1) {
484 printf("Number of slaves (%d) is great than expected (%d).\n",
485 current_slave_count, 0);
490 mac_addr = (struct ether_addr *)slave_mac;
491 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
492 test_params->slave_port_ids[test_params->bonded_slave_count-1];
495 test_params->slave_port_ids[test_params->bonded_slave_count-1],
497 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
498 printf("bonded port mac address not set to that of primary port\n");
503 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
505 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
508 test_params->bonded_slave_count--;
514 test_remove_slave_from_invalid_bonded_device(void)
518 /* Invalid port ID */
519 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id + 5,
520 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
522 printf("Expected call to failed as invalid port specified.\n");
526 /* Non bonded device */
527 retval = rte_eth_bond_slave_remove(test_params->slave_port_ids[0],
528 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
530 printf("Expected call to failed as invalid port specified.\n");
538 test_add_already_bonded_slave_to_bonded_device(void)
540 int retval, port_id, current_slave_count;
541 uint8_t slaves[RTE_MAX_ETHPORTS];
542 char pmd_name[RTE_ETH_NAME_MAX_LEN];
544 test_add_slave_to_bonded_device();
546 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
547 slaves, RTE_MAX_ETHPORTS);
548 if (current_slave_count != 1) {
549 printf("Number of slaves (%d) is not that expected (%d).\n",
550 current_slave_count, 1);
554 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_2", BONDED_DEV_NAME);
556 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
559 printf("Failed to create bonded device.\n");
563 retval = rte_eth_bond_slave_add(port_id,
564 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
566 printf("Added slave (%d) to bonded port (%d) unexpectedly.\n",
567 test_params->slave_port_ids[test_params->bonded_slave_count-1],
572 return test_remove_slave_from_bonded_device();
577 test_get_slaves_from_bonded_device(void)
579 int retval, current_slave_count;
581 uint8_t slaves[RTE_MAX_ETHPORTS];
583 retval = test_add_slave_to_bonded_device();
587 /* Invalid port id */
588 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
590 if (current_slave_count >= 0)
593 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
594 slaves, RTE_MAX_ETHPORTS);
595 if (current_slave_count >= 0)
598 /* Invalid slaves pointer */
599 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
600 NULL, RTE_MAX_ETHPORTS);
601 if (current_slave_count >= 0)
604 current_slave_count = rte_eth_bond_active_slaves_get(
605 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
606 if (current_slave_count >= 0)
609 /* non bonded device*/
610 current_slave_count = rte_eth_bond_slaves_get(
611 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
612 if (current_slave_count >= 0)
615 current_slave_count = rte_eth_bond_active_slaves_get(
616 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
617 if (current_slave_count >= 0)
620 retval = test_remove_slave_from_bonded_device();
629 test_add_remove_multiple_slaves_to_from_bonded_device(void)
633 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
634 if (test_add_slave_to_bonded_device() != 0)
638 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
639 if (test_remove_slave_from_bonded_device() != 0)
647 enable_bonded_slaves(void)
651 for (i = 0; i < test_params->bonded_slave_count; i++) {
652 virtual_ethdev_simulate_link_status_interrupt(
653 test_params->slave_port_ids[i], 1);
658 test_start_bonded_device(void)
660 struct rte_eth_link link_status;
662 int retval, current_slave_count, current_bonding_mode, primary_port;
663 uint8_t slaves[RTE_MAX_ETHPORTS];
665 /* Add slave to bonded device*/
666 if (test_add_slave_to_bonded_device() != 0)
669 retval = rte_eth_dev_start(test_params->bonded_port_id);
671 printf("Failed to start bonded pmd eth device.\n");
675 /* Change link status of virtual pmd so it will be added to the active
676 * slave list of the bonded device*/
677 virtual_ethdev_simulate_link_status_interrupt(
678 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
680 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
681 slaves, RTE_MAX_ETHPORTS);
682 if (current_slave_count != test_params->bonded_slave_count) {
683 printf("Number of slaves (%d) is not expected value (%d).\n",
684 current_slave_count, test_params->bonded_slave_count);
688 current_slave_count = rte_eth_bond_active_slaves_get(
689 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
690 if (current_slave_count != test_params->bonded_slave_count) {
691 printf("Number of active slaves (%d) is not expected value (%d).\n",
692 current_slave_count, test_params->bonded_slave_count);
696 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
697 if (current_bonding_mode != test_params->bonding_mode) {
698 printf("Bonded device mode (%d) is not expected value (%d).\n",
699 current_bonding_mode, test_params->bonding_mode);
704 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
705 if (primary_port != test_params->slave_port_ids[0]) {
706 printf("Primary port (%d) is not expected value (%d).\n",
707 primary_port, test_params->slave_port_ids[0]);
712 rte_eth_link_get(test_params->bonded_port_id, &link_status);
713 if (!link_status.link_status) {
714 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
715 test_params->bonded_port_id, link_status.link_status, 1);
724 test_stop_bonded_device(void)
726 int current_slave_count;
727 uint8_t slaves[RTE_MAX_ETHPORTS];
729 struct rte_eth_link link_status;
731 rte_eth_dev_stop(test_params->bonded_port_id);
733 rte_eth_link_get(test_params->bonded_port_id, &link_status);
734 if (link_status.link_status) {
735 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
736 test_params->bonded_port_id, link_status.link_status, 0);
740 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
741 slaves, RTE_MAX_ETHPORTS);
742 if (current_slave_count != test_params->bonded_slave_count) {
743 printf("Number of slaves (%d) is not expected value (%d).\n",
744 current_slave_count, test_params->bonded_slave_count);
748 current_slave_count = rte_eth_bond_active_slaves_get(
749 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
750 if (current_slave_count != 0) {
751 printf("Number of active slaves (%d) is not expected value (%d).\n",
752 current_slave_count, 0);
759 static int remove_slaves_and_stop_bonded_device(void)
761 /* Clean up and remove slaves from bonded device */
762 while (test_params->bonded_slave_count > 0) {
763 if (test_remove_slave_from_bonded_device() != 0) {
764 printf("test_remove_slave_from_bonded_device failed\n");
769 rte_eth_dev_stop(test_params->bonded_port_id);
770 rte_eth_stats_reset(test_params->bonded_port_id);
771 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
777 test_set_bonding_mode(void)
780 int retval, bonding_mode;
782 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
783 BONDING_MODE_ACTIVE_BACKUP,
784 BONDING_MODE_BALANCE,
785 BONDING_MODE_BROADCAST };
787 /* Test supported link bonding modes */
788 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
789 /* Invalid port ID */
790 retval = rte_eth_bond_mode_set(INVALID_PORT_ID, bonding_modes[i]);
792 printf("Expected call to failed as invalid port (%d) specified.\n",
797 /* Non bonded device */
798 retval = rte_eth_bond_mode_set(test_params->slave_port_ids[0],
801 printf("Expected call to failed as invalid port (%d) specified.\n",
802 test_params->slave_port_ids[0]);
806 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
809 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
810 test_params->bonded_port_id, bonding_modes[i]);
814 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
815 if (bonding_mode != bonding_modes[i]) {
816 printf("Link bonding mode (%d) of port (%d) is not expected value (%d).\n",
817 bonding_mode, test_params->bonded_port_id,
823 /* Invalid port ID */
824 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
825 if (bonding_mode >= 0) {
826 printf("Expected call to failed as invalid port (%d) specified.\n",
832 /* Non bonded device */
833 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
834 if (bonding_mode >= 0) {
835 printf("Expected call to failed as invalid port (%d) specified.\n",
836 test_params->slave_port_ids[0]);
842 return remove_slaves_and_stop_bonded_device();
846 test_set_primary_slave(void)
849 struct ether_addr read_mac_addr;
850 struct ether_addr *expected_mac_addr;
852 /* Add 4 slaves to bonded device */
853 for (i = test_params->bonded_slave_count; i < 4; i++) {
854 retval = test_add_slave_to_bonded_device();
856 printf("Failed to add slave to bonded device.\n");
860 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
861 BONDING_MODE_ROUND_ROBIN);
863 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
864 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
868 /* Invalid port ID */
869 retval = rte_eth_bond_primary_set(INVALID_PORT_ID,
870 test_params->slave_port_ids[i]);
872 printf("Expected call to failed as invalid port specified.\n");
876 /* Set slave as primary
877 * Verify slave it is now primary slave
878 * Verify that MAC address of bonded device is that of primary slave
879 * Verify that MAC address of all bonded slaves are that of primary slave
881 for (i = 0; i < 4; i++) {
883 /* Non bonded device */
884 retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
885 test_params->slave_port_ids[i]);
887 printf("Expected call to failed as invalid port specified.\n");
891 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
892 test_params->slave_port_ids[i]);
894 printf("Failed to set bonded port (%d) primary port to (%d)\n",
895 test_params->bonded_port_id,
896 test_params->slave_port_ids[i]);
900 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
902 printf("Failed to read primary port from bonded port (%d)\n",
903 test_params->bonded_port_id);
905 } else if (retval != test_params->slave_port_ids[i]) {
906 printf("Bonded port (%d) primary port (%d) not expected value (%d)\n",
907 test_params->bonded_port_id, retval,
908 test_params->slave_port_ids[i]);
912 /* stop/start bonded eth dev to apply new MAC */
913 rte_eth_dev_stop(test_params->bonded_port_id);
914 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
917 expected_mac_addr = (struct ether_addr *)&slave_mac;
918 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
919 test_params->slave_port_ids[i];
921 /* Check primary slave MAC */
922 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
923 if (memcmp(expected_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
924 printf("bonded port mac address not set to that of primary port\n");
928 /* Check bonded MAC */
929 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
930 if (memcmp(&read_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
931 printf("bonded port mac address not set to that of primary port\n");
935 /* Check other slaves MACs */
936 for (j = 0; j < 4; j++) {
938 rte_eth_macaddr_get(test_params->slave_port_ids[j],
940 if (memcmp(expected_mac_addr, &read_mac_addr,
941 sizeof(read_mac_addr))) {
942 printf("slave port mac address not set to that of primary port\n");
950 /* Test with none existent port */
951 retval = rte_eth_bond_primary_get(test_params->bonded_port_id + 10);
953 printf("read primary port from expectedly\n");
957 /* Test with slave port */
958 retval = rte_eth_bond_primary_get(test_params->slave_port_ids[0]);
960 printf("read primary port from expectedly\n");
964 if (remove_slaves_and_stop_bonded_device() != 0)
968 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
970 printf("read primary port from expectedly\n");
978 test_set_explicit_bonded_mac(void)
981 struct ether_addr read_mac_addr;
982 struct ether_addr *mac_addr;
984 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
986 mac_addr = (struct ether_addr *)explicit_bonded_mac;
988 /* Invalid port ID */
989 retval = rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr);
991 printf("Expected call to failed as invalid port specified.\n");
995 /* Non bonded device */
996 retval = rte_eth_bond_mac_address_set(test_params->slave_port_ids[0],
999 printf("Expected call to failed as invalid port specified.\n");
1003 /* NULL MAC address */
1004 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id, NULL);
1006 printf("Expected call to failed as NULL MAC specified\n");
1010 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1013 printf("Failed to set MAC address on bonded port (%d)\n",
1014 test_params->bonded_port_id);
1018 /* Add 4 slaves to bonded device */
1019 for (i = test_params->bonded_slave_count; i < 4; i++) {
1020 retval = test_add_slave_to_bonded_device();
1022 printf("Failed to add slave to bonded device.\n");
1027 /* Check bonded MAC */
1028 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1029 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1030 printf("bonded port mac address not set to that of primary port\n");
1034 /* Check other slaves MACs */
1035 for (i = 0; i < 4; i++) {
1036 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1037 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1038 printf("slave port mac address not set to that of primary port\n");
1043 /* test resetting mac address on bonded device */
1044 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1045 printf("Failed to reset MAC address on bonded port (%d)\n",
1046 test_params->bonded_port_id);
1051 if (rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]) == 0) {
1052 printf("Reset MAC address on bonded port (%d) unexpectedly\n",
1053 test_params->slave_port_ids[1]);
1058 /* test resetting mac address on bonded device with no slaves */
1060 if (remove_slaves_and_stop_bonded_device() != 0)
1063 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1064 printf("Failed to reset MAC address on bonded port (%d)\n",
1065 test_params->bonded_port_id);
1075 initialize_bonded_device_with_slaves(uint8_t bonding_mode,
1076 uint8_t number_of_slaves, uint8_t enable_slave)
1080 /* configure bonded device */
1081 retval = configure_ethdev(test_params->bonded_port_id, 0);
1083 printf("Failed to configure bonding port (%d) in mode %d with (%d) slaves.\n",
1084 test_params->bonded_port_id, bonding_mode, number_of_slaves);
1088 while (number_of_slaves > test_params->bonded_slave_count) {
1089 /* Add slaves to bonded device */
1090 retval = test_add_slave_to_bonded_device();
1092 printf("Failed to add slave (%d to bonding port (%d).\n",
1093 test_params->bonded_slave_count - 1,
1094 test_params->bonded_port_id);
1099 /* Set link bonding mode */
1100 retval = rte_eth_bond_mode_set(test_params->bonded_port_id, bonding_mode);
1102 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
1103 test_params->bonded_port_id, bonding_mode);
1107 retval = rte_eth_dev_start(test_params->bonded_port_id);
1109 printf("Failed to start bonded pmd eth device.\n");
1114 enable_bonded_slaves();
1120 test_adding_slave_after_bonded_device_started(void)
1124 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 0) !=
1128 /* Enabled slave devices */
1129 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1130 virtual_ethdev_simulate_link_status_interrupt(
1131 test_params->slave_port_ids[i], 1);
1134 if (rte_eth_bond_slave_add(test_params->bonded_port_id,
1135 test_params->slave_port_ids[test_params->bonded_slave_count]) !=
1137 printf("\t Failed to add slave to bonded port.\n");
1141 test_params->bonded_slave_count++;
1143 return remove_slaves_and_stop_bonded_device();
1147 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1148 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1149 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1151 uint16_t pktlen, generated_burst_size;
1155 initialize_eth_header(test_params->pkt_eth_hdr,
1156 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1159 initialize_eth_header(test_params->pkt_eth_hdr,
1160 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1164 if (toggle_udp_port)
1165 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1168 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1173 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1174 dst_addr_1, pktlen);
1176 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1177 dst_addr_0, pktlen);
1179 ip_hdr = test_params->pkt_ipv4_hdr;
1182 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1183 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1186 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1187 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1190 ip_hdr = test_params->pkt_ipv6_hdr;
1193 /* Generate burst of packets to transmit */
1194 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1195 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1196 test_params->pkt_udp_hdr, burst_size);
1197 if (generated_burst_size != burst_size) {
1198 printf("Failed to generate packet burst");
1202 return generated_burst_size;
1205 /** Round Robin Mode Tests */
1208 test_roundrobin_tx_burst(void)
1210 int i, burst_size, nb_tx;
1211 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1212 struct rte_eth_stats port_stats;
1214 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 2, 1)
1218 burst_size = 20 * test_params->bonded_slave_count;
1220 if (burst_size > MAX_PKT_BURST) {
1221 printf("Burst size specified is greater than supported.\n");
1225 /* Generate test bursts of packets to transmit */
1226 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size)
1229 /* Send burst on bonded port */
1230 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1232 if (nb_tx != burst_size)
1235 /* Verify bonded port tx stats */
1236 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1237 if (port_stats.opackets != (uint64_t)burst_size) {
1238 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1239 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1244 /* Verify slave ports tx stats */
1245 for (i = 0; i < test_params->bonded_slave_count; i++) {
1246 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1247 if (port_stats.opackets !=
1248 (uint64_t)burst_size / test_params->bonded_slave_count) {
1249 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1250 test_params->bonded_port_id,
1251 (unsigned int)port_stats.opackets,
1252 burst_size / test_params->bonded_slave_count);
1257 /* Put all slaves down and try and transmit */
1258 for (i = 0; i < test_params->bonded_slave_count; i++) {
1259 virtual_ethdev_simulate_link_status_interrupt(
1260 test_params->slave_port_ids[i], 0);
1263 /* Send burst on bonded port */
1264 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1269 /* Clean up and remove slaves from bonded device */
1270 return remove_slaves_and_stop_bonded_device();
1274 test_roundrobin_rx_burst_on_single_slave(void)
1276 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1277 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1279 struct rte_eth_stats port_stats;
1281 int i, j, nb_rx, burst_size = 25;
1283 /* Initialize bonded device with 4 slaves in round robin mode */
1284 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1288 /* Generate test bursts of packets to transmit */
1289 if (generate_test_burst(gen_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1293 for (i = 0; i < test_params->bonded_slave_count; i++) {
1294 /* Add rx data to slave */
1295 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1296 &gen_pkt_burst[0], burst_size);
1298 /* Call rx burst on bonded device */
1299 /* Send burst on bonded port */
1300 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1302 if (nb_rx != burst_size) {
1303 printf("round-robin rx burst failed");
1307 /* Verify bonded device rx count */
1308 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1309 if (port_stats.ipackets != (uint64_t)burst_size) {
1310 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1311 test_params->bonded_port_id,
1312 (unsigned int)port_stats.ipackets, burst_size);
1317 /* Verify bonded slave devices rx count */
1318 /* Verify slave ports tx stats */
1319 for (j = 0; j < test_params->bonded_slave_count; j++) {
1320 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1323 if (port_stats.ipackets != (uint64_t)burst_size) {
1324 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1325 test_params->slave_port_ids[i],
1326 (unsigned int)port_stats.ipackets, burst_size);
1330 if (port_stats.ipackets != 0) {
1331 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1332 test_params->slave_port_ids[i],
1333 (unsigned int)port_stats.ipackets, 0);
1338 /* Reset bonded slaves stats */
1339 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1341 /* reset bonded device stats */
1342 rte_eth_stats_reset(test_params->bonded_port_id);
1346 for (i = 0; i < MAX_PKT_BURST; i++) {
1347 if (gen_pkt_burst[i] != NULL)
1348 rte_pktmbuf_free(gen_pkt_burst[i]);
1350 if (rx_pkt_burst[i] != NULL)
1351 rte_pktmbuf_free(rx_pkt_burst[i]);
1355 /* Clean up and remove slaves from bonded device */
1356 return remove_slaves_and_stop_bonded_device();
1359 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1362 test_roundrobin_rx_burst_on_multiple_slaves(void)
1364 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1366 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1367 struct rte_eth_stats port_stats;
1369 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1373 /* Initialize bonded device with 4 slaves in round robin mode */
1374 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1378 /* Generate test bursts of packets to transmit */
1379 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1380 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0,
1381 0) != burst_size[i])
1385 /* Add rx data to slaves */
1386 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1387 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1388 &gen_pkt_burst[i][0], burst_size[i]);
1391 /* Call rx burst on bonded device */
1392 /* Send burst on bonded port */
1393 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1395 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
1396 printf("round-robin rx burst failed (%d != %d)\n", nb_rx,
1397 burst_size[0] + burst_size[1] + burst_size[2]);
1401 /* Verify bonded device rx count */
1402 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1403 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
1405 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1406 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1407 burst_size[0] + burst_size[1] + burst_size[2]);
1412 /* Verify bonded slave devices rx counts */
1413 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1414 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
1415 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1416 test_params->slave_port_ids[0],
1417 (unsigned int)port_stats.ipackets, burst_size[0]);
1421 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1422 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
1423 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1424 test_params->slave_port_ids[1],
1425 (unsigned int)port_stats.ipackets, burst_size[1]);
1429 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1430 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
1431 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1432 test_params->slave_port_ids[2],
1433 (unsigned int)port_stats.ipackets, burst_size[2]);
1437 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1438 if (port_stats.ipackets != 0) {
1439 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1440 test_params->slave_port_ids[3],
1441 (unsigned int)port_stats.ipackets, 0);
1446 for (i = 0; i < MAX_PKT_BURST; i++) {
1447 if (rx_pkt_burst[i] != NULL)
1448 rte_pktmbuf_free(rx_pkt_burst[i]);
1451 /* Clean up and remove slaves from bonded device */
1452 return remove_slaves_and_stop_bonded_device();
1456 test_roundrobin_verify_mac_assignment(void)
1458 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1462 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1463 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1465 /* Initialize bonded device with 4 slaves in round robin mode */
1466 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1)
1470 /* Verify that all MACs are the same as first slave added to bonded dev */
1471 for (i = 0; i < test_params->bonded_slave_count; i++) {
1472 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1473 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1474 sizeof(read_mac_addr))) {
1475 printf("slave port (%d) mac address not set to that of primary port\n",
1476 test_params->slave_port_ids[i]);
1481 /* change primary and verify that MAC addresses haven't changed */
1482 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
1483 test_params->slave_port_ids[2]);
1485 printf("Failed to set bonded port (%d) primary port to (%d)\n",
1486 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1490 for (i = 0; i < test_params->bonded_slave_count; i++) {
1491 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1492 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1493 sizeof(read_mac_addr))) {
1494 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
1495 test_params->slave_port_ids[i]);
1500 /* stop / start bonded device and verify that primary MAC address is
1501 * propagate to bonded device and slaves */
1503 rte_eth_dev_stop(test_params->bonded_port_id);
1505 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
1508 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1509 if (memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr))) {
1510 printf("bonded port (%d) mac address not set to that of new primary port\n",
1511 test_params->slave_port_ids[i]);
1515 for (i = 0; i < test_params->bonded_slave_count; i++) {
1516 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1517 if (memcmp(&expected_mac_addr_2, &read_mac_addr,
1518 sizeof(read_mac_addr))) {
1519 printf("slave port (%d) mac address not set to that of new primary port\n",
1520 test_params->slave_port_ids[i]);
1525 /* Set explicit MAC address */
1526 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1527 (struct ether_addr *)bonded_mac) != 0) {
1531 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1532 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1533 printf("bonded port (%d) mac address not set to that of new primary port\n",
1534 test_params->slave_port_ids[i]);
1538 for (i = 0; i < test_params->bonded_slave_count; i++) {
1539 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1540 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1541 printf("slave port (%d) mac address not set to that of new primary port\n",
1542 test_params->slave_port_ids[i]);
1547 /* Clean up and remove slaves from bonded device */
1548 return remove_slaves_and_stop_bonded_device();
1552 test_roundrobin_verify_promiscuous_enable_disable(void)
1554 int i, promiscuous_en;
1556 /* Initialize bonded device with 4 slaves in round robin mode */
1557 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1561 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1563 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1564 if (promiscuous_en != 1) {
1565 printf("Port (%d) promiscuous mode not enabled\n",
1566 test_params->bonded_port_id);
1570 for (i = 0; i < test_params->bonded_slave_count; i++) {
1571 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1572 if (promiscuous_en != 1) {
1573 printf("slave port (%d) promiscuous mode not enabled\n",
1574 test_params->slave_port_ids[i]);
1579 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1581 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1582 if (promiscuous_en != 0) {
1583 printf("Port (%d) promiscuous mode not disabled\n",
1584 test_params->bonded_port_id);
1588 for (i = 0; i < test_params->bonded_slave_count; i++) {
1589 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1590 if (promiscuous_en != 0) {
1591 printf("slave port (%d) promiscuous mode not disabled\n",
1592 test_params->slave_port_ids[i]);
1597 /* Clean up and remove slaves from bonded device */
1598 return remove_slaves_and_stop_bonded_device();
1601 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1602 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1605 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1607 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1608 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1609 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1611 struct rte_eth_stats port_stats;
1612 uint8_t slaves[RTE_MAX_ETHPORTS];
1614 int i, burst_size, slave_count;
1616 /* NULL all pointers in array to simplify cleanup */
1617 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1619 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1620 * in round robin mode */
1621 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN,
1622 TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
1625 /* Verify Current Slaves Count /Active Slave Count is */
1626 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1628 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1629 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
1630 TEST_RR_LINK_STATUS_SLAVE_COUNT);
1634 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1635 slaves, RTE_MAX_ETHPORTS);
1636 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1637 printf("Number of active slaves (%d) is not as expected (%d).\n",
1638 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1642 /* Set 2 slaves eth_devs link status to down */
1643 virtual_ethdev_simulate_link_status_interrupt(
1644 test_params->slave_port_ids[1], 0);
1645 virtual_ethdev_simulate_link_status_interrupt(
1646 test_params->slave_port_ids[3], 0);
1648 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1649 slaves, RTE_MAX_ETHPORTS) !=
1650 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) {
1651 printf("Number of active slaves (%d) is not as expected (%d).\n",
1652 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1658 /* Verify that pkts are not sent on slaves with link status down:
1660 * 1. Generate test burst of traffic
1661 * 2. Transmit burst on bonded eth_dev
1662 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1663 * 4. Verify stats for slave eth_devs (s0 = 11, s1 = 0, s2 = 10, s3 = 0)
1665 if (generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1667 printf("generate_test_burst failed\n");
1671 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1672 burst_size) != burst_size) {
1673 printf("rte_eth_tx_burst failed\n");
1677 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1678 if (port_stats.opackets != (uint64_t)burst_size) {
1679 printf("(%d) port_stats.opackets not as expected\n",
1680 test_params->bonded_port_id);
1684 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1685 if (port_stats.opackets != 11) {
1686 printf("(%d) port_stats.opackets not as expected\n",
1687 test_params->slave_port_ids[0]);
1691 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1692 if (port_stats.opackets != 0) {
1693 printf("(%d) port_stats.opackets not as expected\n",
1694 test_params->slave_port_ids[1]);
1698 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1699 if (port_stats.opackets != 10) {
1700 printf("(%d) port_stats.opackets not as expected\n",
1701 test_params->slave_port_ids[2]);
1705 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1706 if (port_stats.opackets != 0) {
1707 printf("(%d) port_stats.opackets not as expected\n",
1708 test_params->slave_port_ids[3]);
1712 /* Verify that pkts are not sent on slaves with link status down:
1714 * 1. Generate test bursts of traffic
1715 * 2. Add bursts on to virtual eth_devs
1716 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1717 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1718 * 4. Verify stats for bonded eth_dev
1719 * 6. Verify stats for slave eth_devs (s0 = 11, s1 = 0, s2 = 10, s3 = 0)
1721 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1722 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0)
1726 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1727 &gen_pkt_burst[i][0], burst_size);
1730 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1731 MAX_PKT_BURST) != burst_size + burst_size) {
1732 printf("rte_eth_rx_burst\n");
1736 /* Verify bonded device rx count */
1737 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1738 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
1739 printf("(%d) port_stats.ipackets not as expected\n",
1740 test_params->bonded_port_id);
1745 for (i = 0; i < MAX_PKT_BURST; i++) {
1746 if (rx_pkt_burst[i] != NULL)
1747 rte_pktmbuf_free(rx_pkt_burst[i]);
1749 if (gen_pkt_burst[1][i] != NULL)
1750 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1752 if (gen_pkt_burst[3][i] != NULL)
1753 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1756 /* Clean up and remove slaves from bonded device */
1757 return remove_slaves_and_stop_bonded_device();
1760 /** Active Backup Mode Tests */
1763 test_activebackup_tx_burst(void)
1765 int i, retval, pktlen, primary_port, burst_size, generated_burst_size, nb_tx;
1766 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1767 struct rte_eth_stats port_stats;
1769 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 1);
1771 printf("Failed to initialize_bonded_device_with_slaves.\n");
1775 initialize_eth_header(test_params->pkt_eth_hdr,
1776 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
1777 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1779 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1780 dst_addr_0, pktlen);
1782 burst_size = 20 * test_params->bonded_slave_count;
1784 if (burst_size > MAX_PKT_BURST) {
1785 printf("Burst size specified is greater than supported.\n");
1789 /* Generate a burst of packets to transmit */
1790 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1791 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
1792 1, test_params->pkt_udp_hdr, burst_size);
1793 if (generated_burst_size != burst_size)
1796 /* Send burst on bonded port */
1797 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1799 if (nb_tx != burst_size)
1802 /* Verify bonded port tx stats */
1803 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1804 if (port_stats.opackets != (uint64_t)burst_size) {
1805 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1806 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1811 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1813 /* Verify slave ports tx stats */
1814 for (i = 0; i < test_params->bonded_slave_count; i++) {
1815 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1816 if (test_params->slave_port_ids[i] == primary_port) {
1817 if (port_stats.opackets != (uint64_t)burst_size) {
1818 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1819 test_params->bonded_port_id,
1820 (unsigned int)port_stats.opackets,
1821 burst_size / test_params->bonded_slave_count);
1825 if (port_stats.opackets != 0) {
1826 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1827 test_params->bonded_port_id,
1828 (unsigned int)port_stats.opackets, 0);
1834 /* Put all slaves down and try and transmit */
1835 for (i = 0; i < test_params->bonded_slave_count; i++) {
1837 virtual_ethdev_simulate_link_status_interrupt(
1838 test_params->slave_port_ids[i], 0);
1841 /* Send burst on bonded port */
1842 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1847 /* Clean up and remove slaves from bonded device */
1848 return remove_slaves_and_stop_bonded_device();
1851 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
1854 test_activebackup_rx_burst(void)
1856 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1857 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1859 struct rte_eth_stats port_stats;
1863 int i, j, nb_rx, burst_size = 17;
1865 /* Initialize bonded device with 4 slaves in round robin mode */
1866 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
1867 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
1872 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1873 if (primary_port < 0) {
1874 printf("failed to get primary slave for bonded port (%d)",
1875 test_params->bonded_port_id);
1878 for (i = 0; i < test_params->bonded_slave_count; i++) {
1879 /* Generate test bursts of packets to transmit */
1880 if (generate_test_burst(&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0)
1885 /* Add rx data to slave */
1886 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1887 &gen_pkt_burst[0], burst_size);
1889 /* Call rx burst on bonded device */
1890 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
1891 &rx_pkt_burst[0], MAX_PKT_BURST);
1893 printf("rte_eth_rx_burst failed\n");
1897 if (test_params->slave_port_ids[i] == primary_port) {
1898 /* Verify bonded device rx count */
1899 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1900 if (port_stats.ipackets != (uint64_t)burst_size) {
1901 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1902 test_params->bonded_port_id,
1903 (unsigned int)port_stats.ipackets, burst_size);
1907 /* Verify bonded slave devices rx count */
1908 for (j = 0; j < test_params->bonded_slave_count; j++) {
1909 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1911 if (port_stats.ipackets != (uint64_t)burst_size) {
1912 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1913 test_params->slave_port_ids[i],
1914 (unsigned int)port_stats.ipackets, burst_size);
1918 if (port_stats.ipackets != 0) {
1919 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1920 test_params->slave_port_ids[i],
1921 (unsigned int)port_stats.ipackets, 0);
1927 for (j = 0; j < test_params->bonded_slave_count; j++) {
1928 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1929 if (port_stats.ipackets != 0) {
1930 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1931 test_params->slave_port_ids[i],
1932 (unsigned int)port_stats.ipackets, 0);
1939 for (i = 0; i < MAX_PKT_BURST; i++) {
1940 if (rx_pkt_burst[i] != NULL) {
1941 rte_pktmbuf_free(rx_pkt_burst[i]);
1942 rx_pkt_burst[i] = NULL;
1946 /* reset bonded device stats */
1947 rte_eth_stats_reset(test_params->bonded_port_id);
1950 /* Clean up and remove slaves from bonded device */
1951 return remove_slaves_and_stop_bonded_device();
1955 test_activebackup_verify_promiscuous_enable_disable(void)
1957 int i, primary_port, promiscuous_en;
1959 /* Initialize bonded device with 4 slaves in round robin mode */
1960 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 4, 1)
1964 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1965 if (primary_port < 0) {
1966 printf("failed to get primary slave for bonded port (%d)",
1967 test_params->bonded_port_id);
1970 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1972 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1973 if (promiscuous_en != 1) {
1974 printf("Port (%d) promiscuous mode not enabled\n",
1975 test_params->bonded_port_id);
1979 for (i = 0; i < test_params->bonded_slave_count; i++) {
1980 promiscuous_en = rte_eth_promiscuous_get(
1981 test_params->slave_port_ids[i]);
1982 if (primary_port == test_params->slave_port_ids[i]) {
1983 if (promiscuous_en != 1) {
1984 printf("slave port (%d) promiscuous mode not enabled\n",
1985 test_params->slave_port_ids[i]);
1989 if (promiscuous_en != 0) {
1990 printf("slave port (%d) promiscuous mode enabled\n",
1991 test_params->slave_port_ids[i]);
1998 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2000 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2001 if (promiscuous_en != 0) {
2002 printf("Port (%d) promiscuous mode not disabled\n",
2003 test_params->bonded_port_id);
2007 for (i = 0; i < test_params->bonded_slave_count; i++) {
2008 promiscuous_en = rte_eth_promiscuous_get(
2009 test_params->slave_port_ids[i]);
2010 if (promiscuous_en != 0) {
2011 printf("slave port (%d) promiscuous mode not disabled\n",
2012 test_params->slave_port_ids[i]);
2017 /* Clean up and remove slaves from bonded device */
2018 return remove_slaves_and_stop_bonded_device();
2022 test_activebackup_verify_mac_assignment(void)
2024 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2026 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2027 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2029 /* Initialize bonded device with 2 slaves in active backup mode */
2030 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 1)
2034 /* Verify that bonded MACs is that of first slave and that the other slave
2035 * MAC hasn't been changed */
2036 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2037 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2038 printf("bonded port (%d) mac address not set to that of primary port\n",
2039 test_params->bonded_port_id);
2043 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2044 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2045 printf("slave port (%d) mac address not set to that of primary port\n",
2046 test_params->slave_port_ids[0]);
2050 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2051 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2052 printf("slave port (%d) mac address not as expected\n",
2053 test_params->slave_port_ids[1]);
2057 /* change primary and verify that MAC addresses haven't changed */
2058 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2059 test_params->slave_port_ids[1]) != 0) {
2060 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2061 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2065 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2066 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2067 printf("bonded port (%d) mac address not set to that of primary port\n",
2068 test_params->bonded_port_id);
2072 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2073 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2074 printf("slave port (%d) mac address not set to that of primary port\n",
2075 test_params->slave_port_ids[0]);
2079 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2080 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2081 printf("slave port (%d) mac address not as expected\n",
2082 test_params->slave_port_ids[1]);
2086 /* stop / start bonded device and verify that primary MAC address is
2087 * propagated to bonded device and slaves */
2089 rte_eth_dev_stop(test_params->bonded_port_id);
2091 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2094 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2095 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2096 printf("bonded port (%d) mac address not set to that of primary port\n",
2097 test_params->bonded_port_id);
2101 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2102 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2103 printf("slave port (%d) mac address not as expected\n",
2104 test_params->slave_port_ids[0]);
2108 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2109 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2110 printf("slave port (%d) mac address not set to that of primary port\n",
2111 test_params->slave_port_ids[1]);
2115 /* Set explicit MAC address */
2116 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
2117 (struct ether_addr *)bonded_mac) != 0) {
2121 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2122 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2123 printf("bonded port (%d) mac address not set to that of bonded port\n",
2124 test_params->bonded_port_id);
2128 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2129 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2130 printf("slave port (%d) mac address not as expected\n",
2131 test_params->slave_port_ids[0]);
2135 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2136 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2137 printf("slave port (%d) mac address not set to that of bonded port\n",
2138 test_params->slave_port_ids[1]);
2142 /* Clean up and remove slaves from bonded device */
2143 return remove_slaves_and_stop_bonded_device();
2147 test_activebackup_verify_slave_link_status_change_failover(void)
2149 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2150 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2151 struct rte_eth_stats port_stats;
2153 uint8_t slaves[RTE_MAX_ETHPORTS];
2155 int i, j, burst_size, slave_count, primary_port;
2159 memset(pkt_burst, 0, sizeof(pkt_burst));
2161 /* Generate packet burst for testing */
2162 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
2164 printf("generate_test_burst failed\n");
2168 /* Initialize bonded device with 4 slaves in round robin mode */
2169 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
2170 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2174 /* Verify Current Slaves Count /Active Slave Count is */
2175 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2177 if (slave_count != 4) {
2178 printf("Number of slaves (%d) is not as expected (%d).\n",
2183 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2184 slaves, RTE_MAX_ETHPORTS);
2185 if (slave_count != 4) {
2186 printf("Number of active slaves (%d) is not as expected (%d).\n",
2191 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2192 if (primary_port != test_params->slave_port_ids[0])
2193 printf("Primary port not as expected");
2195 /* Bring 2 slaves down and verify active slave count */
2196 virtual_ethdev_simulate_link_status_interrupt(
2197 test_params->slave_port_ids[1], 0);
2198 virtual_ethdev_simulate_link_status_interrupt(
2199 test_params->slave_port_ids[3], 0);
2201 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2202 RTE_MAX_ETHPORTS) != 2) {
2203 printf("Number of active slaves (%d) is not as expected (%d).\n",
2208 virtual_ethdev_simulate_link_status_interrupt(
2209 test_params->slave_port_ids[1], 1);
2210 virtual_ethdev_simulate_link_status_interrupt(
2211 test_params->slave_port_ids[3], 1);
2214 /* Bring primary port down, verify that active slave count is 3 and primary
2216 virtual_ethdev_simulate_link_status_interrupt(
2217 test_params->slave_port_ids[0], 0);
2219 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2220 RTE_MAX_ETHPORTS) != 3) {
2221 printf("Number of active slaves (%d) is not as expected (%d).\n",
2226 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2227 if (primary_port != test_params->slave_port_ids[2])
2228 printf("Primary port not as expected");
2230 /* Verify that pkts are sent on new primary slave */
2232 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size)
2234 printf("rte_eth_tx_burst failed\n");
2238 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2239 if (port_stats.opackets != (uint64_t)burst_size) {
2240 printf("(%d) port_stats.opackets not as expected\n",
2241 test_params->slave_port_ids[2]);
2245 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2246 if (port_stats.opackets != 0) {
2247 printf("(%d) port_stats.opackets not as expected\n",
2248 test_params->slave_port_ids[0]);
2251 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2252 if (port_stats.opackets != 0) {
2253 printf("(%d) port_stats.opackets not as expected\n",
2254 test_params->slave_port_ids[1]);
2257 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2258 if (port_stats.opackets != 0) {
2259 printf("(%d) port_stats.opackets not as expected\n",
2260 test_params->slave_port_ids[3]);
2264 /* Generate packet burst for testing */
2266 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2267 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
2271 virtual_ethdev_add_mbufs_to_rx_queue(
2272 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2275 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2276 MAX_PKT_BURST) != burst_size) {
2277 printf("rte_eth_rx_burst\n");
2281 /* Verify bonded device rx count */
2282 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2283 if (port_stats.ipackets != (uint64_t)burst_size) {
2284 printf("(%d) port_stats.ipackets not as expected\n",
2285 test_params->bonded_port_id);
2289 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2290 if (port_stats.opackets != (uint64_t)burst_size) {
2291 printf("(%d) port_stats.opackets not as expected\n",
2292 test_params->slave_port_ids[2]);
2296 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2297 if (port_stats.opackets != 0) {
2298 printf("(%d) port_stats.opackets not as expected\n",
2299 test_params->slave_port_ids[0]);
2303 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2304 if (port_stats.opackets != 0) {
2305 printf("(%d) port_stats.opackets not as expected\n",
2306 test_params->slave_port_ids[1]);
2310 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2311 if (port_stats.opackets != 0) {
2312 printf("(%d) port_stats.opackets not as expected\n",
2313 test_params->slave_port_ids[3]);
2319 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2320 for (j = 0; j < MAX_PKT_BURST; j++) {
2321 if (pkt_burst[i][j] != NULL) {
2322 rte_pktmbuf_free(pkt_burst[i][j]);
2323 pkt_burst[i][j] = NULL;
2329 /* Clean up and remove slaves from bonded device */
2330 return remove_slaves_and_stop_bonded_device();
2333 /** Balance Mode Tests */
2336 test_balance_xmit_policy_configuration(void)
2340 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
2343 printf("Failed to initialize_bonded_device_with_slaves.\n");
2347 /* Invalid port id */
2348 retval = rte_eth_bond_xmit_policy_set(INVALID_PORT_ID,
2349 BALANCE_XMIT_POLICY_LAYER2);
2351 printf("Expected call to failed as invalid port specified.\n");
2355 /* Set xmit policy on non bonded device */
2356 retval = rte_eth_bond_xmit_policy_set(test_params->slave_port_ids[0],
2357 BALANCE_XMIT_POLICY_LAYER2);
2359 printf("Expected call to failed as invalid port specified.\n");
2363 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2364 BALANCE_XMIT_POLICY_LAYER2);
2366 printf("Failed to set balance xmit policy.\n");
2369 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2370 BALANCE_XMIT_POLICY_LAYER2) {
2371 printf("balance xmit policy not as expected.\n");
2375 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2376 BALANCE_XMIT_POLICY_LAYER23);
2378 printf("Failed to set balance xmit policy.\n");
2381 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2382 BALANCE_XMIT_POLICY_LAYER23) {
2383 printf("balance xmit policy not as expected.\n");
2387 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2388 BALANCE_XMIT_POLICY_LAYER34);
2390 printf("Failed to set balance xmit policy.\n");
2393 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2394 BALANCE_XMIT_POLICY_LAYER34) {
2395 printf("balance xmit policy not as expected.\n");
2399 /* Invalid port id */
2400 if (rte_eth_bond_xmit_policy_get(INVALID_PORT_ID) >= 0)
2403 /* Clean up and remove slaves from bonded device */
2404 return remove_slaves_and_stop_bonded_device();
2407 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2410 test_balance_l2_tx_burst(void)
2412 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2413 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2418 struct rte_eth_stats port_stats;
2420 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
2421 TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1);
2423 printf("Failed to initialize_bonded_device_with_slaves.\n");
2427 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2428 BALANCE_XMIT_POLICY_LAYER2);
2430 printf("Failed to set balance xmit policy.\n");
2435 initialize_eth_header(test_params->pkt_eth_hdr,
2436 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2437 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2439 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2440 dst_addr_0, pktlen);
2442 /* Generate a burst 1 of packets to transmit */
2443 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2444 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2445 test_params->pkt_udp_hdr, burst_size[0]) != burst_size[0])
2448 initialize_eth_header(test_params->pkt_eth_hdr,
2449 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2451 /* Generate a burst 2 of packets to transmit */
2452 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2453 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2454 test_params->pkt_udp_hdr, burst_size[1]) != burst_size[1])
2457 /* Send burst 1 on bonded port */
2458 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2459 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[i][0],
2460 burst_size[i]) != burst_size[i])
2463 /* Verify bonded port tx stats */
2464 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2465 if (port_stats.opackets != (uint64_t)(burst_size[0] + burst_size[1])) {
2466 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2467 test_params->bonded_port_id,
2468 (unsigned int)port_stats.opackets, burst_size[0] + burst_size[1]);
2473 /* Verify slave ports tx stats */
2474 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2475 if (port_stats.opackets != (uint64_t)burst_size[0]) {
2476 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2477 test_params->slave_port_ids[0],
2478 (unsigned int)port_stats.opackets, burst_size[0]);
2482 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2483 if (port_stats.opackets != (uint64_t)burst_size[1]) {
2484 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2485 test_params->slave_port_ids[1], (
2486 unsigned int)port_stats.opackets, burst_size[1]);
2490 /* Put all slaves down and try and transmit */
2491 for (i = 0; i < test_params->bonded_slave_count; i++) {
2493 virtual_ethdev_simulate_link_status_interrupt(
2494 test_params->slave_port_ids[i], 0);
2497 /* Send burst on bonded port */
2498 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[0][0],
2499 burst_size[0]) != 0)
2502 /* Clean up and remove slaves from bonded device */
2503 return remove_slaves_and_stop_bonded_device();
2507 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2508 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2511 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2513 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2514 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2516 struct rte_eth_stats port_stats;
2518 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1);
2520 printf("Failed to initialize_bonded_device_with_slaves.\n");
2524 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2525 BALANCE_XMIT_POLICY_LAYER23);
2527 printf("Failed to set balance xmit policy.\n");
2534 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2535 printf("Burst size specified is greater than supported.\n");
2539 /* Generate test bursts of packets to transmit */
2540 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4,
2541 0, 0, 0) != burst_size_1)
2544 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2545 toggle_mac_addr, toggle_ip_addr, 0) != burst_size_2)
2548 /* Send burst 1 on bonded port */
2549 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2551 if (nb_tx_1 != burst_size_1)
2554 /* Send burst 2 on bonded port */
2555 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2557 if (nb_tx_2 != burst_size_2)
2560 /* Verify bonded port tx stats */
2561 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2562 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2563 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2564 test_params->bonded_port_id,
2565 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2569 /* Verify slave ports tx stats */
2570 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2571 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2572 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2573 test_params->slave_port_ids[0],
2574 (unsigned int)port_stats.opackets, nb_tx_1);
2578 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2579 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2580 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2581 test_params->slave_port_ids[1],
2582 (unsigned int)port_stats.opackets, nb_tx_2);
2586 /* Put all slaves down and try and transmit */
2587 for (i = 0; i < test_params->bonded_slave_count; i++) {
2589 virtual_ethdev_simulate_link_status_interrupt(
2590 test_params->slave_port_ids[i], 0);
2593 /* Send burst on bonded port */
2594 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2599 /* Clean up and remove slaves from bonded device */
2600 return remove_slaves_and_stop_bonded_device();
2604 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2606 return balance_l23_tx_burst(0, 1, 1, 0);
2610 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2612 return balance_l23_tx_burst(1, 1, 0, 1);
2616 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2618 return balance_l23_tx_burst(0, 0, 0, 1);
2622 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2624 return balance_l23_tx_burst(1, 0, 0, 1);
2628 test_balance_l23_tx_burst_toggle_mac_addr(void)
2630 return balance_l23_tx_burst(0, 0, 1, 0);
2634 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2635 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2636 uint8_t toggle_udp_port)
2639 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2641 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2642 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2644 struct rte_eth_stats port_stats;
2646 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1);
2648 printf("Failed to initialize_bonded_device_with_slaves.\n");
2652 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2653 BALANCE_XMIT_POLICY_LAYER34);
2655 printf("Failed to set balance xmit policy.\n");
2662 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2663 printf("Burst size specified is greater than supported.\n");
2667 /* Generate test bursts of packets to transmit */
2668 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0,
2669 0, 0) != burst_size_1)
2672 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2673 toggle_mac_addr, toggle_ip_addr, toggle_udp_port) != burst_size_2)
2676 /* Send burst 1 on bonded port */
2677 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2679 if (nb_tx_1 != burst_size_1)
2682 /* Send burst 2 on bonded port */
2683 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2685 if (nb_tx_2 != burst_size_2)
2689 /* Verify bonded port tx stats */
2690 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2691 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2692 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2693 test_params->bonded_port_id,
2694 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2698 /* Verify slave ports tx stats */
2699 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2700 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2701 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2702 test_params->slave_port_ids[0],
2703 (unsigned int)port_stats.opackets, nb_tx_1);
2707 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2708 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2709 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2710 test_params->slave_port_ids[1],
2711 (unsigned int)port_stats.opackets, nb_tx_2);
2715 /* Put all slaves down and try and transmit */
2716 for (i = 0; i < test_params->bonded_slave_count; i++) {
2718 virtual_ethdev_simulate_link_status_interrupt(
2719 test_params->slave_port_ids[i], 0);
2722 /* Send burst on bonded port */
2723 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2728 /* Clean up and remove slaves from bonded device */
2729 return remove_slaves_and_stop_bonded_device();
2733 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2735 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2739 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2741 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2745 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2747 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2751 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2753 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2757 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2759 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2763 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2765 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2768 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
2771 test_balance_rx_burst(void)
2773 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2775 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2776 struct rte_eth_stats port_stats;
2778 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
2781 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
2783 /* Initialize bonded device with 4 slaves in round robin mode */
2784 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 3, 1)
2788 /* Generate test bursts of packets to transmit */
2789 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2790 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
2791 0, 0) != burst_size[i])
2794 /* Add rx data to slaves */
2795 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2796 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2797 &gen_pkt_burst[i][0], burst_size[i]);
2800 /* Call rx burst on bonded device */
2801 /* Send burst on bonded port */
2802 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2804 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
2805 printf("balance rx burst failed\n");
2809 /* Verify bonded device rx count */
2810 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2811 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
2813 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2814 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
2815 burst_size[0] + burst_size[1] + burst_size[2]);
2820 /* Verify bonded slave devices rx counts */
2821 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2822 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
2823 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2824 test_params->slave_port_ids[0],
2825 (unsigned int)port_stats.ipackets, burst_size[0]);
2829 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2830 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
2831 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2832 test_params->slave_port_ids[1],
2833 (unsigned int)port_stats.ipackets, burst_size[1]);
2837 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2838 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
2839 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2840 test_params->slave_port_ids[2],
2841 (unsigned int)port_stats.ipackets, burst_size[2]);
2845 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2846 if (port_stats.ipackets != 0) {
2847 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2848 test_params->slave_port_ids[3],
2849 (unsigned int)port_stats.ipackets, 0);
2854 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2855 for (j = 0; j < MAX_PKT_BURST; j++) {
2856 if (gen_pkt_burst[i][j] != NULL) {
2857 rte_pktmbuf_free(gen_pkt_burst[i][j]);
2858 gen_pkt_burst[i][j] = NULL;
2863 /* Clean up and remove slaves from bonded device */
2864 return remove_slaves_and_stop_bonded_device();
2868 test_balance_verify_promiscuous_enable_disable(void)
2870 int i, promiscuous_en;
2872 /* Initialize bonded device with 4 slaves in round robin mode */
2873 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 0)
2876 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2878 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2879 if (promiscuous_en != 1) {
2880 printf("Port (%d) promiscuous mode not enabled\n",
2881 test_params->bonded_port_id);
2885 for (i = 0; i < test_params->bonded_slave_count; i++) {
2886 promiscuous_en = rte_eth_promiscuous_get(
2887 test_params->slave_port_ids[i]);
2888 if (promiscuous_en != 1) {
2889 printf("slave port (%d) promiscuous mode not enabled\n",
2890 test_params->slave_port_ids[i]);
2895 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2897 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2898 if (promiscuous_en != 0) {
2899 printf("Port (%d) promiscuous mode not disabled\n",
2900 test_params->bonded_port_id);
2904 for (i = 0; i < test_params->bonded_slave_count; i++) {
2905 promiscuous_en = rte_eth_promiscuous_get(
2906 test_params->slave_port_ids[i]);
2907 if (promiscuous_en != 0) {
2908 printf("slave port (%d) promiscuous mode not disabled\n",
2909 test_params->slave_port_ids[i]);
2914 /* Clean up and remove slaves from bonded device */
2915 return remove_slaves_and_stop_bonded_device();
2919 test_balance_verify_mac_assignment(void)
2921 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2923 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2924 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2926 /* Initialize bonded device with 2 slaves in active backup mode */
2927 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1) != 0)
2930 /* Verify that bonded MACs is that of first slave and that the other slave
2931 * MAC hasn't been changed */
2932 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2933 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2934 printf("bonded port (%d) mac address not set to that of primary port\n",
2935 test_params->bonded_port_id);
2939 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2940 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2941 printf("slave port (%d) mac address not set to that of primary port\n",
2942 test_params->slave_port_ids[0]);
2946 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2947 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2948 printf("slave port (%d) mac address not set to that of primary port\n",
2949 test_params->slave_port_ids[1]);
2953 /* change primary and verify that MAC addresses haven't changed */
2954 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2955 test_params->slave_port_ids[1]) != 0) {
2956 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2957 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2961 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2962 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2963 printf("bonded port (%d) mac address not set to that of primary port\n",
2964 test_params->bonded_port_id);
2968 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2969 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2970 printf("slave port (%d) mac address not set to that of primary port\n",
2971 test_params->slave_port_ids[0]);
2975 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2976 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2977 printf("slave port (%d) mac address not set to that of primary port\n",
2978 test_params->slave_port_ids[1]);
2982 /* stop / start bonded device and verify that primary MAC address is
2983 * propagated to bonded device and slaves */
2985 rte_eth_dev_stop(test_params->bonded_port_id);
2987 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2990 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2991 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2992 printf("bonded port (%d) mac address not set to that of primary port\n",
2993 test_params->bonded_port_id);
2997 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2998 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2999 printf("slave port (%d) mac address not set to that of primary port\n",
3000 test_params->slave_port_ids[0]);
3004 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3005 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3006 printf("slave port (%d) mac address not set to that of primary port\n",
3007 test_params->slave_port_ids[1]);
3011 /* Set explicit MAC address */
3012 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3013 (struct ether_addr *)bonded_mac) != 0)
3016 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3017 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3018 printf("bonded port (%d) mac address not set to that of bonded port\n",
3019 test_params->bonded_port_id);
3023 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3024 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3025 printf("slave port (%d) mac address not as expected\n",
3026 test_params->slave_port_ids[0]);
3030 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3031 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3032 printf("slave port (%d) mac address not set to that of bonded port\n",
3033 test_params->slave_port_ids[1]);
3037 /* Clean up and remove slaves from bonded device */
3038 return remove_slaves_and_stop_bonded_device();
3041 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3044 test_balance_verify_slave_link_status_change_behaviour(void)
3046 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3047 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3048 struct rte_eth_stats port_stats;
3050 uint8_t slaves[RTE_MAX_ETHPORTS];
3052 int i, j, burst_size, slave_count;
3054 memset(pkt_burst, 0, sizeof(pkt_burst));
3056 /* Initialize bonded device with 4 slaves in round robin mode */
3057 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
3058 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
3061 if (rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
3062 BALANCE_XMIT_POLICY_LAYER2)) {
3063 printf("Failed to set balance xmit policy.\n");
3067 /* Verify Current Slaves Count /Active Slave Count is */
3068 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3070 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3071 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
3072 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3076 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3077 slaves, RTE_MAX_ETHPORTS);
3078 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3079 printf("Number of active slaves (%d) is not as expected (%d).\n",
3080 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3084 /* Set 2 slaves link status to down */
3085 virtual_ethdev_simulate_link_status_interrupt(
3086 test_params->slave_port_ids[1], 0);
3087 virtual_ethdev_simulate_link_status_interrupt(
3088 test_params->slave_port_ids[3], 0);
3090 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3091 slaves, RTE_MAX_ETHPORTS) != 2) {
3092 printf("Number of active slaves (%d) is not as expected (%d).\n",
3097 /* Send to sets of packet burst and verify that they are balanced across
3101 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
3103 printf("generate_test_burst failed\n");
3107 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3109 printf("generate_test_burst failed\n");
3113 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3114 burst_size) != burst_size) {
3115 printf("rte_eth_tx_burst failed\n");
3119 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3120 burst_size) != burst_size) {
3121 printf("rte_eth_tx_burst failed\n");
3125 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3126 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3127 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3128 test_params->bonded_port_id, (int)port_stats.opackets,
3129 burst_size + burst_size);
3133 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3134 if (port_stats.opackets != (uint64_t)burst_size) {
3135 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3136 test_params->slave_port_ids[0], (int)port_stats.opackets,
3141 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3142 if (port_stats.opackets != (uint64_t)burst_size) {
3143 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3144 test_params->slave_port_ids[2], (int)port_stats.opackets,
3149 /* verify that all packets get send on primary slave when no other slaves
3151 virtual_ethdev_simulate_link_status_interrupt(
3152 test_params->slave_port_ids[2], 0);
3154 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
3155 RTE_MAX_ETHPORTS) != 1) {
3156 printf("Number of active slaves (%d) is not as expected (%d).\n",
3161 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3163 printf("generate_test_burst failed\n");
3167 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3168 burst_size) != burst_size) {
3169 printf("rte_eth_tx_burst failed\n");
3173 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3174 if (port_stats.opackets != (uint64_t)(burst_size + burst_size +
3176 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3177 test_params->bonded_port_id, (int)port_stats.opackets,
3178 burst_size + burst_size + burst_size);
3182 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3183 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3184 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3185 test_params->slave_port_ids[0], (int)port_stats.opackets,
3186 burst_size + burst_size);
3191 virtual_ethdev_simulate_link_status_interrupt(
3192 test_params->slave_port_ids[0], 0);
3193 virtual_ethdev_simulate_link_status_interrupt(
3194 test_params->slave_port_ids[1], 1);
3195 virtual_ethdev_simulate_link_status_interrupt(
3196 test_params->slave_port_ids[2], 1);
3197 virtual_ethdev_simulate_link_status_interrupt(
3198 test_params->slave_port_ids[3], 1);
3200 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3201 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
3205 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3206 &pkt_burst[i][0], burst_size);
3211 /* Verify that pkts are not received on slaves with link status down */
3213 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3216 /* Verify bonded device rx count */
3217 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3218 if (port_stats.ipackets != (uint64_t)(burst_size * 3)) {
3219 printf("(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3220 test_params->bonded_port_id, (int)port_stats.ipackets,
3225 /* free mbufs allocate for rx testing */
3226 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3227 for (j = 0; j < MAX_PKT_BURST; j++) {
3228 if (pkt_burst[i][j] != NULL) {
3229 rte_pktmbuf_free(pkt_burst[i][j]);
3230 pkt_burst[i][j] = NULL;
3235 /* Clean up and remove slaves from bonded device */
3236 return remove_slaves_and_stop_bonded_device();
3239 /** Broadcast Mode Tests */
3242 test_broadcast_tx_burst(void)
3244 int i, pktlen, retval, burst_size, generated_burst_size, nb_tx;
3245 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3247 struct rte_eth_stats port_stats;
3249 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 2, 1);
3251 printf("Failed to initialize_bonded_device_with_slaves.\n");
3255 initialize_eth_header(test_params->pkt_eth_hdr,
3256 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3258 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3260 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3261 dst_addr_0, pktlen);
3263 burst_size = 20 * test_params->bonded_slave_count;
3265 if (burst_size > MAX_PKT_BURST) {
3266 printf("Burst size specified is greater than supported.\n");
3270 /* Generate a burst of packets to transmit */
3271 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
3272 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3273 1, test_params->pkt_udp_hdr, burst_size);
3274 if (generated_burst_size != burst_size)
3277 /* Send burst on bonded port */
3278 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3280 if (nb_tx != burst_size * test_params->bonded_slave_count) {
3281 printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
3282 test_params->bonded_port_id,
3287 /* Verify bonded port tx stats */
3288 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3289 if (port_stats.opackets != (uint64_t)burst_size *
3290 test_params->bonded_slave_count) {
3291 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3292 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3296 /* Verify slave ports tx stats */
3297 for (i = 0; i < test_params->bonded_slave_count; i++) {
3298 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3299 if (port_stats.opackets != (uint64_t)burst_size) {
3300 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3301 test_params->bonded_port_id,
3302 (unsigned int)port_stats.opackets, burst_size);
3306 /* Put all slaves down and try and transmit */
3307 for (i = 0; i < test_params->bonded_slave_count; i++) {
3309 virtual_ethdev_simulate_link_status_interrupt(
3310 test_params->slave_port_ids[i], 0);
3313 /* Send burst on bonded port */
3314 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3319 /* Clean up and remove slaves from bonded device */
3320 return remove_slaves_and_stop_bonded_device();
3323 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3326 test_broadcast_rx_burst(void)
3328 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3330 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3331 struct rte_eth_stats port_stats;
3333 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3336 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3338 /* Initialize bonded device with 4 slaves in round robin mode */
3339 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 3, 1) != 0)
3343 /* Generate test bursts of packets to transmit */
3344 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3345 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0,
3346 0) != burst_size[i])
3350 /* Add rx data to slave 0 */
3351 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3352 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3353 &gen_pkt_burst[i][0], burst_size[i]);
3357 /* Call rx burst on bonded device */
3358 /* Send burst on bonded port */
3359 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3361 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3362 printf("round-robin rx burst failed");
3366 /* Verify bonded device rx count */
3367 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3368 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3370 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3371 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3372 burst_size[0] + burst_size[1] + burst_size[2]);
3377 /* Verify bonded slave devices rx counts */
3378 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3379 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3380 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3381 test_params->slave_port_ids[0],
3382 (unsigned int)port_stats.ipackets, burst_size[0]);
3386 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3387 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3388 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3389 test_params->slave_port_ids[1],
3390 (unsigned int)port_stats.ipackets, burst_size[1]);
3394 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3395 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3396 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3397 test_params->slave_port_ids[2],
3398 (unsigned int)port_stats.ipackets,
3403 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3404 if (port_stats.ipackets != 0) {
3405 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3406 test_params->slave_port_ids[3],
3407 (unsigned int)port_stats.ipackets, 0);
3411 /* free mbufs allocate for rx testing */
3412 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3413 for (j = 0; j < MAX_PKT_BURST; j++) {
3414 if (gen_pkt_burst[i][j] != NULL) {
3415 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3416 gen_pkt_burst[i][j] = NULL;
3421 /* Clean up and remove slaves from bonded device */
3422 return remove_slaves_and_stop_bonded_device();
3426 test_broadcast_verify_promiscuous_enable_disable(void)
3428 int i, promiscuous_en;
3430 /* Initialize bonded device with 4 slaves in round robin mode */
3431 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 0)
3434 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3436 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3437 if (promiscuous_en != 1) {
3438 printf("Port (%d) promiscuous mode not enabled\n",
3439 test_params->bonded_port_id);
3443 for (i = 0; i < test_params->bonded_slave_count; i++) {
3444 promiscuous_en = rte_eth_promiscuous_get(
3445 test_params->slave_port_ids[i]);
3446 if (promiscuous_en != 1) {
3447 printf("slave port (%d) promiscuous mode not enabled\n",
3448 test_params->slave_port_ids[i]);
3453 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3455 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3456 if (promiscuous_en != 0) {
3457 printf("Port (%d) promiscuous mode not disabled\n",
3458 test_params->bonded_port_id);
3462 for (i = 0; i < test_params->bonded_slave_count; i++) {
3463 promiscuous_en = rte_eth_promiscuous_get(
3464 test_params->slave_port_ids[i]);
3465 if (promiscuous_en != 0) {
3466 printf("slave port (%d) promiscuous mode not disabled\n",
3467 test_params->slave_port_ids[i]);
3472 /* Clean up and remove slaves from bonded device */
3473 return remove_slaves_and_stop_bonded_device();
3477 test_broadcast_verify_mac_assignment(void)
3479 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3483 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3484 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3486 /* Initialize bonded device with 4 slaves in round robin mode */
3487 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 4, 1) != 0)
3490 /* Verify that all MACs are the same as first slave added to bonded
3492 for (i = 0; i < test_params->bonded_slave_count; i++) {
3493 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3494 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3495 sizeof(read_mac_addr))) {
3496 printf("slave port (%d) mac address not set to that of primary port\n",
3497 test_params->slave_port_ids[i]);
3502 /* change primary and verify that MAC addresses haven't changed */
3503 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
3504 test_params->slave_port_ids[2]);
3506 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3507 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3511 for (i = 0; i < test_params->bonded_slave_count; i++) {
3512 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3513 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3514 sizeof(read_mac_addr))) {
3515 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
3516 test_params->slave_port_ids[i]);
3521 /* stop / start bonded device and verify that primary MAC address is
3522 * propagated to bonded device and slaves */
3524 rte_eth_dev_stop(test_params->bonded_port_id);
3526 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3529 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3530 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3531 printf("bonded port (%d) mac address not set to that of new primary port\n",
3532 test_params->slave_port_ids[i]);
3536 for (i = 0; i < test_params->bonded_slave_count; i++) {
3537 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3538 if (memcmp(&expected_mac_addr_1, &read_mac_addr,
3539 sizeof(read_mac_addr))) {
3540 printf("slave port (%d) mac address not set to that of new primary port\n",
3541 test_params->slave_port_ids[i]);
3546 /* Set explicit MAC address */
3547 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3548 (struct ether_addr *)bonded_mac) != 0)
3551 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3552 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3553 printf("bonded port (%d) mac address not set to that of new primary port\n",
3554 test_params->slave_port_ids[i]);
3558 for (i = 0; i < test_params->bonded_slave_count; i++) {
3559 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3560 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3561 printf("slave port (%d) mac address not set to that of new primary port\n",
3562 test_params->slave_port_ids[i]);
3567 /* Clean up and remove slaves from bonded device */
3568 return remove_slaves_and_stop_bonded_device();
3571 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3573 test_broadcast_verify_slave_link_status_change_behaviour(void)
3575 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3576 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3577 struct rte_eth_stats port_stats;
3579 uint8_t slaves[RTE_MAX_ETHPORTS];
3581 int i, j, burst_size, slave_count;
3583 memset(pkt_burst, 0, sizeof(pkt_burst));
3585 /* Initialize bonded device with 4 slaves in round robin mode */
3586 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST,
3587 BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
3590 /* Verify Current Slaves Count /Active Slave Count is */
3591 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3593 if (slave_count != 4) {
3594 printf("Number of slaves (%d) is not as expected (%d).\n",
3599 slave_count = rte_eth_bond_active_slaves_get(
3600 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
3601 if (slave_count != 4) {
3602 printf("Number of active slaves (%d) is not as expected (%d).\n",
3607 /* Set 2 slaves link status to down */
3608 virtual_ethdev_simulate_link_status_interrupt(
3609 test_params->slave_port_ids[1], 0);
3610 virtual_ethdev_simulate_link_status_interrupt(
3611 test_params->slave_port_ids[3], 0);
3613 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3614 slaves, RTE_MAX_ETHPORTS);
3615 if (slave_count != 2) {
3616 printf("Number of active slaves (%d) is not as expected (%d).\n",
3621 for (i = 0; i < test_params->bonded_slave_count; i++)
3622 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3624 /* Verify that pkts are not sent on slaves with link status down */
3627 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0) !=
3629 printf("generate_test_burst failed\n");
3633 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3634 burst_size) != (burst_size * slave_count)) {
3635 printf("rte_eth_tx_burst failed\n");
3639 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3640 if (port_stats.opackets != (uint64_t)(burst_size * slave_count)) {
3641 printf("(%d) port_stats.opackets (%d) not as expected (%d)\n",
3642 test_params->bonded_port_id, (int)port_stats.opackets,
3643 burst_size * slave_count);
3647 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3648 if (port_stats.opackets != (uint64_t)burst_size) {
3649 printf("(%d) port_stats.opackets not as expected\n",
3650 test_params->slave_port_ids[0]);
3654 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3655 if (port_stats.opackets != 0) {
3656 printf("(%d) port_stats.opackets not as expected\n",
3657 test_params->slave_port_ids[1]);
3661 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3662 if (port_stats.opackets != (uint64_t)burst_size) {
3663 printf("(%d) port_stats.opackets not as expected\n",
3664 test_params->slave_port_ids[2]);
3668 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3669 if (port_stats.opackets != 0) {
3670 printf("(%d) port_stats.opackets not as expected\n",
3671 test_params->slave_port_ids[3]);
3675 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3676 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0) !=
3681 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3682 &pkt_burst[i][0], burst_size);
3685 /* Verify that pkts are not received on slaves with link status down */
3687 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3689 burst_size + burst_size) {
3690 printf("rte_eth_rx_burst\n");
3694 /* Verify bonded device rx count */
3695 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3696 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
3697 printf("(%d) port_stats.ipackets not as expected\n",
3698 test_params->bonded_port_id);
3702 /* free mbufs allocate for rx testing */
3703 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3704 for (j = 0; j < MAX_PKT_BURST; j++) {
3705 if (pkt_burst[i][j] != NULL) {
3706 rte_pktmbuf_free(pkt_burst[i][j]);
3707 pkt_burst[i][j] = NULL;
3712 /* Clean up and remove slaves from bonded device */
3713 return remove_slaves_and_stop_bonded_device();
3717 test_reconfigure_bonded_device(void)
3719 test_params->nb_rx_q = 4;
3720 test_params->nb_tx_q = 4;
3722 if (configure_ethdev(test_params->bonded_port_id, 0) != 0) {
3723 printf("failed to reconfigure bonded device");
3728 test_params->nb_rx_q = 2;
3729 test_params->nb_tx_q = 2;
3731 if (configure_ethdev(test_params->bonded_port_id, 0) != 0) {
3732 printf("failed to reconfigure bonded device with less rx/tx queues");
3741 test_close_bonded_device(void)
3743 rte_eth_dev_close(test_params->bonded_port_id);
3748 testsuite_teardown(void)
3750 if (test_params->pkt_eth_hdr != NULL)
3751 free(test_params->pkt_eth_hdr);
3757 int (*test_function)(void);
3758 const char *success_msg;
3759 const char *fail_msg;
3762 struct unittest_suite {
3763 int (*setup_function)(void);
3764 int (*teardown_function)(void);
3765 struct unittest unittests[];
3768 static struct unittest_suite link_bonding_test_suite = {
3769 .setup_function = test_setup,
3770 .teardown_function = testsuite_teardown,
3772 { test_create_bonded_device, "test_create_bonded_device succeeded",
3773 "test_create_bonded_device failed" },
3774 { test_create_bonded_device_with_invalid_params,
3775 "test_create_bonded_device_with_invalid_params succeeded",
3776 "test_create_bonded_device_with_invalid_params failed" },
3777 { test_add_slave_to_bonded_device,
3778 "test_add_slave_to_bonded_device succeeded",
3779 "test_add_slave_to_bonded_device failed" },
3780 { test_add_slave_to_invalid_bonded_device,
3781 "test_add_slave_to_invalid_bonded_device succeeded",
3782 "test_add_slave_to_invalid_bonded_device failed" },
3783 { test_remove_slave_from_bonded_device,
3784 "test_remove_slave_from_bonded_device succeeded ",
3785 "test_remove_slave_from_bonded_device failed" },
3786 { test_remove_slave_from_invalid_bonded_device,
3787 "test_remove_slave_from_invalid_bonded_device succeeded",
3788 "test_remove_slave_from_invalid_bonded_device failed" },
3789 { test_get_slaves_from_bonded_device,
3790 "test_get_slaves_from_bonded_device succeeded",
3791 "test_get_slaves_from_bonded_device failed" },
3792 { test_add_already_bonded_slave_to_bonded_device,
3793 "test_add_already_bonded_slave_to_bonded_device succeeded",
3794 "test_add_already_bonded_slave_to_bonded_device failed" },
3795 { test_add_remove_multiple_slaves_to_from_bonded_device,
3796 "test_add_remove_multiple_slaves_to_from_bonded_device succeeded",
3797 "test_add_remove_multiple_slaves_to_from_bonded_device failed" },
3798 { test_start_bonded_device,
3799 "test_start_bonded_device succeeded",
3800 "test_start_bonded_device failed" },
3801 { test_stop_bonded_device,
3802 "test_stop_bonded_device succeeded",
3803 "test_stop_bonded_device failed" },
3804 { test_set_bonding_mode,
3805 "test_set_bonding_mode succeeded",
3806 "test_set_bonding_mode failed" },
3807 { test_set_primary_slave,
3808 "test_set_primary_slave succeeded",
3809 "test_set_primary_slave failed" },
3810 { test_set_explicit_bonded_mac,
3811 "test_set_explicit_bonded_mac succeeded",
3812 "test_set_explicit_bonded_mac failed" },
3813 { test_adding_slave_after_bonded_device_started,
3814 "test_adding_slave_after_bonded_device_started succeeded",
3815 "test_adding_slave_after_bonded_device_started failed" },
3816 { test_roundrobin_tx_burst,
3817 "test_roundrobin_tx_burst succeeded",
3818 "test_roundrobin_tx_burst failed" },
3819 { test_roundrobin_rx_burst_on_single_slave,
3820 "test_roundrobin_rx_burst_on_single_slave succeeded",
3821 "test_roundrobin_rx_burst_on_single_slave failed" },
3822 { test_roundrobin_rx_burst_on_multiple_slaves,
3823 "test_roundrobin_rx_burst_on_multiple_slaves succeeded",
3824 "test_roundrobin_rx_burst_on_multiple_slaves failed" },
3825 { test_roundrobin_verify_promiscuous_enable_disable,
3826 "test_roundrobin_verify_promiscuous_enable_disable succeeded",
3827 "test_roundrobin_verify_promiscuous_enable_disable failed" },
3828 { test_roundrobin_verify_mac_assignment,
3829 "test_roundrobin_verify_mac_assignment succeeded",
3830 "test_roundrobin_verify_mac_assignment failed" },
3831 { test_roundrobin_verify_slave_link_status_change_behaviour,
3832 "test_roundrobin_verify_slave_link_status_change_behaviour succeeded",
3833 "test_roundrobin_verify_slave_link_status_change_behaviour failed" },
3834 { test_activebackup_tx_burst,
3835 "test_activebackup_tx_burst succeeded",
3836 "test_activebackup_tx_burst failed" },
3837 { test_activebackup_rx_burst,
3838 "test_activebackup_rx_burst succeeded",
3839 "test_activebackup_rx_burst failed" },
3840 { test_activebackup_verify_promiscuous_enable_disable,
3841 "test_activebackup_verify_promiscuous_enable_disable succeeded",
3842 "test_activebackup_verify_promiscuous_enable_disable failed" },
3843 { test_activebackup_verify_mac_assignment,
3844 "test_activebackup_verify_mac_assignment succeeded",
3845 "test_activebackup_verify_mac_assignment failed" },
3846 { test_activebackup_verify_slave_link_status_change_failover,
3847 "test_activebackup_verify_slave_link_status_change_failover succeeded",
3848 "test_activebackup_verify_slave_link_status_change_failover failed" },
3849 { test_balance_xmit_policy_configuration,
3850 "test_balance_xmit_policy_configuration succeeded",
3851 "test_balance_xmit_policy_configuration failed" },
3852 { test_balance_l2_tx_burst,
3853 "test_balance_l2_tx_burst succeeded",
3854 "test_balance_l2_tx_burst failed" },
3855 { test_balance_l23_tx_burst_ipv4_toggle_ip_addr,
3856 "test_balance_l23_tx_burst_ipv4_toggle_ip_addr succeeded",
3857 "test_balance_l23_tx_burst_ipv4_toggle_ip_addr failed" },
3858 { test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr,
3859 "test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr succeeded",
3860 "test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr failed" },
3861 { test_balance_l23_tx_burst_ipv6_toggle_ip_addr,
3862 "test_balance_l23_tx_burst_ipv6_toggle_ip_addr succeeded",
3863 "test_balance_l23_tx_burst_ipv6_toggle_ip_addr failed" },
3864 { test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr,
3865 "test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr succeeded",
3866 "test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr failed" },
3867 { test_balance_l23_tx_burst_toggle_mac_addr,
3868 "test_balance_l23_tx_burst_toggle_mac_addr succeeded",
3869 "test_balance_l23_tx_burst_toggle_mac_addr failed" },
3870 { test_balance_l34_tx_burst_ipv4_toggle_ip_addr,
3871 "test_balance_l34_tx_burst_ipv4_toggle_ip_addr succeeded",
3872 "test_balance_l34_tx_burst_ipv4_toggle_ip_addr failed" },
3873 { test_balance_l34_tx_burst_ipv4_toggle_udp_port,
3874 "test_balance_l34_tx_burst_ipv4_toggle_udp_port succeeded",
3875 "test_balance_l34_tx_burst_ipv4_toggle_udp_port failed" },
3876 { test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr,
3877 "test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr succeeded",
3878 "test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr failed" },
3879 { test_balance_l34_tx_burst_ipv6_toggle_ip_addr,
3880 "test_balance_l34_tx_burst_ipv6_toggle_ip_addr succeeded",
3881 "test_balance_l34_tx_burst_ipv6_toggle_ip_addr failed" },
3882 { test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr,
3883 "test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr succeeded",
3884 "test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr failed" },
3885 { test_balance_l34_tx_burst_ipv6_toggle_udp_port,
3886 "test_balance_l34_tx_burst_ipv6_toggle_udp_port succeeded",
3887 "test_balance_l34_tx_burst_ipv6_toggle_udp_port failed" },
3888 { test_balance_rx_burst,
3889 "test_balance_rx_burst succeeded",
3890 "test_balance_rx_burst failed" },
3891 { test_balance_verify_promiscuous_enable_disable,
3892 "test_balance_verify_promiscuous_enable_disable succeeded",
3893 "test_balance_verify_promiscuous_enable_disable failed" },
3894 { test_balance_verify_mac_assignment,
3895 "test_balance_verify_mac_assignment succeeded",
3896 "test_balance_verify_mac_assignment failed" },
3897 { test_balance_verify_slave_link_status_change_behaviour,
3898 "test_balance_verify_slave_link_status_change_behaviour succeeded",
3899 "test_balance_verify_slave_link_status_change_behaviour failed" },
3900 { test_broadcast_tx_burst,
3901 "test_broadcast_tx_burst succeeded",
3902 "test_broadcast_tx_burst failed" },
3903 { test_broadcast_rx_burst,
3904 "test_broadcast_rx_burst succeeded",
3905 "test_broadcast_rx_burst failed" },
3906 { test_broadcast_verify_promiscuous_enable_disable,
3907 "test_broadcast_verify_promiscuous_enable_disable succeeded",
3908 "test_broadcast_verify_promiscuous_enable_disable failed" },
3909 { test_broadcast_verify_mac_assignment,
3910 "test_broadcast_verify_mac_assignment succeeded",
3911 "test_broadcast_verify_mac_assignment failed" },
3912 { test_broadcast_verify_slave_link_status_change_behaviour,
3913 "test_broadcast_verify_slave_link_status_change_behaviour succeeded",
3914 "test_broadcast_verify_slave_link_status_change_behaviour failed" },
3915 { test_reconfigure_bonded_device,
3916 "test_reconfigure_bonded_device succeeded",
3917 "test_reconfigure_bonded_device failed" },
3918 { test_close_bonded_device,
3919 "test_close_bonded_device succeeded",
3920 "test_close_bonded_device failed" },
3922 { NULL , NULL, NULL } /**< NULL terminate unit test array */
3928 test_link_bonding(void)
3932 if (link_bonding_test_suite.setup_function) {
3933 if (link_bonding_test_suite.setup_function() != 0)
3937 while (link_bonding_test_suite.unittests[i].test_function) {
3938 if (link_bonding_test_suite.unittests[i].test_function() == 0) {
3939 printf("%s", link_bonding_test_suite.unittests[i].success_msg ?
3940 link_bonding_test_suite.unittests[i].success_msg :
3941 "unit test succeeded");
3943 printf("%s", link_bonding_test_suite.unittests[i].fail_msg ?
3944 link_bonding_test_suite.unittests[i].fail_msg :
3945 "unit test failed");
3952 if (link_bonding_test_suite.teardown_function) {
3953 if (link_bonding_test_suite.teardown_function() != 0)