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 = { -1 },
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\n", port_id);
265 static int slaves_initialized;
270 int i, retval, nb_mbuf_per_pool;
271 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
273 /* Allocate ethernet packet header with space for VLAN header */
274 if (test_params->pkt_eth_hdr == NULL) {
275 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
276 sizeof(struct vlan_hdr));
278 if (test_params->pkt_eth_hdr == NULL) {
279 printf("ethernet header struct allocation failed!\n");
284 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
285 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
286 if (test_params->mbuf_pool == NULL) {
287 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
288 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
289 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
291 if (test_params->mbuf_pool == NULL) {
292 printf("rte_mempool_create failed\n");
297 /* Create / Initialize virtual eth devs */
298 if (!slaves_initialized) {
299 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
300 char pmd_name[RTE_ETH_NAME_MAX_LEN];
302 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
304 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
306 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
307 mac_addr, rte_socket_id());
308 if (test_params->slave_port_ids[i] < 0) {
309 printf("Failed to create virtual virtual ethdev %s\n", pmd_name);
313 printf("Created virtual ethdev %s\n", pmd_name);
315 retval = configure_ethdev(test_params->slave_port_ids[i], 1);
317 printf("Failed to configure virtual ethdev %s\n", pmd_name);
321 printf("Configured virtual ethdev %s\n", pmd_name);
323 slaves_initialized = 1;
330 test_create_bonded_device(void)
332 int current_slave_count;
334 uint8_t slaves[RTE_MAX_ETHPORTS];
336 /* Don't try to recreate bonded device if re-running test suite*/
337 if (test_params->bonded_port_id == -1) {
338 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
339 test_params->bonding_mode, rte_socket_id());
341 TEST_ASSERT(test_params->bonded_port_id >= 0,
342 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
344 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0),
345 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
348 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
349 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
350 test_params->bonded_port_id, test_params->bonding_mode);
352 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
353 slaves, RTE_MAX_ETHPORTS);
355 TEST_ASSERT(current_slave_count == 0,
356 "Number of slaves %d is great than expected %d.",
357 current_slave_count, 0);
359 current_slave_count = rte_eth_bond_active_slaves_get(
360 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
362 TEST_ASSERT(current_slave_count == 0,
363 "Number of active slaves %d is great than expected %d.",
364 current_slave_count, 0);
371 test_create_bonded_device_with_invalid_params(void)
375 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
378 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
381 printf("Created bonded device unexpectedly.\n");
385 test_params->bonding_mode = INVALID_BONDING_MODE;
387 /* Invalid bonding mode */
388 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
391 printf("Created bonded device unexpectedly.\n");
395 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
397 /* Invalid socket id */
398 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
401 printf("Created bonded device unexpectedly.\n");
409 test_add_slave_to_bonded_device(void)
411 int retval, current_slave_count;
413 uint8_t slaves[RTE_MAX_ETHPORTS];
415 retval = rte_eth_bond_slave_add(test_params->bonded_port_id,
416 test_params->slave_port_ids[test_params->bonded_slave_count]);
418 printf("Failed to add slave (%d) to bonded port (%d).\n",
419 test_params->bonded_port_id,
420 test_params->slave_port_ids[test_params->bonded_slave_count]);
424 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
425 slaves, RTE_MAX_ETHPORTS);
426 if (current_slave_count != test_params->bonded_slave_count + 1) {
427 printf("Number of slaves (%d) is greater than expected (%d).\n",
428 current_slave_count, test_params->bonded_slave_count + 1);
432 current_slave_count = rte_eth_bond_active_slaves_get(
433 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
434 if (current_slave_count != 0) {
435 printf("Number of active slaves (%d) is not as expected (%d).\n",
436 current_slave_count, 0);
440 test_params->bonded_slave_count++;
446 test_add_slave_to_invalid_bonded_device(void)
450 /* Invalid port ID */
451 retval = rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
452 test_params->slave_port_ids[test_params->bonded_slave_count]);
454 printf("Expected call to failed as invalid port specified.\n");
458 /* Non bonded device */
459 retval = rte_eth_bond_slave_add(test_params->slave_port_ids[0],
460 test_params->slave_port_ids[test_params->bonded_slave_count]);
462 printf("Expected call to failed as invalid port specified.\n");
471 test_remove_slave_from_bonded_device(void)
473 int retval, current_slave_count;
474 struct ether_addr read_mac_addr, *mac_addr;
475 uint8_t slaves[RTE_MAX_ETHPORTS];
477 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id,
478 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
480 printf("\t Failed to remove slave %d from bonded port (%d).\n",
481 test_params->slave_port_ids[test_params->bonded_slave_count-1],
482 test_params->bonded_port_id);
487 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
488 slaves, RTE_MAX_ETHPORTS);
489 if (current_slave_count != test_params->bonded_slave_count - 1) {
490 printf("Number of slaves (%d) is great than expected (%d).\n",
491 current_slave_count, 0);
496 mac_addr = (struct ether_addr *)slave_mac;
497 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
498 test_params->slave_port_ids[test_params->bonded_slave_count-1];
501 test_params->slave_port_ids[test_params->bonded_slave_count-1],
503 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
504 printf("bonded port mac address not set to that of primary port\n");
509 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
511 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
514 test_params->bonded_slave_count--;
520 test_remove_slave_from_invalid_bonded_device(void)
524 /* Invalid port ID */
525 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id + 5,
526 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
528 printf("Expected call to failed as invalid port specified.\n");
532 /* Non bonded device */
533 retval = rte_eth_bond_slave_remove(test_params->slave_port_ids[0],
534 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
536 printf("Expected call to failed as invalid port specified.\n");
543 static int bonded_id = 2;
546 test_add_already_bonded_slave_to_bonded_device(void)
548 int retval, port_id, current_slave_count;
549 uint8_t slaves[RTE_MAX_ETHPORTS];
550 char pmd_name[RTE_ETH_NAME_MAX_LEN];
552 test_add_slave_to_bonded_device();
554 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
555 slaves, RTE_MAX_ETHPORTS);
556 if (current_slave_count != 1) {
557 printf("Number of slaves (%d) is not that expected (%d).\n",
558 current_slave_count, 1);
562 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
564 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
567 printf("Failed to create bonded device.\n");
571 retval = rte_eth_bond_slave_add(port_id,
572 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
574 printf("Added slave (%d) to bonded port (%d) unexpectedly.\n",
575 test_params->slave_port_ids[test_params->bonded_slave_count-1],
580 return test_remove_slave_from_bonded_device();
585 test_get_slaves_from_bonded_device(void)
587 int retval, current_slave_count;
589 uint8_t slaves[RTE_MAX_ETHPORTS];
591 retval = test_add_slave_to_bonded_device();
595 /* Invalid port id */
596 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
598 if (current_slave_count >= 0)
601 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
602 slaves, RTE_MAX_ETHPORTS);
603 if (current_slave_count >= 0)
606 /* Invalid slaves pointer */
607 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
608 NULL, RTE_MAX_ETHPORTS);
609 if (current_slave_count >= 0)
612 current_slave_count = rte_eth_bond_active_slaves_get(
613 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
614 if (current_slave_count >= 0)
617 /* non bonded device*/
618 current_slave_count = rte_eth_bond_slaves_get(
619 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
620 if (current_slave_count >= 0)
623 current_slave_count = rte_eth_bond_active_slaves_get(
624 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
625 if (current_slave_count >= 0)
628 retval = test_remove_slave_from_bonded_device();
637 test_add_remove_multiple_slaves_to_from_bonded_device(void)
641 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
642 if (test_add_slave_to_bonded_device() != 0)
646 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
647 if (test_remove_slave_from_bonded_device() != 0)
655 enable_bonded_slaves(void)
659 for (i = 0; i < test_params->bonded_slave_count; i++) {
660 virtual_ethdev_simulate_link_status_interrupt(
661 test_params->slave_port_ids[i], 1);
666 test_start_bonded_device(void)
668 struct rte_eth_link link_status;
670 int current_slave_count, current_bonding_mode, primary_port;
671 uint8_t slaves[RTE_MAX_ETHPORTS];
673 /* Add slave to bonded device*/
674 if (test_add_slave_to_bonded_device() != 0)
677 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
678 "Failed to start bonded pmd eth device %d.",
679 test_params->bonded_port_id);
681 /* Change link status of virtual pmd so it will be added to the active
682 * slave list of the bonded device*/
683 virtual_ethdev_simulate_link_status_interrupt(
684 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
686 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
687 slaves, RTE_MAX_ETHPORTS);
688 if (current_slave_count != test_params->bonded_slave_count) {
689 printf("Number of slaves (%d) is not expected value (%d).\n",
690 current_slave_count, test_params->bonded_slave_count);
694 current_slave_count = rte_eth_bond_active_slaves_get(
695 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
696 if (current_slave_count != test_params->bonded_slave_count) {
697 printf("Number of active slaves (%d) is not expected value (%d).\n",
698 current_slave_count, test_params->bonded_slave_count);
702 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
703 if (current_bonding_mode != test_params->bonding_mode) {
704 printf("Bonded device mode (%d) is not expected value (%d).\n",
705 current_bonding_mode, test_params->bonding_mode);
710 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
711 if (primary_port != test_params->slave_port_ids[0]) {
712 printf("Primary port (%d) is not expected value (%d).\n",
713 primary_port, test_params->slave_port_ids[0]);
718 rte_eth_link_get(test_params->bonded_port_id, &link_status);
719 if (!link_status.link_status) {
720 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
721 test_params->bonded_port_id, link_status.link_status, 1);
730 test_stop_bonded_device(void)
732 int current_slave_count;
733 uint8_t slaves[RTE_MAX_ETHPORTS];
735 struct rte_eth_link link_status;
737 rte_eth_dev_stop(test_params->bonded_port_id);
739 rte_eth_link_get(test_params->bonded_port_id, &link_status);
740 if (link_status.link_status) {
741 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
742 test_params->bonded_port_id, link_status.link_status, 0);
746 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
747 slaves, RTE_MAX_ETHPORTS);
748 if (current_slave_count != test_params->bonded_slave_count) {
749 printf("Number of slaves (%d) is not expected value (%d).\n",
750 current_slave_count, test_params->bonded_slave_count);
754 current_slave_count = rte_eth_bond_active_slaves_get(
755 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
756 if (current_slave_count != 0) {
757 printf("Number of active slaves (%d) is not expected value (%d).\n",
758 current_slave_count, 0);
765 static int remove_slaves_and_stop_bonded_device(void)
767 /* Clean up and remove slaves from bonded device */
768 while (test_params->bonded_slave_count > 0) {
769 if (test_remove_slave_from_bonded_device() != 0) {
770 printf("test_remove_slave_from_bonded_device failed\n");
775 rte_eth_dev_stop(test_params->bonded_port_id);
776 rte_eth_stats_reset(test_params->bonded_port_id);
777 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
783 test_set_bonding_mode(void)
786 int retval, bonding_mode;
788 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
789 BONDING_MODE_ACTIVE_BACKUP,
790 BONDING_MODE_BALANCE,
791 #ifdef RTE_MBUF_REFCNT
792 BONDING_MODE_BROADCAST
796 /* Test supported link bonding modes */
797 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
798 /* Invalid port ID */
799 retval = rte_eth_bond_mode_set(INVALID_PORT_ID, bonding_modes[i]);
801 printf("Expected call to failed as invalid port (%d) specified.\n",
806 /* Non bonded device */
807 retval = rte_eth_bond_mode_set(test_params->slave_port_ids[0],
810 printf("Expected call to failed as invalid port (%d) specified.\n",
811 test_params->slave_port_ids[0]);
815 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
818 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
819 test_params->bonded_port_id, bonding_modes[i]);
823 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
824 if (bonding_mode != bonding_modes[i]) {
825 printf("Link bonding mode (%d) of port (%d) is not expected value (%d).\n",
826 bonding_mode, test_params->bonded_port_id,
832 /* Invalid port ID */
833 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
834 if (bonding_mode >= 0) {
835 printf("Expected call to failed as invalid port (%d) specified.\n",
841 /* Non bonded device */
842 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
843 if (bonding_mode >= 0) {
844 printf("Expected call to failed as invalid port (%d) specified.\n",
845 test_params->slave_port_ids[0]);
851 return remove_slaves_and_stop_bonded_device();
855 test_set_primary_slave(void)
858 struct ether_addr read_mac_addr;
859 struct ether_addr *expected_mac_addr;
861 /* Add 4 slaves to bonded device */
862 for (i = test_params->bonded_slave_count; i < 4; i++) {
863 retval = test_add_slave_to_bonded_device();
865 printf("Failed to add slave to bonded device.\n");
869 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
870 BONDING_MODE_ROUND_ROBIN);
872 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
873 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
877 /* Invalid port ID */
878 retval = rte_eth_bond_primary_set(INVALID_PORT_ID,
879 test_params->slave_port_ids[i]);
881 printf("Expected call to failed as invalid port specified.\n");
885 /* Set slave as primary
886 * Verify slave it is now primary slave
887 * Verify that MAC address of bonded device is that of primary slave
888 * Verify that MAC address of all bonded slaves are that of primary slave
890 for (i = 0; i < 4; i++) {
892 /* Non bonded device */
893 retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
894 test_params->slave_port_ids[i]);
896 printf("Expected call to failed as invalid port specified.\n");
900 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
901 test_params->slave_port_ids[i]);
903 printf("Failed to set bonded port (%d) primary port to (%d)\n",
904 test_params->bonded_port_id,
905 test_params->slave_port_ids[i]);
909 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
911 printf("Failed to read primary port from bonded port (%d)\n",
912 test_params->bonded_port_id);
914 } else if (retval != test_params->slave_port_ids[i]) {
915 printf("Bonded port (%d) primary port (%d) not expected value (%d)\n",
916 test_params->bonded_port_id, retval,
917 test_params->slave_port_ids[i]);
921 /* stop/start bonded eth dev to apply new MAC */
922 rte_eth_dev_stop(test_params->bonded_port_id);
923 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
926 expected_mac_addr = (struct ether_addr *)&slave_mac;
927 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
928 test_params->slave_port_ids[i];
930 /* Check primary slave MAC */
931 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
932 if (memcmp(expected_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
933 printf("bonded port mac address not set to that of primary port\n");
937 /* Check bonded MAC */
938 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
939 if (memcmp(&read_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
940 printf("bonded port mac address not set to that of primary port\n");
944 /* Check other slaves MACs */
945 for (j = 0; j < 4; j++) {
947 rte_eth_macaddr_get(test_params->slave_port_ids[j],
949 if (memcmp(expected_mac_addr, &read_mac_addr,
950 sizeof(read_mac_addr))) {
951 printf("slave port mac address not set to that of primary port\n");
959 /* Test with none existent port */
960 retval = rte_eth_bond_primary_get(test_params->bonded_port_id + 10);
962 printf("read primary port from expectedly\n");
966 /* Test with slave port */
967 retval = rte_eth_bond_primary_get(test_params->slave_port_ids[0]);
969 printf("read primary port from expectedly\n");
973 if (remove_slaves_and_stop_bonded_device() != 0)
977 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
979 printf("read primary port from expectedly\n");
987 test_set_explicit_bonded_mac(void)
990 struct ether_addr read_mac_addr;
991 struct ether_addr *mac_addr;
993 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
995 mac_addr = (struct ether_addr *)explicit_bonded_mac;
997 /* Invalid port ID */
998 retval = rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr);
1000 printf("Expected call to failed as invalid port specified.\n");
1004 /* Non bonded device */
1005 retval = rte_eth_bond_mac_address_set(test_params->slave_port_ids[0],
1008 printf("Expected call to failed as invalid port specified.\n");
1012 /* NULL MAC address */
1013 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id, NULL);
1015 printf("Expected call to failed as NULL MAC specified\n");
1019 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1022 printf("Failed to set MAC address on bonded port (%d)\n",
1023 test_params->bonded_port_id);
1027 /* Add 4 slaves to bonded device */
1028 for (i = test_params->bonded_slave_count; i < 4; i++) {
1029 retval = test_add_slave_to_bonded_device();
1031 printf("Failed to add slave to bonded device.\n");
1036 /* Check bonded MAC */
1037 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1038 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1039 printf("bonded port mac address not set to that of primary port\n");
1043 /* Check other slaves MACs */
1044 for (i = 0; i < 4; i++) {
1045 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1046 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1047 printf("slave port mac address not set to that of primary port\n");
1052 /* test resetting mac address on bonded device */
1053 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1054 printf("Failed to reset MAC address on bonded port (%d)\n",
1055 test_params->bonded_port_id);
1060 if (rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]) == 0) {
1061 printf("Reset MAC address on bonded port (%d) unexpectedly\n",
1062 test_params->slave_port_ids[1]);
1067 /* test resetting mac address on bonded device with no slaves */
1069 if (remove_slaves_and_stop_bonded_device() != 0)
1072 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1073 printf("Failed to reset MAC address on bonded port (%d)\n",
1074 test_params->bonded_port_id);
1084 initialize_bonded_device_with_slaves(uint8_t bonding_mode,
1085 uint8_t number_of_slaves, uint8_t enable_slave)
1087 /* configure bonded device */
1088 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0),
1089 "Failed to configure bonding port (%d) in mode %d "
1090 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1093 while (number_of_slaves > test_params->bonded_slave_count) {
1094 /* Add slaves to bonded device */
1095 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1096 "Failed to add slave (%d to bonding port (%d).",
1097 test_params->bonded_slave_count - 1,
1098 test_params->bonded_port_id);
1101 /* Set link bonding mode */
1102 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1104 "Failed to set link bonding mode on port (%d) to (%d).",
1105 test_params->bonded_port_id, bonding_mode);
1107 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1108 "Failed to start bonded pmd eth device %d.",
1109 test_params->bonded_port_id);
1112 enable_bonded_slaves();
1118 test_adding_slave_after_bonded_device_started(void)
1122 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 0) !=
1126 /* Enabled slave devices */
1127 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1128 virtual_ethdev_simulate_link_status_interrupt(
1129 test_params->slave_port_ids[i], 1);
1132 if (rte_eth_bond_slave_add(test_params->bonded_port_id,
1133 test_params->slave_port_ids[test_params->bonded_slave_count]) !=
1135 printf("\t Failed to add slave to bonded port.\n");
1139 rte_eth_stats_reset(
1140 test_params->slave_port_ids[test_params->bonded_slave_count]);
1142 test_params->bonded_slave_count++;
1144 return remove_slaves_and_stop_bonded_device();
1148 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1149 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1150 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1152 uint16_t pktlen, generated_burst_size;
1156 initialize_eth_header(test_params->pkt_eth_hdr,
1157 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1160 initialize_eth_header(test_params->pkt_eth_hdr,
1161 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1165 if (toggle_udp_port)
1166 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1169 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1174 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1175 dst_addr_1, pktlen);
1177 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1178 dst_addr_0, pktlen);
1180 ip_hdr = test_params->pkt_ipv4_hdr;
1183 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1184 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1187 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1188 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1191 ip_hdr = test_params->pkt_ipv6_hdr;
1194 /* Generate burst of packets to transmit */
1195 generated_burst_size =
1196 generate_packet_burst(test_params->mbuf_pool,
1197 pkts_burst, test_params->pkt_eth_hdr,
1199 test_params->pkt_udp_hdr, burst_size,
1200 PACKET_BURST_GEN_PKT_LEN_128, 1);
1201 if (generated_burst_size != burst_size) {
1202 printf("Failed to generate packet burst");
1206 return generated_burst_size;
1209 /** Round Robin Mode Tests */
1212 test_roundrobin_tx_burst(void)
1214 int i, burst_size, nb_tx;
1215 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1216 struct rte_eth_stats port_stats;
1218 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 2, 1)
1222 burst_size = 20 * test_params->bonded_slave_count;
1224 if (burst_size > MAX_PKT_BURST) {
1225 printf("Burst size specified is greater than supported.\n");
1229 /* Generate test bursts of packets to transmit */
1230 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size)
1233 /* Send burst on bonded port */
1234 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1236 if (nb_tx != burst_size)
1239 /* Verify bonded port tx stats */
1240 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1241 if (port_stats.opackets != (uint64_t)burst_size) {
1242 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1243 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1248 /* Verify slave ports tx stats */
1249 for (i = 0; i < test_params->bonded_slave_count; i++) {
1250 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1251 if (port_stats.opackets !=
1252 (uint64_t)burst_size / test_params->bonded_slave_count) {
1253 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1254 test_params->bonded_port_id,
1255 (unsigned int)port_stats.opackets,
1256 burst_size / test_params->bonded_slave_count);
1261 /* Put all slaves down and try and transmit */
1262 for (i = 0; i < test_params->bonded_slave_count; i++) {
1263 virtual_ethdev_simulate_link_status_interrupt(
1264 test_params->slave_port_ids[i], 0);
1267 /* Send burst on bonded port */
1268 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1273 /* Clean up and remove slaves from bonded device */
1274 return remove_slaves_and_stop_bonded_device();
1278 test_roundrobin_rx_burst_on_single_slave(void)
1280 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1281 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1283 struct rte_eth_stats port_stats;
1285 int i, j, nb_rx, burst_size = 25;
1287 /* Initialize bonded device with 4 slaves in round robin mode */
1288 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1292 /* Generate test bursts of packets to transmit */
1293 if (generate_test_burst(gen_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1297 for (i = 0; i < test_params->bonded_slave_count; i++) {
1298 /* Add rx data to slave */
1299 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1300 &gen_pkt_burst[0], burst_size);
1302 /* Call rx burst on bonded device */
1303 /* Send burst on bonded port */
1304 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1306 if (nb_rx != burst_size) {
1307 printf("round-robin rx burst failed");
1311 /* Verify bonded device rx count */
1312 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1313 if (port_stats.ipackets != (uint64_t)burst_size) {
1314 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1315 test_params->bonded_port_id,
1316 (unsigned int)port_stats.ipackets, burst_size);
1321 /* Verify bonded slave devices rx count */
1322 /* Verify slave ports tx stats */
1323 for (j = 0; j < test_params->bonded_slave_count; j++) {
1324 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1327 if (port_stats.ipackets != (uint64_t)burst_size) {
1328 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1329 test_params->slave_port_ids[i],
1330 (unsigned int)port_stats.ipackets, burst_size);
1334 if (port_stats.ipackets != 0) {
1335 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1336 test_params->slave_port_ids[i],
1337 (unsigned int)port_stats.ipackets, 0);
1342 /* Reset bonded slaves stats */
1343 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1345 /* reset bonded device stats */
1346 rte_eth_stats_reset(test_params->bonded_port_id);
1350 for (i = 0; i < MAX_PKT_BURST; i++) {
1351 if (gen_pkt_burst[i] != NULL)
1352 rte_pktmbuf_free(gen_pkt_burst[i]);
1354 if (rx_pkt_burst[i] != NULL)
1355 rte_pktmbuf_free(rx_pkt_burst[i]);
1359 /* Clean up and remove slaves from bonded device */
1360 return remove_slaves_and_stop_bonded_device();
1363 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1366 test_roundrobin_rx_burst_on_multiple_slaves(void)
1368 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1370 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1371 struct rte_eth_stats port_stats;
1373 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1377 /* Initialize bonded device with 4 slaves in round robin mode */
1378 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1382 /* Generate test bursts of packets to transmit */
1383 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1384 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0,
1385 0) != burst_size[i])
1389 /* Add rx data to slaves */
1390 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1391 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1392 &gen_pkt_burst[i][0], burst_size[i]);
1395 /* Call rx burst on bonded device */
1396 /* Send burst on bonded port */
1397 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1399 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
1400 printf("round-robin rx burst failed (%d != %d)\n", nb_rx,
1401 burst_size[0] + burst_size[1] + burst_size[2]);
1405 /* Verify bonded device rx count */
1406 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1407 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
1409 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1410 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1411 burst_size[0] + burst_size[1] + burst_size[2]);
1416 /* Verify bonded slave devices rx counts */
1417 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1418 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
1419 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1420 test_params->slave_port_ids[0],
1421 (unsigned int)port_stats.ipackets, burst_size[0]);
1425 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1426 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
1427 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1428 test_params->slave_port_ids[1],
1429 (unsigned int)port_stats.ipackets, burst_size[1]);
1433 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1434 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
1435 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1436 test_params->slave_port_ids[2],
1437 (unsigned int)port_stats.ipackets, burst_size[2]);
1441 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1442 if (port_stats.ipackets != 0) {
1443 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1444 test_params->slave_port_ids[3],
1445 (unsigned int)port_stats.ipackets, 0);
1450 for (i = 0; i < MAX_PKT_BURST; i++) {
1451 if (rx_pkt_burst[i] != NULL)
1452 rte_pktmbuf_free(rx_pkt_burst[i]);
1455 /* Clean up and remove slaves from bonded device */
1456 return remove_slaves_and_stop_bonded_device();
1460 test_roundrobin_verify_mac_assignment(void)
1462 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1466 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1467 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1469 /* Initialize bonded device with 4 slaves in round robin mode */
1470 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1)
1474 /* Verify that all MACs are the same as first slave added to bonded dev */
1475 for (i = 0; i < test_params->bonded_slave_count; i++) {
1476 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1477 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1478 sizeof(read_mac_addr))) {
1479 printf("slave port (%d) mac address not set to that of primary port\n",
1480 test_params->slave_port_ids[i]);
1485 /* change primary and verify that MAC addresses haven't changed */
1486 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
1487 test_params->slave_port_ids[2]);
1489 printf("Failed to set bonded port (%d) primary port to (%d)\n",
1490 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1494 for (i = 0; i < test_params->bonded_slave_count; i++) {
1495 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1496 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1497 sizeof(read_mac_addr))) {
1498 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
1499 test_params->slave_port_ids[i]);
1504 /* stop / start bonded device and verify that primary MAC address is
1505 * propagate to bonded device and slaves */
1507 rte_eth_dev_stop(test_params->bonded_port_id);
1509 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
1512 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1513 if (memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr))) {
1514 printf("bonded port (%d) mac address not set to that of new primary port\n",
1515 test_params->slave_port_ids[i]);
1519 for (i = 0; i < test_params->bonded_slave_count; i++) {
1520 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1521 if (memcmp(&expected_mac_addr_2, &read_mac_addr,
1522 sizeof(read_mac_addr))) {
1523 printf("slave port (%d) mac address not set to that of new primary port\n",
1524 test_params->slave_port_ids[i]);
1529 /* Set explicit MAC address */
1530 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1531 (struct ether_addr *)bonded_mac) != 0) {
1535 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1536 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1537 printf("bonded port (%d) mac address not set to that of new primary port\n",
1538 test_params->slave_port_ids[i]);
1542 for (i = 0; i < test_params->bonded_slave_count; i++) {
1543 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1544 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1545 printf("slave port (%d) mac address not set to that of new primary port\n",
1546 test_params->slave_port_ids[i]);
1551 /* Clean up and remove slaves from bonded device */
1552 return remove_slaves_and_stop_bonded_device();
1556 test_roundrobin_verify_promiscuous_enable_disable(void)
1558 int i, promiscuous_en;
1560 /* Initialize bonded device with 4 slaves in round robin mode */
1561 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1565 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1567 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1568 if (promiscuous_en != 1) {
1569 printf("Port (%d) promiscuous mode not enabled\n",
1570 test_params->bonded_port_id);
1574 for (i = 0; i < test_params->bonded_slave_count; i++) {
1575 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1576 if (promiscuous_en != 1) {
1577 printf("slave port (%d) promiscuous mode not enabled\n",
1578 test_params->slave_port_ids[i]);
1583 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1585 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1586 if (promiscuous_en != 0) {
1587 printf("Port (%d) promiscuous mode not disabled\n",
1588 test_params->bonded_port_id);
1592 for (i = 0; i < test_params->bonded_slave_count; i++) {
1593 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1594 if (promiscuous_en != 0) {
1595 printf("slave port (%d) promiscuous mode not disabled\n",
1596 test_params->slave_port_ids[i]);
1601 /* Clean up and remove slaves from bonded device */
1602 return remove_slaves_and_stop_bonded_device();
1605 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1606 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1609 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1611 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1612 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1613 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1615 struct rte_eth_stats port_stats;
1616 uint8_t slaves[RTE_MAX_ETHPORTS];
1618 int i, burst_size, slave_count;
1620 /* NULL all pointers in array to simplify cleanup */
1621 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1623 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1624 * in round robin mode */
1625 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN,
1626 TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
1629 /* Verify Current Slaves Count /Active Slave Count is */
1630 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1632 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1633 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
1634 TEST_RR_LINK_STATUS_SLAVE_COUNT);
1638 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1639 slaves, RTE_MAX_ETHPORTS);
1640 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1641 printf("Number of active slaves (%d) is not as expected (%d).\n",
1642 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1646 /* Set 2 slaves eth_devs link status to down */
1647 virtual_ethdev_simulate_link_status_interrupt(
1648 test_params->slave_port_ids[1], 0);
1649 virtual_ethdev_simulate_link_status_interrupt(
1650 test_params->slave_port_ids[3], 0);
1652 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1653 slaves, RTE_MAX_ETHPORTS) !=
1654 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) {
1655 printf("Number of active slaves (%d) is not as expected (%d).\n",
1656 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1662 /* Verify that pkts are not sent on slaves with link status down:
1664 * 1. Generate test burst of traffic
1665 * 2. Transmit burst on bonded eth_dev
1666 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1667 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1669 if (generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1671 printf("generate_test_burst failed\n");
1675 rte_eth_stats_reset(test_params->bonded_port_id);
1677 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1678 burst_size) != burst_size) {
1679 printf("rte_eth_tx_burst failed\n");
1683 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1684 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1685 "Port (%d) opackets stats (%d) not expected (%d) value",
1686 test_params->bonded_port_id, (int)port_stats.opackets,
1689 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1690 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1691 "Port (%d) opackets stats (%d) not expected (%d) value",
1692 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1694 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1695 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1696 "Port (%d) opackets stats (%d) not expected (%d) value",
1697 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1699 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1700 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1701 "Port (%d) opackets stats (%d) not expected (%d) value",
1702 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1704 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1705 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1706 "Port (%d) opackets stats (%d) not expected (%d) value",
1707 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1709 /* Verify that pkts are not sent on slaves with link status down:
1711 * 1. Generate test bursts of traffic
1712 * 2. Add bursts on to virtual eth_devs
1713 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1714 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1715 * 4. Verify stats for bonded eth_dev
1716 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1718 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1719 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0)
1723 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1724 &gen_pkt_burst[i][0], burst_size);
1727 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1728 MAX_PKT_BURST) != burst_size + burst_size) {
1729 printf("rte_eth_rx_burst\n");
1733 /* Verify bonded device rx count */
1734 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1735 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
1736 printf("(%d) port_stats.ipackets not as expected\n",
1737 test_params->bonded_port_id);
1742 for (i = 0; i < MAX_PKT_BURST; i++) {
1743 if (rx_pkt_burst[i] != NULL)
1744 rte_pktmbuf_free(rx_pkt_burst[i]);
1746 if (gen_pkt_burst[1][i] != NULL)
1747 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1749 if (gen_pkt_burst[3][i] != NULL)
1750 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1753 /* Clean up and remove slaves from bonded device */
1754 return remove_slaves_and_stop_bonded_device();
1757 /** Active Backup Mode Tests */
1760 test_activebackup_tx_burst(void)
1762 int i, retval, pktlen, primary_port, burst_size, generated_burst_size, nb_tx;
1763 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1764 struct rte_eth_stats port_stats;
1766 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 1);
1768 printf("Failed to initialize_bonded_device_with_slaves.\n");
1772 initialize_eth_header(test_params->pkt_eth_hdr,
1773 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
1774 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1776 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1777 dst_addr_0, pktlen);
1779 burst_size = 20 * test_params->bonded_slave_count;
1781 if (burst_size > MAX_PKT_BURST) {
1782 printf("Burst size specified is greater than supported.\n");
1786 /* Generate a burst of packets to transmit */
1787 generated_burst_size =
1788 generate_packet_burst(test_params->mbuf_pool,
1789 pkts_burst, test_params->pkt_eth_hdr, 0,
1790 test_params->pkt_ipv4_hdr, 1,
1791 test_params->pkt_udp_hdr, burst_size,
1792 PACKET_BURST_GEN_PKT_LEN, 1);
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,
2445 test_params->pkt_ipv4_hdr, 1,
2446 test_params->pkt_udp_hdr, burst_size[0],
2447 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[0])
2450 initialize_eth_header(test_params->pkt_eth_hdr,
2451 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2453 /* Generate a burst 2 of packets to transmit */
2454 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2455 test_params->pkt_eth_hdr, 0,
2456 test_params->pkt_ipv4_hdr, 1,
2457 test_params->pkt_udp_hdr, burst_size[1],
2458 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[1])
2461 /* Send burst 1 on bonded port */
2462 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2463 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[i][0],
2464 burst_size[i]) != burst_size[i])
2467 /* Verify bonded port tx stats */
2468 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2469 if (port_stats.opackets != (uint64_t)(burst_size[0] + burst_size[1])) {
2470 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2471 test_params->bonded_port_id,
2472 (unsigned int)port_stats.opackets, burst_size[0] + burst_size[1]);
2477 /* Verify slave ports tx stats */
2478 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2479 if (port_stats.opackets != (uint64_t)burst_size[0]) {
2480 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2481 test_params->slave_port_ids[0],
2482 (unsigned int)port_stats.opackets, burst_size[0]);
2486 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2487 if (port_stats.opackets != (uint64_t)burst_size[1]) {
2488 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2489 test_params->slave_port_ids[1], (
2490 unsigned int)port_stats.opackets, burst_size[1]);
2494 /* Put all slaves down and try and transmit */
2495 for (i = 0; i < test_params->bonded_slave_count; i++) {
2497 virtual_ethdev_simulate_link_status_interrupt(
2498 test_params->slave_port_ids[i], 0);
2501 /* Send burst on bonded port */
2502 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[0][0],
2503 burst_size[0]) != 0)
2506 /* Clean up and remove slaves from bonded device */
2507 return remove_slaves_and_stop_bonded_device();
2511 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2512 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2515 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2517 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2518 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2520 struct rte_eth_stats port_stats;
2522 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1);
2524 printf("Failed to initialize_bonded_device_with_slaves.\n");
2528 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2529 BALANCE_XMIT_POLICY_LAYER23);
2531 printf("Failed to set balance xmit policy.\n");
2538 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2539 printf("Burst size specified is greater than supported.\n");
2543 /* Generate test bursts of packets to transmit */
2544 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4,
2545 0, 0, 0) != burst_size_1)
2548 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2549 toggle_mac_addr, toggle_ip_addr, 0) != burst_size_2)
2552 /* Send burst 1 on bonded port */
2553 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2555 if (nb_tx_1 != burst_size_1)
2558 /* Send burst 2 on bonded port */
2559 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2561 if (nb_tx_2 != burst_size_2)
2564 /* Verify bonded port tx stats */
2565 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2566 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2567 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2568 test_params->bonded_port_id,
2569 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2573 /* Verify slave ports tx stats */
2574 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2575 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2576 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2577 test_params->slave_port_ids[0],
2578 (unsigned int)port_stats.opackets, nb_tx_1);
2582 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2583 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2584 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2585 test_params->slave_port_ids[1],
2586 (unsigned int)port_stats.opackets, nb_tx_2);
2590 /* Put all slaves down and try and transmit */
2591 for (i = 0; i < test_params->bonded_slave_count; i++) {
2593 virtual_ethdev_simulate_link_status_interrupt(
2594 test_params->slave_port_ids[i], 0);
2597 /* Send burst on bonded port */
2598 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2603 /* Clean up and remove slaves from bonded device */
2604 return remove_slaves_and_stop_bonded_device();
2608 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2610 return balance_l23_tx_burst(0, 1, 1, 0);
2614 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2616 return balance_l23_tx_burst(1, 1, 0, 1);
2620 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2622 return balance_l23_tx_burst(0, 0, 0, 1);
2626 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2628 return balance_l23_tx_burst(1, 0, 0, 1);
2632 test_balance_l23_tx_burst_toggle_mac_addr(void)
2634 return balance_l23_tx_burst(0, 0, 1, 0);
2638 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2639 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2640 uint8_t toggle_udp_port)
2643 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2645 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2646 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2648 struct rte_eth_stats port_stats;
2650 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1);
2652 printf("Failed to initialize_bonded_device_with_slaves.\n");
2656 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2657 BALANCE_XMIT_POLICY_LAYER34);
2659 printf("Failed to set balance xmit policy.\n");
2666 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2667 printf("Burst size specified is greater than supported.\n");
2671 /* Generate test bursts of packets to transmit */
2672 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0,
2673 0, 0) != burst_size_1)
2676 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2677 toggle_mac_addr, toggle_ip_addr, toggle_udp_port) != burst_size_2)
2680 /* Send burst 1 on bonded port */
2681 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2683 if (nb_tx_1 != burst_size_1)
2686 /* Send burst 2 on bonded port */
2687 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2689 if (nb_tx_2 != burst_size_2)
2693 /* Verify bonded port tx stats */
2694 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2695 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2696 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2697 test_params->bonded_port_id,
2698 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2702 /* Verify slave ports tx stats */
2703 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2704 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2705 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2706 test_params->slave_port_ids[0],
2707 (unsigned int)port_stats.opackets, nb_tx_1);
2711 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2712 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2713 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2714 test_params->slave_port_ids[1],
2715 (unsigned int)port_stats.opackets, nb_tx_2);
2719 /* Put all slaves down and try and transmit */
2720 for (i = 0; i < test_params->bonded_slave_count; i++) {
2722 virtual_ethdev_simulate_link_status_interrupt(
2723 test_params->slave_port_ids[i], 0);
2726 /* Send burst on bonded port */
2727 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2732 /* Clean up and remove slaves from bonded device */
2733 return remove_slaves_and_stop_bonded_device();
2737 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2739 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2743 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2745 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2749 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2751 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2755 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2757 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2761 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2763 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2767 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2769 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2772 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
2775 test_balance_rx_burst(void)
2777 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2779 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2780 struct rte_eth_stats port_stats;
2782 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
2785 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
2787 /* Initialize bonded device with 4 slaves in round robin mode */
2788 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 3, 1)
2792 /* Generate test bursts of packets to transmit */
2793 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2794 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
2795 0, 0) != burst_size[i])
2798 /* Add rx data to slaves */
2799 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2800 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2801 &gen_pkt_burst[i][0], burst_size[i]);
2804 /* Call rx burst on bonded device */
2805 /* Send burst on bonded port */
2806 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2808 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
2809 printf("balance rx burst failed\n");
2813 /* Verify bonded device rx count */
2814 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2815 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
2817 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2818 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
2819 burst_size[0] + burst_size[1] + burst_size[2]);
2824 /* Verify bonded slave devices rx counts */
2825 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2826 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
2827 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2828 test_params->slave_port_ids[0],
2829 (unsigned int)port_stats.ipackets, burst_size[0]);
2833 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2834 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
2835 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2836 test_params->slave_port_ids[1],
2837 (unsigned int)port_stats.ipackets, burst_size[1]);
2841 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2842 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
2843 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2844 test_params->slave_port_ids[2],
2845 (unsigned int)port_stats.ipackets, burst_size[2]);
2849 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2850 if (port_stats.ipackets != 0) {
2851 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2852 test_params->slave_port_ids[3],
2853 (unsigned int)port_stats.ipackets, 0);
2858 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2859 for (j = 0; j < MAX_PKT_BURST; j++) {
2860 if (gen_pkt_burst[i][j] != NULL) {
2861 rte_pktmbuf_free(gen_pkt_burst[i][j]);
2862 gen_pkt_burst[i][j] = NULL;
2867 /* Clean up and remove slaves from bonded device */
2868 return remove_slaves_and_stop_bonded_device();
2872 test_balance_verify_promiscuous_enable_disable(void)
2874 int i, promiscuous_en;
2876 /* Initialize bonded device with 4 slaves in round robin mode */
2877 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 0)
2880 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2882 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2883 if (promiscuous_en != 1) {
2884 printf("Port (%d) promiscuous mode not enabled\n",
2885 test_params->bonded_port_id);
2889 for (i = 0; i < test_params->bonded_slave_count; i++) {
2890 promiscuous_en = rte_eth_promiscuous_get(
2891 test_params->slave_port_ids[i]);
2892 if (promiscuous_en != 1) {
2893 printf("slave port (%d) promiscuous mode not enabled\n",
2894 test_params->slave_port_ids[i]);
2899 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2901 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2902 if (promiscuous_en != 0) {
2903 printf("Port (%d) promiscuous mode not disabled\n",
2904 test_params->bonded_port_id);
2908 for (i = 0; i < test_params->bonded_slave_count; i++) {
2909 promiscuous_en = rte_eth_promiscuous_get(
2910 test_params->slave_port_ids[i]);
2911 if (promiscuous_en != 0) {
2912 printf("slave port (%d) promiscuous mode not disabled\n",
2913 test_params->slave_port_ids[i]);
2918 /* Clean up and remove slaves from bonded device */
2919 return remove_slaves_and_stop_bonded_device();
2923 test_balance_verify_mac_assignment(void)
2925 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2927 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2928 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2930 /* Initialize bonded device with 2 slaves in active backup mode */
2931 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1) != 0)
2934 /* Verify that bonded MACs is that of first slave and that the other slave
2935 * MAC hasn't been changed */
2936 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2937 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2938 printf("bonded port (%d) mac address not set to that of primary port\n",
2939 test_params->bonded_port_id);
2943 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2944 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2945 printf("slave port (%d) mac address not set to that of primary port\n",
2946 test_params->slave_port_ids[0]);
2950 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2951 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2952 printf("slave port (%d) mac address not set to that of primary port\n",
2953 test_params->slave_port_ids[1]);
2957 /* change primary and verify that MAC addresses haven't changed */
2958 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2959 test_params->slave_port_ids[1]) != 0) {
2960 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2961 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2965 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2966 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2967 printf("bonded port (%d) mac address not set to that of primary port\n",
2968 test_params->bonded_port_id);
2972 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2973 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2974 printf("slave port (%d) mac address not set to that of primary port\n",
2975 test_params->slave_port_ids[0]);
2979 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2980 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2981 printf("slave port (%d) mac address not set to that of primary port\n",
2982 test_params->slave_port_ids[1]);
2986 /* stop / start bonded device and verify that primary MAC address is
2987 * propagated to bonded device and slaves */
2989 rte_eth_dev_stop(test_params->bonded_port_id);
2991 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2994 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2995 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2996 printf("bonded port (%d) mac address not set to that of primary port\n",
2997 test_params->bonded_port_id);
3001 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3002 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3003 printf("slave port (%d) mac address not set to that of primary port\n",
3004 test_params->slave_port_ids[0]);
3008 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3009 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3010 printf("slave port (%d) mac address not set to that of primary port\n",
3011 test_params->slave_port_ids[1]);
3015 /* Set explicit MAC address */
3016 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3017 (struct ether_addr *)bonded_mac) != 0)
3020 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3021 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3022 printf("bonded port (%d) mac address not set to that of bonded port\n",
3023 test_params->bonded_port_id);
3027 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3028 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3029 printf("slave port (%d) mac address not as expected\n",
3030 test_params->slave_port_ids[0]);
3034 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3035 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3036 printf("slave port (%d) mac address not set to that of bonded port\n",
3037 test_params->slave_port_ids[1]);
3041 /* Clean up and remove slaves from bonded device */
3042 return remove_slaves_and_stop_bonded_device();
3045 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3048 test_balance_verify_slave_link_status_change_behaviour(void)
3050 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3051 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3052 struct rte_eth_stats port_stats;
3054 uint8_t slaves[RTE_MAX_ETHPORTS];
3056 int i, j, burst_size, slave_count;
3058 memset(pkt_burst, 0, sizeof(pkt_burst));
3060 /* Initialize bonded device with 4 slaves in round robin mode */
3061 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
3062 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
3065 if (rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
3066 BALANCE_XMIT_POLICY_LAYER2)) {
3067 printf("Failed to set balance xmit policy.\n");
3071 /* Verify Current Slaves Count /Active Slave Count is */
3072 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3074 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3075 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
3076 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3080 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3081 slaves, RTE_MAX_ETHPORTS);
3082 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3083 printf("Number of active slaves (%d) is not as expected (%d).\n",
3084 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3088 /* Set 2 slaves link status to down */
3089 virtual_ethdev_simulate_link_status_interrupt(
3090 test_params->slave_port_ids[1], 0);
3091 virtual_ethdev_simulate_link_status_interrupt(
3092 test_params->slave_port_ids[3], 0);
3094 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3095 slaves, RTE_MAX_ETHPORTS) != 2) {
3096 printf("Number of active slaves (%d) is not as expected (%d).\n",
3101 /* Send to sets of packet burst and verify that they are balanced across
3105 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
3107 printf("generate_test_burst failed\n");
3111 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3113 printf("generate_test_burst failed\n");
3117 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3118 burst_size) != burst_size) {
3119 printf("rte_eth_tx_burst failed\n");
3123 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3124 burst_size) != burst_size) {
3125 printf("rte_eth_tx_burst failed\n");
3129 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3130 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3131 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3132 test_params->bonded_port_id, (int)port_stats.opackets,
3133 burst_size + burst_size);
3137 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3138 if (port_stats.opackets != (uint64_t)burst_size) {
3139 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3140 test_params->slave_port_ids[0], (int)port_stats.opackets,
3145 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3146 if (port_stats.opackets != (uint64_t)burst_size) {
3147 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3148 test_params->slave_port_ids[2], (int)port_stats.opackets,
3153 /* verify that all packets get send on primary slave when no other slaves
3155 virtual_ethdev_simulate_link_status_interrupt(
3156 test_params->slave_port_ids[2], 0);
3158 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
3159 RTE_MAX_ETHPORTS) != 1) {
3160 printf("Number of active slaves (%d) is not as expected (%d).\n",
3165 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3167 printf("generate_test_burst failed\n");
3171 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3172 burst_size) != burst_size) {
3173 printf("rte_eth_tx_burst failed\n");
3177 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3178 if (port_stats.opackets != (uint64_t)(burst_size + burst_size +
3180 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3181 test_params->bonded_port_id, (int)port_stats.opackets,
3182 burst_size + burst_size + burst_size);
3186 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3187 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3188 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3189 test_params->slave_port_ids[0], (int)port_stats.opackets,
3190 burst_size + burst_size);
3195 virtual_ethdev_simulate_link_status_interrupt(
3196 test_params->slave_port_ids[0], 0);
3197 virtual_ethdev_simulate_link_status_interrupt(
3198 test_params->slave_port_ids[1], 1);
3199 virtual_ethdev_simulate_link_status_interrupt(
3200 test_params->slave_port_ids[2], 1);
3201 virtual_ethdev_simulate_link_status_interrupt(
3202 test_params->slave_port_ids[3], 1);
3204 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3205 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
3209 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3210 &pkt_burst[i][0], burst_size);
3215 /* Verify that pkts are not received on slaves with link status down */
3217 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3220 /* Verify bonded device rx count */
3221 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3222 if (port_stats.ipackets != (uint64_t)(burst_size * 3)) {
3223 printf("(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3224 test_params->bonded_port_id, (int)port_stats.ipackets,
3229 /* free mbufs allocate for rx testing */
3230 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3231 for (j = 0; j < MAX_PKT_BURST; j++) {
3232 if (pkt_burst[i][j] != NULL) {
3233 rte_pktmbuf_free(pkt_burst[i][j]);
3234 pkt_burst[i][j] = NULL;
3239 /* Clean up and remove slaves from bonded device */
3240 return remove_slaves_and_stop_bonded_device();
3243 #ifdef RTE_MBUF_REFCNT
3244 /** Broadcast Mode Tests */
3247 test_broadcast_tx_burst(void)
3249 int i, pktlen, retval, burst_size, generated_burst_size, nb_tx;
3250 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3252 struct rte_eth_stats port_stats;
3254 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 2, 1);
3256 printf("Failed to initialize_bonded_device_with_slaves.\n");
3260 initialize_eth_header(test_params->pkt_eth_hdr,
3261 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3263 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3265 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3266 dst_addr_0, pktlen);
3268 burst_size = 20 * test_params->bonded_slave_count;
3270 if (burst_size > MAX_PKT_BURST) {
3271 printf("Burst size specified is greater than supported.\n");
3275 /* Generate a burst of packets to transmit */
3276 generated_burst_size =
3277 generate_packet_burst(test_params->mbuf_pool,
3278 pkts_burst, test_params->pkt_eth_hdr, 0,
3279 test_params->pkt_ipv4_hdr, 1,
3280 test_params->pkt_udp_hdr, burst_size,
3281 PACKET_BURST_GEN_PKT_LEN, 1);
3282 if (generated_burst_size != burst_size)
3285 /* Send burst on bonded port */
3286 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3288 if (nb_tx != burst_size * test_params->bonded_slave_count) {
3289 printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
3290 test_params->bonded_port_id,
3295 /* Verify bonded port tx stats */
3296 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3297 if (port_stats.opackets != (uint64_t)burst_size *
3298 test_params->bonded_slave_count) {
3299 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3300 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3304 /* Verify slave ports tx stats */
3305 for (i = 0; i < test_params->bonded_slave_count; i++) {
3306 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3307 if (port_stats.opackets != (uint64_t)burst_size) {
3308 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3309 test_params->bonded_port_id,
3310 (unsigned int)port_stats.opackets, burst_size);
3314 /* Put all slaves down and try and transmit */
3315 for (i = 0; i < test_params->bonded_slave_count; i++) {
3317 virtual_ethdev_simulate_link_status_interrupt(
3318 test_params->slave_port_ids[i], 0);
3321 /* Send burst on bonded port */
3322 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3327 /* Clean up and remove slaves from bonded device */
3328 return remove_slaves_and_stop_bonded_device();
3331 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3334 test_broadcast_rx_burst(void)
3336 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3338 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3339 struct rte_eth_stats port_stats;
3341 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3344 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3346 /* Initialize bonded device with 4 slaves in round robin mode */
3347 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 3, 1) != 0)
3351 /* Generate test bursts of packets to transmit */
3352 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3353 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0,
3354 0) != burst_size[i])
3358 /* Add rx data to slave 0 */
3359 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3360 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3361 &gen_pkt_burst[i][0], burst_size[i]);
3365 /* Call rx burst on bonded device */
3366 /* Send burst on bonded port */
3367 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3369 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3370 printf("round-robin rx burst failed");
3374 /* Verify bonded device rx count */
3375 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3376 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3378 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3379 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3380 burst_size[0] + burst_size[1] + burst_size[2]);
3385 /* Verify bonded slave devices rx counts */
3386 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3387 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3388 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3389 test_params->slave_port_ids[0],
3390 (unsigned int)port_stats.ipackets, burst_size[0]);
3394 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3395 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3396 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3397 test_params->slave_port_ids[1],
3398 (unsigned int)port_stats.ipackets, burst_size[1]);
3402 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3403 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3404 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3405 test_params->slave_port_ids[2],
3406 (unsigned int)port_stats.ipackets,
3411 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3412 if (port_stats.ipackets != 0) {
3413 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3414 test_params->slave_port_ids[3],
3415 (unsigned int)port_stats.ipackets, 0);
3419 /* free mbufs allocate for rx testing */
3420 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3421 for (j = 0; j < MAX_PKT_BURST; j++) {
3422 if (gen_pkt_burst[i][j] != NULL) {
3423 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3424 gen_pkt_burst[i][j] = NULL;
3429 /* Clean up and remove slaves from bonded device */
3430 return remove_slaves_and_stop_bonded_device();
3434 test_broadcast_verify_promiscuous_enable_disable(void)
3436 int i, promiscuous_en;
3438 /* Initialize bonded device with 4 slaves in round robin mode */
3439 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 0)
3442 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3444 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3445 if (promiscuous_en != 1) {
3446 printf("Port (%d) promiscuous mode not enabled\n",
3447 test_params->bonded_port_id);
3451 for (i = 0; i < test_params->bonded_slave_count; i++) {
3452 promiscuous_en = rte_eth_promiscuous_get(
3453 test_params->slave_port_ids[i]);
3454 if (promiscuous_en != 1) {
3455 printf("slave port (%d) promiscuous mode not enabled\n",
3456 test_params->slave_port_ids[i]);
3461 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3463 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3464 if (promiscuous_en != 0) {
3465 printf("Port (%d) promiscuous mode not disabled\n",
3466 test_params->bonded_port_id);
3470 for (i = 0; i < test_params->bonded_slave_count; i++) {
3471 promiscuous_en = rte_eth_promiscuous_get(
3472 test_params->slave_port_ids[i]);
3473 if (promiscuous_en != 0) {
3474 printf("slave port (%d) promiscuous mode not disabled\n",
3475 test_params->slave_port_ids[i]);
3480 /* Clean up and remove slaves from bonded device */
3481 return remove_slaves_and_stop_bonded_device();
3485 test_broadcast_verify_mac_assignment(void)
3487 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3491 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3492 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3494 /* Initialize bonded device with 4 slaves in round robin mode */
3495 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 4, 1) != 0)
3498 /* Verify that all MACs are the same as first slave added to bonded
3500 for (i = 0; i < test_params->bonded_slave_count; i++) {
3501 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3502 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3503 sizeof(read_mac_addr))) {
3504 printf("slave port (%d) mac address not set to that of primary port\n",
3505 test_params->slave_port_ids[i]);
3510 /* change primary and verify that MAC addresses haven't changed */
3511 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
3512 test_params->slave_port_ids[2]);
3514 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3515 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3519 for (i = 0; i < test_params->bonded_slave_count; i++) {
3520 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3521 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3522 sizeof(read_mac_addr))) {
3523 printf("slave port (%d) mac address has changed to that of primary"
3524 "port without stop/start toggle of bonded device\n",
3525 test_params->slave_port_ids[i]);
3530 /* stop / start bonded device and verify that primary MAC address is
3531 * propagated to bonded device and slaves */
3533 rte_eth_dev_stop(test_params->bonded_port_id);
3535 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3538 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3539 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3540 printf("bonded port (%d) mac address not set to that of new primary"
3541 " port\n", test_params->slave_port_ids[i]);
3545 for (i = 0; i < test_params->bonded_slave_count; i++) {
3546 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3547 if (memcmp(&expected_mac_addr_1, &read_mac_addr,
3548 sizeof(read_mac_addr))) {
3549 printf("slave port (%d) mac address not set to that of new primary"
3550 "port\n", test_params->slave_port_ids[i]);
3555 /* Set explicit MAC address */
3556 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3557 (struct ether_addr *)bonded_mac) != 0)
3560 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3561 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3562 printf("bonded port (%d) mac address not set to that of new primary port\n",
3563 test_params->slave_port_ids[i]);
3567 for (i = 0; i < test_params->bonded_slave_count; i++) {
3568 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3569 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3570 printf("slave port (%d) mac address not set to that of new primary port\n",
3571 test_params->slave_port_ids[i]);
3576 /* Clean up and remove slaves from bonded device */
3577 return remove_slaves_and_stop_bonded_device();
3580 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3582 test_broadcast_verify_slave_link_status_change_behaviour(void)
3584 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3585 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3586 struct rte_eth_stats port_stats;
3588 uint8_t slaves[RTE_MAX_ETHPORTS];
3590 int i, j, burst_size, slave_count;
3592 memset(pkt_burst, 0, sizeof(pkt_burst));
3594 /* Initialize bonded device with 4 slaves in round robin mode */
3595 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST,
3596 BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
3599 /* Verify Current Slaves Count /Active Slave Count is */
3600 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3602 if (slave_count != 4) {
3603 printf("Number of slaves (%d) is not as expected (%d).\n",
3608 slave_count = rte_eth_bond_active_slaves_get(
3609 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
3610 if (slave_count != 4) {
3611 printf("Number of active slaves (%d) is not as expected (%d).\n",
3616 /* Set 2 slaves link status to down */
3617 virtual_ethdev_simulate_link_status_interrupt(
3618 test_params->slave_port_ids[1], 0);
3619 virtual_ethdev_simulate_link_status_interrupt(
3620 test_params->slave_port_ids[3], 0);
3622 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3623 slaves, RTE_MAX_ETHPORTS);
3624 if (slave_count != 2) {
3625 printf("Number of active slaves (%d) is not as expected (%d).\n",
3630 for (i = 0; i < test_params->bonded_slave_count; i++)
3631 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3633 /* Verify that pkts are not sent on slaves with link status down */
3636 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0) !=
3638 printf("generate_test_burst failed\n");
3642 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3643 burst_size) != (burst_size * slave_count)) {
3644 printf("rte_eth_tx_burst failed\n");
3648 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3649 if (port_stats.opackets != (uint64_t)(burst_size * slave_count)) {
3650 printf("(%d) port_stats.opackets (%d) not as expected (%d)\n",
3651 test_params->bonded_port_id, (int)port_stats.opackets,
3652 burst_size * slave_count);
3656 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3657 if (port_stats.opackets != (uint64_t)burst_size) {
3658 printf("(%d) port_stats.opackets not as expected\n",
3659 test_params->slave_port_ids[0]);
3663 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3664 if (port_stats.opackets != 0) {
3665 printf("(%d) port_stats.opackets not as expected\n",
3666 test_params->slave_port_ids[1]);
3670 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3671 if (port_stats.opackets != (uint64_t)burst_size) {
3672 printf("(%d) port_stats.opackets not as expected\n",
3673 test_params->slave_port_ids[2]);
3677 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3678 if (port_stats.opackets != 0) {
3679 printf("(%d) port_stats.opackets not as expected\n",
3680 test_params->slave_port_ids[3]);
3684 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3685 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0) !=
3690 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3691 &pkt_burst[i][0], burst_size);
3694 /* Verify that pkts are not received on slaves with link status down */
3696 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3698 burst_size + burst_size) {
3699 printf("rte_eth_rx_burst\n");
3703 /* Verify bonded device rx count */
3704 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3705 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
3706 printf("(%d) port_stats.ipackets not as expected\n",
3707 test_params->bonded_port_id);
3711 /* free mbufs allocate for rx testing */
3712 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3713 for (j = 0; j < MAX_PKT_BURST; j++) {
3714 if (pkt_burst[i][j] != NULL) {
3715 rte_pktmbuf_free(pkt_burst[i][j]);
3716 pkt_burst[i][j] = NULL;
3721 /* Clean up and remove slaves from bonded device */
3722 return remove_slaves_and_stop_bonded_device();
3727 test_reconfigure_bonded_device(void)
3729 test_params->nb_rx_q = 4;
3730 test_params->nb_tx_q = 4;
3732 if (configure_ethdev(test_params->bonded_port_id, 0) != 0) {
3733 printf("failed to reconfigure bonded device");
3738 test_params->nb_rx_q = 2;
3739 test_params->nb_tx_q = 2;
3741 if (configure_ethdev(test_params->bonded_port_id, 0) != 0) {
3742 printf("failed to reconfigure bonded device with less rx/tx queues");
3751 test_close_bonded_device(void)
3753 rte_eth_dev_close(test_params->bonded_port_id);
3758 testsuite_teardown(void)
3760 if (test_params->pkt_eth_hdr != NULL) {
3761 free(test_params->pkt_eth_hdr);
3762 test_params->pkt_eth_hdr = NULL;
3765 /* Clean up and remove slaves from bonded device */
3766 return remove_slaves_and_stop_bonded_device();
3770 static struct unit_test_suite link_bonding_test_suite = {
3771 .suite_name = "Link Bonding Unit Test Suite",
3772 .setup = test_setup,
3773 .teardown = testsuite_teardown,
3774 .unit_test_cases = {
3775 TEST_CASE(test_create_bonded_device),
3776 TEST_CASE(test_create_bonded_device_with_invalid_params),
3777 TEST_CASE(test_add_slave_to_bonded_device),
3778 TEST_CASE(test_add_slave_to_invalid_bonded_device),
3779 TEST_CASE(test_remove_slave_from_bonded_device),
3780 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
3781 TEST_CASE(test_get_slaves_from_bonded_device),
3782 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
3783 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
3784 TEST_CASE(test_start_bonded_device),
3785 TEST_CASE(test_stop_bonded_device),
3786 TEST_CASE(test_set_bonding_mode),
3787 TEST_CASE(test_set_primary_slave),
3788 TEST_CASE(test_set_explicit_bonded_mac),
3789 TEST_CASE(test_adding_slave_after_bonded_device_started),
3790 TEST_CASE(test_roundrobin_tx_burst),
3791 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
3792 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
3793 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
3794 TEST_CASE(test_roundrobin_verify_mac_assignment),
3795 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
3796 TEST_CASE(test_activebackup_tx_burst),
3797 TEST_CASE(test_activebackup_rx_burst),
3798 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
3799 TEST_CASE(test_activebackup_verify_mac_assignment),
3800 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
3801 TEST_CASE(test_balance_xmit_policy_configuration),
3802 TEST_CASE(test_balance_l2_tx_burst),
3803 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
3804 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
3805 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
3806 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
3807 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
3808 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
3809 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
3810 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
3811 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
3812 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
3813 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
3814 TEST_CASE(test_balance_rx_burst),
3815 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
3816 TEST_CASE(test_balance_verify_mac_assignment),
3817 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
3818 #ifdef RTE_MBUF_REFCNT
3819 TEST_CASE(test_broadcast_tx_burst),
3820 TEST_CASE(test_broadcast_rx_burst),
3821 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
3822 TEST_CASE(test_broadcast_verify_mac_assignment),
3823 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
3825 TEST_CASE(test_reconfigure_bonded_device),
3826 TEST_CASE(test_close_bonded_device),
3828 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
3834 test_link_bonding(void)
3836 return unit_test_suite_runner(&link_bonding_test_suite);
3839 static struct test_command link_bonding_cmd = {
3840 .command = "link_bonding_autotest",
3841 .callback = test_link_bonding,
3843 REGISTER_TEST_COMMAND(link_bonding_cmd);