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 BONDING_MODE_BROADCAST };
793 /* Test supported link bonding modes */
794 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
795 /* Invalid port ID */
796 retval = rte_eth_bond_mode_set(INVALID_PORT_ID, bonding_modes[i]);
798 printf("Expected call to failed as invalid port (%d) specified.\n",
803 /* Non bonded device */
804 retval = rte_eth_bond_mode_set(test_params->slave_port_ids[0],
807 printf("Expected call to failed as invalid port (%d) specified.\n",
808 test_params->slave_port_ids[0]);
812 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
815 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
816 test_params->bonded_port_id, bonding_modes[i]);
820 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
821 if (bonding_mode != bonding_modes[i]) {
822 printf("Link bonding mode (%d) of port (%d) is not expected value (%d).\n",
823 bonding_mode, test_params->bonded_port_id,
829 /* Invalid port ID */
830 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
831 if (bonding_mode >= 0) {
832 printf("Expected call to failed as invalid port (%d) specified.\n",
838 /* Non bonded device */
839 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
840 if (bonding_mode >= 0) {
841 printf("Expected call to failed as invalid port (%d) specified.\n",
842 test_params->slave_port_ids[0]);
848 return remove_slaves_and_stop_bonded_device();
852 test_set_primary_slave(void)
855 struct ether_addr read_mac_addr;
856 struct ether_addr *expected_mac_addr;
858 /* Add 4 slaves to bonded device */
859 for (i = test_params->bonded_slave_count; i < 4; i++) {
860 retval = test_add_slave_to_bonded_device();
862 printf("Failed to add slave to bonded device.\n");
866 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
867 BONDING_MODE_ROUND_ROBIN);
869 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
870 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
874 /* Invalid port ID */
875 retval = rte_eth_bond_primary_set(INVALID_PORT_ID,
876 test_params->slave_port_ids[i]);
878 printf("Expected call to failed as invalid port specified.\n");
882 /* Set slave as primary
883 * Verify slave it is now primary slave
884 * Verify that MAC address of bonded device is that of primary slave
885 * Verify that MAC address of all bonded slaves are that of primary slave
887 for (i = 0; i < 4; i++) {
889 /* Non bonded device */
890 retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
891 test_params->slave_port_ids[i]);
893 printf("Expected call to failed as invalid port specified.\n");
897 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
898 test_params->slave_port_ids[i]);
900 printf("Failed to set bonded port (%d) primary port to (%d)\n",
901 test_params->bonded_port_id,
902 test_params->slave_port_ids[i]);
906 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
908 printf("Failed to read primary port from bonded port (%d)\n",
909 test_params->bonded_port_id);
911 } else if (retval != test_params->slave_port_ids[i]) {
912 printf("Bonded port (%d) primary port (%d) not expected value (%d)\n",
913 test_params->bonded_port_id, retval,
914 test_params->slave_port_ids[i]);
918 /* stop/start bonded eth dev to apply new MAC */
919 rte_eth_dev_stop(test_params->bonded_port_id);
920 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
923 expected_mac_addr = (struct ether_addr *)&slave_mac;
924 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
925 test_params->slave_port_ids[i];
927 /* Check primary slave MAC */
928 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
929 if (memcmp(expected_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
930 printf("bonded port mac address not set to that of primary port\n");
934 /* Check bonded MAC */
935 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
936 if (memcmp(&read_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
937 printf("bonded port mac address not set to that of primary port\n");
941 /* Check other slaves MACs */
942 for (j = 0; j < 4; j++) {
944 rte_eth_macaddr_get(test_params->slave_port_ids[j],
946 if (memcmp(expected_mac_addr, &read_mac_addr,
947 sizeof(read_mac_addr))) {
948 printf("slave port mac address not set to that of primary port\n");
956 /* Test with none existent port */
957 retval = rte_eth_bond_primary_get(test_params->bonded_port_id + 10);
959 printf("read primary port from expectedly\n");
963 /* Test with slave port */
964 retval = rte_eth_bond_primary_get(test_params->slave_port_ids[0]);
966 printf("read primary port from expectedly\n");
970 if (remove_slaves_and_stop_bonded_device() != 0)
974 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
976 printf("read primary port from expectedly\n");
984 test_set_explicit_bonded_mac(void)
987 struct ether_addr read_mac_addr;
988 struct ether_addr *mac_addr;
990 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
992 mac_addr = (struct ether_addr *)explicit_bonded_mac;
994 /* Invalid port ID */
995 retval = rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr);
997 printf("Expected call to failed as invalid port specified.\n");
1001 /* Non bonded device */
1002 retval = rte_eth_bond_mac_address_set(test_params->slave_port_ids[0],
1005 printf("Expected call to failed as invalid port specified.\n");
1009 /* NULL MAC address */
1010 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id, NULL);
1012 printf("Expected call to failed as NULL MAC specified\n");
1016 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1019 printf("Failed to set MAC address on bonded port (%d)\n",
1020 test_params->bonded_port_id);
1024 /* Add 4 slaves to bonded device */
1025 for (i = test_params->bonded_slave_count; i < 4; i++) {
1026 retval = test_add_slave_to_bonded_device();
1028 printf("Failed to add slave to bonded device.\n");
1033 /* Check bonded MAC */
1034 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1035 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1036 printf("bonded port mac address not set to that of primary port\n");
1040 /* Check other slaves MACs */
1041 for (i = 0; i < 4; i++) {
1042 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1043 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1044 printf("slave port mac address not set to that of primary port\n");
1049 /* test resetting mac address on bonded device */
1050 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1051 printf("Failed to reset MAC address on bonded port (%d)\n",
1052 test_params->bonded_port_id);
1057 if (rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]) == 0) {
1058 printf("Reset MAC address on bonded port (%d) unexpectedly\n",
1059 test_params->slave_port_ids[1]);
1064 /* test resetting mac address on bonded device with no slaves */
1066 if (remove_slaves_and_stop_bonded_device() != 0)
1069 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1070 printf("Failed to reset MAC address on bonded port (%d)\n",
1071 test_params->bonded_port_id);
1081 initialize_bonded_device_with_slaves(uint8_t bonding_mode,
1082 uint8_t number_of_slaves, uint8_t enable_slave)
1084 /* configure bonded device */
1085 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0),
1086 "Failed to configure bonding port (%d) in mode %d "
1087 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1090 while (number_of_slaves > test_params->bonded_slave_count) {
1091 /* Add slaves to bonded device */
1092 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1093 "Failed to add slave (%d to bonding port (%d).",
1094 test_params->bonded_slave_count - 1,
1095 test_params->bonded_port_id);
1098 /* Set link bonding mode */
1099 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1101 "Failed to set link bonding mode on port (%d) to (%d).",
1102 test_params->bonded_port_id, bonding_mode);
1104 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1105 "Failed to start bonded pmd eth device %d.",
1106 test_params->bonded_port_id);
1109 enable_bonded_slaves();
1115 test_adding_slave_after_bonded_device_started(void)
1119 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 0) !=
1123 /* Enabled slave devices */
1124 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1125 virtual_ethdev_simulate_link_status_interrupt(
1126 test_params->slave_port_ids[i], 1);
1129 if (rte_eth_bond_slave_add(test_params->bonded_port_id,
1130 test_params->slave_port_ids[test_params->bonded_slave_count]) !=
1132 printf("\t Failed to add slave to bonded port.\n");
1136 rte_eth_stats_reset(
1137 test_params->slave_port_ids[test_params->bonded_slave_count]);
1139 test_params->bonded_slave_count++;
1141 return remove_slaves_and_stop_bonded_device();
1145 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1146 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1147 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1149 uint16_t pktlen, generated_burst_size;
1153 initialize_eth_header(test_params->pkt_eth_hdr,
1154 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1157 initialize_eth_header(test_params->pkt_eth_hdr,
1158 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1162 if (toggle_udp_port)
1163 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1166 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1171 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1172 dst_addr_1, pktlen);
1174 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1175 dst_addr_0, pktlen);
1177 ip_hdr = test_params->pkt_ipv4_hdr;
1180 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1181 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1184 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1185 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1188 ip_hdr = test_params->pkt_ipv6_hdr;
1191 /* Generate burst of packets to transmit */
1192 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1193 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1194 test_params->pkt_udp_hdr, burst_size);
1195 if (generated_burst_size != burst_size) {
1196 printf("Failed to generate packet burst");
1200 return generated_burst_size;
1203 /** Round Robin Mode Tests */
1206 test_roundrobin_tx_burst(void)
1208 int i, burst_size, nb_tx;
1209 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1210 struct rte_eth_stats port_stats;
1212 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 2, 1)
1216 burst_size = 20 * test_params->bonded_slave_count;
1218 if (burst_size > MAX_PKT_BURST) {
1219 printf("Burst size specified is greater than supported.\n");
1223 /* Generate test bursts of packets to transmit */
1224 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size)
1227 /* Send burst on bonded port */
1228 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1230 if (nb_tx != burst_size)
1233 /* Verify bonded port tx stats */
1234 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1235 if (port_stats.opackets != (uint64_t)burst_size) {
1236 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1237 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1242 /* Verify slave ports tx stats */
1243 for (i = 0; i < test_params->bonded_slave_count; i++) {
1244 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1245 if (port_stats.opackets !=
1246 (uint64_t)burst_size / test_params->bonded_slave_count) {
1247 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1248 test_params->bonded_port_id,
1249 (unsigned int)port_stats.opackets,
1250 burst_size / test_params->bonded_slave_count);
1255 /* Put all slaves down and try and transmit */
1256 for (i = 0; i < test_params->bonded_slave_count; i++) {
1257 virtual_ethdev_simulate_link_status_interrupt(
1258 test_params->slave_port_ids[i], 0);
1261 /* Send burst on bonded port */
1262 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1267 /* Clean up and remove slaves from bonded device */
1268 return remove_slaves_and_stop_bonded_device();
1272 test_roundrobin_rx_burst_on_single_slave(void)
1274 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1275 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1277 struct rte_eth_stats port_stats;
1279 int i, j, nb_rx, burst_size = 25;
1281 /* Initialize bonded device with 4 slaves in round robin mode */
1282 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1286 /* Generate test bursts of packets to transmit */
1287 if (generate_test_burst(gen_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1291 for (i = 0; i < test_params->bonded_slave_count; i++) {
1292 /* Add rx data to slave */
1293 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1294 &gen_pkt_burst[0], burst_size);
1296 /* Call rx burst on bonded device */
1297 /* Send burst on bonded port */
1298 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1300 if (nb_rx != burst_size) {
1301 printf("round-robin rx burst failed");
1305 /* Verify bonded device rx count */
1306 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1307 if (port_stats.ipackets != (uint64_t)burst_size) {
1308 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1309 test_params->bonded_port_id,
1310 (unsigned int)port_stats.ipackets, burst_size);
1315 /* Verify bonded slave devices rx count */
1316 /* Verify slave ports tx stats */
1317 for (j = 0; j < test_params->bonded_slave_count; j++) {
1318 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1321 if (port_stats.ipackets != (uint64_t)burst_size) {
1322 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1323 test_params->slave_port_ids[i],
1324 (unsigned int)port_stats.ipackets, burst_size);
1328 if (port_stats.ipackets != 0) {
1329 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1330 test_params->slave_port_ids[i],
1331 (unsigned int)port_stats.ipackets, 0);
1336 /* Reset bonded slaves stats */
1337 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1339 /* reset bonded device stats */
1340 rte_eth_stats_reset(test_params->bonded_port_id);
1344 for (i = 0; i < MAX_PKT_BURST; i++) {
1345 if (gen_pkt_burst[i] != NULL)
1346 rte_pktmbuf_free(gen_pkt_burst[i]);
1348 if (rx_pkt_burst[i] != NULL)
1349 rte_pktmbuf_free(rx_pkt_burst[i]);
1353 /* Clean up and remove slaves from bonded device */
1354 return remove_slaves_and_stop_bonded_device();
1357 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1360 test_roundrobin_rx_burst_on_multiple_slaves(void)
1362 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1364 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1365 struct rte_eth_stats port_stats;
1367 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1371 /* Initialize bonded device with 4 slaves in round robin mode */
1372 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1376 /* Generate test bursts of packets to transmit */
1377 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1378 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0,
1379 0) != burst_size[i])
1383 /* Add rx data to slaves */
1384 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1385 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1386 &gen_pkt_burst[i][0], burst_size[i]);
1389 /* Call rx burst on bonded device */
1390 /* Send burst on bonded port */
1391 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1393 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
1394 printf("round-robin rx burst failed (%d != %d)\n", nb_rx,
1395 burst_size[0] + burst_size[1] + burst_size[2]);
1399 /* Verify bonded device rx count */
1400 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1401 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
1403 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1404 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1405 burst_size[0] + burst_size[1] + burst_size[2]);
1410 /* Verify bonded slave devices rx counts */
1411 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1412 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
1413 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1414 test_params->slave_port_ids[0],
1415 (unsigned int)port_stats.ipackets, burst_size[0]);
1419 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1420 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
1421 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1422 test_params->slave_port_ids[1],
1423 (unsigned int)port_stats.ipackets, burst_size[1]);
1427 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1428 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
1429 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1430 test_params->slave_port_ids[2],
1431 (unsigned int)port_stats.ipackets, burst_size[2]);
1435 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1436 if (port_stats.ipackets != 0) {
1437 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1438 test_params->slave_port_ids[3],
1439 (unsigned int)port_stats.ipackets, 0);
1444 for (i = 0; i < MAX_PKT_BURST; i++) {
1445 if (rx_pkt_burst[i] != NULL)
1446 rte_pktmbuf_free(rx_pkt_burst[i]);
1449 /* Clean up and remove slaves from bonded device */
1450 return remove_slaves_and_stop_bonded_device();
1454 test_roundrobin_verify_mac_assignment(void)
1456 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1460 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1461 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1463 /* Initialize bonded device with 4 slaves in round robin mode */
1464 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1)
1468 /* Verify that all MACs are the same as first slave added to bonded dev */
1469 for (i = 0; i < test_params->bonded_slave_count; i++) {
1470 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1471 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1472 sizeof(read_mac_addr))) {
1473 printf("slave port (%d) mac address not set to that of primary port\n",
1474 test_params->slave_port_ids[i]);
1479 /* change primary and verify that MAC addresses haven't changed */
1480 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
1481 test_params->slave_port_ids[2]);
1483 printf("Failed to set bonded port (%d) primary port to (%d)\n",
1484 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1488 for (i = 0; i < test_params->bonded_slave_count; i++) {
1489 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1490 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1491 sizeof(read_mac_addr))) {
1492 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
1493 test_params->slave_port_ids[i]);
1498 /* stop / start bonded device and verify that primary MAC address is
1499 * propagate to bonded device and slaves */
1501 rte_eth_dev_stop(test_params->bonded_port_id);
1503 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
1506 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1507 if (memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr))) {
1508 printf("bonded port (%d) mac address not set to that of new primary port\n",
1509 test_params->slave_port_ids[i]);
1513 for (i = 0; i < test_params->bonded_slave_count; i++) {
1514 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1515 if (memcmp(&expected_mac_addr_2, &read_mac_addr,
1516 sizeof(read_mac_addr))) {
1517 printf("slave port (%d) mac address not set to that of new primary port\n",
1518 test_params->slave_port_ids[i]);
1523 /* Set explicit MAC address */
1524 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1525 (struct ether_addr *)bonded_mac) != 0) {
1529 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1530 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1531 printf("bonded port (%d) mac address not set to that of new primary port\n",
1532 test_params->slave_port_ids[i]);
1536 for (i = 0; i < test_params->bonded_slave_count; i++) {
1537 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1538 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1539 printf("slave port (%d) mac address not set to that of new primary port\n",
1540 test_params->slave_port_ids[i]);
1545 /* Clean up and remove slaves from bonded device */
1546 return remove_slaves_and_stop_bonded_device();
1550 test_roundrobin_verify_promiscuous_enable_disable(void)
1552 int i, promiscuous_en;
1554 /* Initialize bonded device with 4 slaves in round robin mode */
1555 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1) !=
1559 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1561 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1562 if (promiscuous_en != 1) {
1563 printf("Port (%d) promiscuous mode not enabled\n",
1564 test_params->bonded_port_id);
1568 for (i = 0; i < test_params->bonded_slave_count; i++) {
1569 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1570 if (promiscuous_en != 1) {
1571 printf("slave port (%d) promiscuous mode not enabled\n",
1572 test_params->slave_port_ids[i]);
1577 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1579 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1580 if (promiscuous_en != 0) {
1581 printf("Port (%d) promiscuous mode not disabled\n",
1582 test_params->bonded_port_id);
1586 for (i = 0; i < test_params->bonded_slave_count; i++) {
1587 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1588 if (promiscuous_en != 0) {
1589 printf("slave port (%d) promiscuous mode not disabled\n",
1590 test_params->slave_port_ids[i]);
1595 /* Clean up and remove slaves from bonded device */
1596 return remove_slaves_and_stop_bonded_device();
1599 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1600 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1603 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1605 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1606 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1607 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1609 struct rte_eth_stats port_stats;
1610 uint8_t slaves[RTE_MAX_ETHPORTS];
1612 int i, burst_size, slave_count;
1614 /* NULL all pointers in array to simplify cleanup */
1615 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1617 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1618 * in round robin mode */
1619 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN,
1620 TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
1623 /* Verify Current Slaves Count /Active Slave Count is */
1624 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1626 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1627 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
1628 TEST_RR_LINK_STATUS_SLAVE_COUNT);
1632 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1633 slaves, RTE_MAX_ETHPORTS);
1634 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1635 printf("Number of active slaves (%d) is not as expected (%d).\n",
1636 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1640 /* Set 2 slaves eth_devs link status to down */
1641 virtual_ethdev_simulate_link_status_interrupt(
1642 test_params->slave_port_ids[1], 0);
1643 virtual_ethdev_simulate_link_status_interrupt(
1644 test_params->slave_port_ids[3], 0);
1646 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1647 slaves, RTE_MAX_ETHPORTS) !=
1648 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) {
1649 printf("Number of active slaves (%d) is not as expected (%d).\n",
1650 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1656 /* Verify that pkts are not sent on slaves with link status down:
1658 * 1. Generate test burst of traffic
1659 * 2. Transmit burst on bonded eth_dev
1660 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1661 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1663 if (generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1665 printf("generate_test_burst failed\n");
1669 rte_eth_stats_reset(test_params->bonded_port_id);
1671 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1672 burst_size) != burst_size) {
1673 printf("rte_eth_tx_burst failed\n");
1677 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1678 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1679 "Port (%d) opackets stats (%d) not expected (%d) value",
1680 test_params->bonded_port_id, (int)port_stats.opackets,
1683 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1684 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1685 "Port (%d) opackets stats (%d) not expected (%d) value",
1686 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1688 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1689 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1690 "Port (%d) opackets stats (%d) not expected (%d) value",
1691 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1693 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1694 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1695 "Port (%d) opackets stats (%d) not expected (%d) value",
1696 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1698 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1699 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1700 "Port (%d) opackets stats (%d) not expected (%d) value",
1701 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1703 /* Verify that pkts are not sent on slaves with link status down:
1705 * 1. Generate test bursts of traffic
1706 * 2. Add bursts on to virtual eth_devs
1707 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1708 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1709 * 4. Verify stats for bonded eth_dev
1710 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1712 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1713 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0)
1717 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1718 &gen_pkt_burst[i][0], burst_size);
1721 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1722 MAX_PKT_BURST) != burst_size + burst_size) {
1723 printf("rte_eth_rx_burst\n");
1727 /* Verify bonded device rx count */
1728 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1729 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
1730 printf("(%d) port_stats.ipackets not as expected\n",
1731 test_params->bonded_port_id);
1736 for (i = 0; i < MAX_PKT_BURST; i++) {
1737 if (rx_pkt_burst[i] != NULL)
1738 rte_pktmbuf_free(rx_pkt_burst[i]);
1740 if (gen_pkt_burst[1][i] != NULL)
1741 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1743 if (gen_pkt_burst[3][i] != NULL)
1744 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1747 /* Clean up and remove slaves from bonded device */
1748 return remove_slaves_and_stop_bonded_device();
1751 /** Active Backup Mode Tests */
1754 test_activebackup_tx_burst(void)
1756 int i, retval, pktlen, primary_port, burst_size, generated_burst_size, nb_tx;
1757 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1758 struct rte_eth_stats port_stats;
1760 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 1);
1762 printf("Failed to initialize_bonded_device_with_slaves.\n");
1766 initialize_eth_header(test_params->pkt_eth_hdr,
1767 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
1768 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1770 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1771 dst_addr_0, pktlen);
1773 burst_size = 20 * test_params->bonded_slave_count;
1775 if (burst_size > MAX_PKT_BURST) {
1776 printf("Burst size specified is greater than supported.\n");
1780 /* Generate a burst of packets to transmit */
1781 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1782 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
1783 1, test_params->pkt_udp_hdr, burst_size);
1784 if (generated_burst_size != burst_size)
1787 /* Send burst on bonded port */
1788 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1790 if (nb_tx != burst_size)
1793 /* Verify bonded port tx stats */
1794 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1795 if (port_stats.opackets != (uint64_t)burst_size) {
1796 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1797 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1802 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1804 /* Verify slave ports tx stats */
1805 for (i = 0; i < test_params->bonded_slave_count; i++) {
1806 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1807 if (test_params->slave_port_ids[i] == primary_port) {
1808 if (port_stats.opackets != (uint64_t)burst_size) {
1809 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1810 test_params->bonded_port_id,
1811 (unsigned int)port_stats.opackets,
1812 burst_size / test_params->bonded_slave_count);
1816 if (port_stats.opackets != 0) {
1817 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1818 test_params->bonded_port_id,
1819 (unsigned int)port_stats.opackets, 0);
1825 /* Put all slaves down and try and transmit */
1826 for (i = 0; i < test_params->bonded_slave_count; i++) {
1828 virtual_ethdev_simulate_link_status_interrupt(
1829 test_params->slave_port_ids[i], 0);
1832 /* Send burst on bonded port */
1833 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1838 /* Clean up and remove slaves from bonded device */
1839 return remove_slaves_and_stop_bonded_device();
1842 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
1845 test_activebackup_rx_burst(void)
1847 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1848 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1850 struct rte_eth_stats port_stats;
1854 int i, j, nb_rx, burst_size = 17;
1856 /* Initialize bonded device with 4 slaves in round robin mode */
1857 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
1858 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
1863 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1864 if (primary_port < 0) {
1865 printf("failed to get primary slave for bonded port (%d)",
1866 test_params->bonded_port_id);
1869 for (i = 0; i < test_params->bonded_slave_count; i++) {
1870 /* Generate test bursts of packets to transmit */
1871 if (generate_test_burst(&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0)
1876 /* Add rx data to slave */
1877 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1878 &gen_pkt_burst[0], burst_size);
1880 /* Call rx burst on bonded device */
1881 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
1882 &rx_pkt_burst[0], MAX_PKT_BURST);
1884 printf("rte_eth_rx_burst failed\n");
1888 if (test_params->slave_port_ids[i] == primary_port) {
1889 /* Verify bonded device rx count */
1890 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1891 if (port_stats.ipackets != (uint64_t)burst_size) {
1892 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1893 test_params->bonded_port_id,
1894 (unsigned int)port_stats.ipackets, burst_size);
1898 /* Verify bonded slave devices rx count */
1899 for (j = 0; j < test_params->bonded_slave_count; j++) {
1900 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1902 if (port_stats.ipackets != (uint64_t)burst_size) {
1903 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1904 test_params->slave_port_ids[i],
1905 (unsigned int)port_stats.ipackets, burst_size);
1909 if (port_stats.ipackets != 0) {
1910 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1911 test_params->slave_port_ids[i],
1912 (unsigned int)port_stats.ipackets, 0);
1918 for (j = 0; j < test_params->bonded_slave_count; j++) {
1919 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1920 if (port_stats.ipackets != 0) {
1921 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1922 test_params->slave_port_ids[i],
1923 (unsigned int)port_stats.ipackets, 0);
1930 for (i = 0; i < MAX_PKT_BURST; i++) {
1931 if (rx_pkt_burst[i] != NULL) {
1932 rte_pktmbuf_free(rx_pkt_burst[i]);
1933 rx_pkt_burst[i] = NULL;
1937 /* reset bonded device stats */
1938 rte_eth_stats_reset(test_params->bonded_port_id);
1941 /* Clean up and remove slaves from bonded device */
1942 return remove_slaves_and_stop_bonded_device();
1946 test_activebackup_verify_promiscuous_enable_disable(void)
1948 int i, primary_port, promiscuous_en;
1950 /* Initialize bonded device with 4 slaves in round robin mode */
1951 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 4, 1)
1955 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1956 if (primary_port < 0) {
1957 printf("failed to get primary slave for bonded port (%d)",
1958 test_params->bonded_port_id);
1961 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1963 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1964 if (promiscuous_en != 1) {
1965 printf("Port (%d) promiscuous mode not enabled\n",
1966 test_params->bonded_port_id);
1970 for (i = 0; i < test_params->bonded_slave_count; i++) {
1971 promiscuous_en = rte_eth_promiscuous_get(
1972 test_params->slave_port_ids[i]);
1973 if (primary_port == test_params->slave_port_ids[i]) {
1974 if (promiscuous_en != 1) {
1975 printf("slave port (%d) promiscuous mode not enabled\n",
1976 test_params->slave_port_ids[i]);
1980 if (promiscuous_en != 0) {
1981 printf("slave port (%d) promiscuous mode enabled\n",
1982 test_params->slave_port_ids[i]);
1989 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1991 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1992 if (promiscuous_en != 0) {
1993 printf("Port (%d) promiscuous mode not disabled\n",
1994 test_params->bonded_port_id);
1998 for (i = 0; i < test_params->bonded_slave_count; i++) {
1999 promiscuous_en = rte_eth_promiscuous_get(
2000 test_params->slave_port_ids[i]);
2001 if (promiscuous_en != 0) {
2002 printf("slave port (%d) promiscuous mode not disabled\n",
2003 test_params->slave_port_ids[i]);
2008 /* Clean up and remove slaves from bonded device */
2009 return remove_slaves_and_stop_bonded_device();
2013 test_activebackup_verify_mac_assignment(void)
2015 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2017 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2018 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2020 /* Initialize bonded device with 2 slaves in active backup mode */
2021 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 1)
2025 /* Verify that bonded MACs is that of first slave and that the other slave
2026 * MAC hasn't been changed */
2027 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2028 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2029 printf("bonded port (%d) mac address not set to that of primary port\n",
2030 test_params->bonded_port_id);
2034 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2035 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2036 printf("slave port (%d) mac address not set to that of primary port\n",
2037 test_params->slave_port_ids[0]);
2041 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2042 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2043 printf("slave port (%d) mac address not as expected\n",
2044 test_params->slave_port_ids[1]);
2048 /* change primary and verify that MAC addresses haven't changed */
2049 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2050 test_params->slave_port_ids[1]) != 0) {
2051 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2052 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2056 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2057 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2058 printf("bonded port (%d) mac address not set to that of primary port\n",
2059 test_params->bonded_port_id);
2063 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2064 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2065 printf("slave port (%d) mac address not set to that of primary port\n",
2066 test_params->slave_port_ids[0]);
2070 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2071 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2072 printf("slave port (%d) mac address not as expected\n",
2073 test_params->slave_port_ids[1]);
2077 /* stop / start bonded device and verify that primary MAC address is
2078 * propagated to bonded device and slaves */
2080 rte_eth_dev_stop(test_params->bonded_port_id);
2082 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2085 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2086 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2087 printf("bonded port (%d) mac address not set to that of primary port\n",
2088 test_params->bonded_port_id);
2092 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2093 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2094 printf("slave port (%d) mac address not as expected\n",
2095 test_params->slave_port_ids[0]);
2099 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2100 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2101 printf("slave port (%d) mac address not set to that of primary port\n",
2102 test_params->slave_port_ids[1]);
2106 /* Set explicit MAC address */
2107 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
2108 (struct ether_addr *)bonded_mac) != 0) {
2112 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2113 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2114 printf("bonded port (%d) mac address not set to that of bonded port\n",
2115 test_params->bonded_port_id);
2119 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2120 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2121 printf("slave port (%d) mac address not as expected\n",
2122 test_params->slave_port_ids[0]);
2126 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2127 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2128 printf("slave port (%d) mac address not set to that of bonded port\n",
2129 test_params->slave_port_ids[1]);
2133 /* Clean up and remove slaves from bonded device */
2134 return remove_slaves_and_stop_bonded_device();
2138 test_activebackup_verify_slave_link_status_change_failover(void)
2140 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2141 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2142 struct rte_eth_stats port_stats;
2144 uint8_t slaves[RTE_MAX_ETHPORTS];
2146 int i, j, burst_size, slave_count, primary_port;
2150 memset(pkt_burst, 0, sizeof(pkt_burst));
2152 /* Generate packet burst for testing */
2153 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
2155 printf("generate_test_burst failed\n");
2159 /* Initialize bonded device with 4 slaves in round robin mode */
2160 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
2161 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2165 /* Verify Current Slaves Count /Active Slave Count is */
2166 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2168 if (slave_count != 4) {
2169 printf("Number of slaves (%d) is not as expected (%d).\n",
2174 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2175 slaves, RTE_MAX_ETHPORTS);
2176 if (slave_count != 4) {
2177 printf("Number of active slaves (%d) is not as expected (%d).\n",
2182 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2183 if (primary_port != test_params->slave_port_ids[0])
2184 printf("Primary port not as expected");
2186 /* Bring 2 slaves down and verify active slave count */
2187 virtual_ethdev_simulate_link_status_interrupt(
2188 test_params->slave_port_ids[1], 0);
2189 virtual_ethdev_simulate_link_status_interrupt(
2190 test_params->slave_port_ids[3], 0);
2192 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2193 RTE_MAX_ETHPORTS) != 2) {
2194 printf("Number of active slaves (%d) is not as expected (%d).\n",
2199 virtual_ethdev_simulate_link_status_interrupt(
2200 test_params->slave_port_ids[1], 1);
2201 virtual_ethdev_simulate_link_status_interrupt(
2202 test_params->slave_port_ids[3], 1);
2205 /* Bring primary port down, verify that active slave count is 3 and primary
2207 virtual_ethdev_simulate_link_status_interrupt(
2208 test_params->slave_port_ids[0], 0);
2210 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2211 RTE_MAX_ETHPORTS) != 3) {
2212 printf("Number of active slaves (%d) is not as expected (%d).\n",
2217 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2218 if (primary_port != test_params->slave_port_ids[2])
2219 printf("Primary port not as expected");
2221 /* Verify that pkts are sent on new primary slave */
2223 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size)
2225 printf("rte_eth_tx_burst failed\n");
2229 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2230 if (port_stats.opackets != (uint64_t)burst_size) {
2231 printf("(%d) port_stats.opackets not as expected\n",
2232 test_params->slave_port_ids[2]);
2236 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2237 if (port_stats.opackets != 0) {
2238 printf("(%d) port_stats.opackets not as expected\n",
2239 test_params->slave_port_ids[0]);
2242 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2243 if (port_stats.opackets != 0) {
2244 printf("(%d) port_stats.opackets not as expected\n",
2245 test_params->slave_port_ids[1]);
2248 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2249 if (port_stats.opackets != 0) {
2250 printf("(%d) port_stats.opackets not as expected\n",
2251 test_params->slave_port_ids[3]);
2255 /* Generate packet burst for testing */
2257 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2258 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
2262 virtual_ethdev_add_mbufs_to_rx_queue(
2263 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2266 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2267 MAX_PKT_BURST) != burst_size) {
2268 printf("rte_eth_rx_burst\n");
2272 /* Verify bonded device rx count */
2273 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2274 if (port_stats.ipackets != (uint64_t)burst_size) {
2275 printf("(%d) port_stats.ipackets not as expected\n",
2276 test_params->bonded_port_id);
2280 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2281 if (port_stats.opackets != (uint64_t)burst_size) {
2282 printf("(%d) port_stats.opackets not as expected\n",
2283 test_params->slave_port_ids[2]);
2287 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2288 if (port_stats.opackets != 0) {
2289 printf("(%d) port_stats.opackets not as expected\n",
2290 test_params->slave_port_ids[0]);
2294 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2295 if (port_stats.opackets != 0) {
2296 printf("(%d) port_stats.opackets not as expected\n",
2297 test_params->slave_port_ids[1]);
2301 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2302 if (port_stats.opackets != 0) {
2303 printf("(%d) port_stats.opackets not as expected\n",
2304 test_params->slave_port_ids[3]);
2310 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2311 for (j = 0; j < MAX_PKT_BURST; j++) {
2312 if (pkt_burst[i][j] != NULL) {
2313 rte_pktmbuf_free(pkt_burst[i][j]);
2314 pkt_burst[i][j] = NULL;
2320 /* Clean up and remove slaves from bonded device */
2321 return remove_slaves_and_stop_bonded_device();
2324 /** Balance Mode Tests */
2327 test_balance_xmit_policy_configuration(void)
2331 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
2334 printf("Failed to initialize_bonded_device_with_slaves.\n");
2338 /* Invalid port id */
2339 retval = rte_eth_bond_xmit_policy_set(INVALID_PORT_ID,
2340 BALANCE_XMIT_POLICY_LAYER2);
2342 printf("Expected call to failed as invalid port specified.\n");
2346 /* Set xmit policy on non bonded device */
2347 retval = rte_eth_bond_xmit_policy_set(test_params->slave_port_ids[0],
2348 BALANCE_XMIT_POLICY_LAYER2);
2350 printf("Expected call to failed as invalid port specified.\n");
2354 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2355 BALANCE_XMIT_POLICY_LAYER2);
2357 printf("Failed to set balance xmit policy.\n");
2360 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2361 BALANCE_XMIT_POLICY_LAYER2) {
2362 printf("balance xmit policy not as expected.\n");
2366 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2367 BALANCE_XMIT_POLICY_LAYER23);
2369 printf("Failed to set balance xmit policy.\n");
2372 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2373 BALANCE_XMIT_POLICY_LAYER23) {
2374 printf("balance xmit policy not as expected.\n");
2378 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2379 BALANCE_XMIT_POLICY_LAYER34);
2381 printf("Failed to set balance xmit policy.\n");
2384 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2385 BALANCE_XMIT_POLICY_LAYER34) {
2386 printf("balance xmit policy not as expected.\n");
2390 /* Invalid port id */
2391 if (rte_eth_bond_xmit_policy_get(INVALID_PORT_ID) >= 0)
2394 /* Clean up and remove slaves from bonded device */
2395 return remove_slaves_and_stop_bonded_device();
2398 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2401 test_balance_l2_tx_burst(void)
2403 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2404 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2409 struct rte_eth_stats port_stats;
2411 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
2412 TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1);
2414 printf("Failed to initialize_bonded_device_with_slaves.\n");
2418 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2419 BALANCE_XMIT_POLICY_LAYER2);
2421 printf("Failed to set balance xmit policy.\n");
2426 initialize_eth_header(test_params->pkt_eth_hdr,
2427 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2428 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2430 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2431 dst_addr_0, pktlen);
2433 /* Generate a burst 1 of packets to transmit */
2434 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2435 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2436 test_params->pkt_udp_hdr, burst_size[0]) != burst_size[0])
2439 initialize_eth_header(test_params->pkt_eth_hdr,
2440 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2442 /* Generate a burst 2 of packets to transmit */
2443 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2444 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2445 test_params->pkt_udp_hdr, burst_size[1]) != burst_size[1])
2448 /* Send burst 1 on bonded port */
2449 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2450 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[i][0],
2451 burst_size[i]) != burst_size[i])
2454 /* Verify bonded port tx stats */
2455 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2456 if (port_stats.opackets != (uint64_t)(burst_size[0] + burst_size[1])) {
2457 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2458 test_params->bonded_port_id,
2459 (unsigned int)port_stats.opackets, burst_size[0] + burst_size[1]);
2464 /* Verify slave ports tx stats */
2465 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2466 if (port_stats.opackets != (uint64_t)burst_size[0]) {
2467 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2468 test_params->slave_port_ids[0],
2469 (unsigned int)port_stats.opackets, burst_size[0]);
2473 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2474 if (port_stats.opackets != (uint64_t)burst_size[1]) {
2475 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2476 test_params->slave_port_ids[1], (
2477 unsigned int)port_stats.opackets, burst_size[1]);
2481 /* Put all slaves down and try and transmit */
2482 for (i = 0; i < test_params->bonded_slave_count; i++) {
2484 virtual_ethdev_simulate_link_status_interrupt(
2485 test_params->slave_port_ids[i], 0);
2488 /* Send burst on bonded port */
2489 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[0][0],
2490 burst_size[0]) != 0)
2493 /* Clean up and remove slaves from bonded device */
2494 return remove_slaves_and_stop_bonded_device();
2498 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2499 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2502 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2504 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2505 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2507 struct rte_eth_stats port_stats;
2509 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1);
2511 printf("Failed to initialize_bonded_device_with_slaves.\n");
2515 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2516 BALANCE_XMIT_POLICY_LAYER23);
2518 printf("Failed to set balance xmit policy.\n");
2525 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2526 printf("Burst size specified is greater than supported.\n");
2530 /* Generate test bursts of packets to transmit */
2531 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4,
2532 0, 0, 0) != burst_size_1)
2535 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2536 toggle_mac_addr, toggle_ip_addr, 0) != burst_size_2)
2539 /* Send burst 1 on bonded port */
2540 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2542 if (nb_tx_1 != burst_size_1)
2545 /* Send burst 2 on bonded port */
2546 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2548 if (nb_tx_2 != burst_size_2)
2551 /* Verify bonded port tx stats */
2552 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2553 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2554 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2555 test_params->bonded_port_id,
2556 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2560 /* Verify slave ports tx stats */
2561 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2562 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2563 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2564 test_params->slave_port_ids[0],
2565 (unsigned int)port_stats.opackets, nb_tx_1);
2569 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2570 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2571 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2572 test_params->slave_port_ids[1],
2573 (unsigned int)port_stats.opackets, nb_tx_2);
2577 /* Put all slaves down and try and transmit */
2578 for (i = 0; i < test_params->bonded_slave_count; i++) {
2580 virtual_ethdev_simulate_link_status_interrupt(
2581 test_params->slave_port_ids[i], 0);
2584 /* Send burst on bonded port */
2585 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2590 /* Clean up and remove slaves from bonded device */
2591 return remove_slaves_and_stop_bonded_device();
2595 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2597 return balance_l23_tx_burst(0, 1, 1, 0);
2601 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2603 return balance_l23_tx_burst(1, 1, 0, 1);
2607 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2609 return balance_l23_tx_burst(0, 0, 0, 1);
2613 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2615 return balance_l23_tx_burst(1, 0, 0, 1);
2619 test_balance_l23_tx_burst_toggle_mac_addr(void)
2621 return balance_l23_tx_burst(0, 0, 1, 0);
2625 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2626 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2627 uint8_t toggle_udp_port)
2630 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2632 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2633 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2635 struct rte_eth_stats port_stats;
2637 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1);
2639 printf("Failed to initialize_bonded_device_with_slaves.\n");
2643 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2644 BALANCE_XMIT_POLICY_LAYER34);
2646 printf("Failed to set balance xmit policy.\n");
2653 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2654 printf("Burst size specified is greater than supported.\n");
2658 /* Generate test bursts of packets to transmit */
2659 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0,
2660 0, 0) != burst_size_1)
2663 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2664 toggle_mac_addr, toggle_ip_addr, toggle_udp_port) != burst_size_2)
2667 /* Send burst 1 on bonded port */
2668 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2670 if (nb_tx_1 != burst_size_1)
2673 /* Send burst 2 on bonded port */
2674 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2676 if (nb_tx_2 != burst_size_2)
2680 /* Verify bonded port tx stats */
2681 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2682 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2683 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2684 test_params->bonded_port_id,
2685 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2689 /* Verify slave ports tx stats */
2690 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2691 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2692 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2693 test_params->slave_port_ids[0],
2694 (unsigned int)port_stats.opackets, nb_tx_1);
2698 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2699 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2700 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2701 test_params->slave_port_ids[1],
2702 (unsigned int)port_stats.opackets, nb_tx_2);
2706 /* Put all slaves down and try and transmit */
2707 for (i = 0; i < test_params->bonded_slave_count; i++) {
2709 virtual_ethdev_simulate_link_status_interrupt(
2710 test_params->slave_port_ids[i], 0);
2713 /* Send burst on bonded port */
2714 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2719 /* Clean up and remove slaves from bonded device */
2720 return remove_slaves_and_stop_bonded_device();
2724 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2726 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2730 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2732 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2736 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2738 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2742 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2744 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2748 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2750 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2754 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2756 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2759 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
2762 test_balance_rx_burst(void)
2764 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2766 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2767 struct rte_eth_stats port_stats;
2769 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
2772 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
2774 /* Initialize bonded device with 4 slaves in round robin mode */
2775 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 3, 1)
2779 /* Generate test bursts of packets to transmit */
2780 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2781 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
2782 0, 0) != burst_size[i])
2785 /* Add rx data to slaves */
2786 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2787 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2788 &gen_pkt_burst[i][0], burst_size[i]);
2791 /* Call rx burst on bonded device */
2792 /* Send burst on bonded port */
2793 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2795 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
2796 printf("balance rx burst failed\n");
2800 /* Verify bonded device rx count */
2801 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2802 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
2804 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2805 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
2806 burst_size[0] + burst_size[1] + burst_size[2]);
2811 /* Verify bonded slave devices rx counts */
2812 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2813 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
2814 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2815 test_params->slave_port_ids[0],
2816 (unsigned int)port_stats.ipackets, burst_size[0]);
2820 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2821 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
2822 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2823 test_params->slave_port_ids[1],
2824 (unsigned int)port_stats.ipackets, burst_size[1]);
2828 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2829 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
2830 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2831 test_params->slave_port_ids[2],
2832 (unsigned int)port_stats.ipackets, burst_size[2]);
2836 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2837 if (port_stats.ipackets != 0) {
2838 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2839 test_params->slave_port_ids[3],
2840 (unsigned int)port_stats.ipackets, 0);
2845 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2846 for (j = 0; j < MAX_PKT_BURST; j++) {
2847 if (gen_pkt_burst[i][j] != NULL) {
2848 rte_pktmbuf_free(gen_pkt_burst[i][j]);
2849 gen_pkt_burst[i][j] = NULL;
2854 /* Clean up and remove slaves from bonded device */
2855 return remove_slaves_and_stop_bonded_device();
2859 test_balance_verify_promiscuous_enable_disable(void)
2861 int i, promiscuous_en;
2863 /* Initialize bonded device with 4 slaves in round robin mode */
2864 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 0)
2867 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2869 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2870 if (promiscuous_en != 1) {
2871 printf("Port (%d) promiscuous mode not enabled\n",
2872 test_params->bonded_port_id);
2876 for (i = 0; i < test_params->bonded_slave_count; i++) {
2877 promiscuous_en = rte_eth_promiscuous_get(
2878 test_params->slave_port_ids[i]);
2879 if (promiscuous_en != 1) {
2880 printf("slave port (%d) promiscuous mode not enabled\n",
2881 test_params->slave_port_ids[i]);
2886 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2888 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2889 if (promiscuous_en != 0) {
2890 printf("Port (%d) promiscuous mode not disabled\n",
2891 test_params->bonded_port_id);
2895 for (i = 0; i < test_params->bonded_slave_count; i++) {
2896 promiscuous_en = rte_eth_promiscuous_get(
2897 test_params->slave_port_ids[i]);
2898 if (promiscuous_en != 0) {
2899 printf("slave port (%d) promiscuous mode not disabled\n",
2900 test_params->slave_port_ids[i]);
2905 /* Clean up and remove slaves from bonded device */
2906 return remove_slaves_and_stop_bonded_device();
2910 test_balance_verify_mac_assignment(void)
2912 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2914 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2915 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2917 /* Initialize bonded device with 2 slaves in active backup mode */
2918 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1) != 0)
2921 /* Verify that bonded MACs is that of first slave and that the other slave
2922 * MAC hasn't been changed */
2923 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2924 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2925 printf("bonded port (%d) mac address not set to that of primary port\n",
2926 test_params->bonded_port_id);
2930 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2931 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2932 printf("slave port (%d) mac address not set to that of primary port\n",
2933 test_params->slave_port_ids[0]);
2937 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2938 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2939 printf("slave port (%d) mac address not set to that of primary port\n",
2940 test_params->slave_port_ids[1]);
2944 /* change primary and verify that MAC addresses haven't changed */
2945 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2946 test_params->slave_port_ids[1]) != 0) {
2947 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2948 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2952 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2953 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2954 printf("bonded port (%d) mac address not set to that of primary port\n",
2955 test_params->bonded_port_id);
2959 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2960 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2961 printf("slave port (%d) mac address not set to that of primary port\n",
2962 test_params->slave_port_ids[0]);
2966 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2967 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2968 printf("slave port (%d) mac address not set to that of primary port\n",
2969 test_params->slave_port_ids[1]);
2973 /* stop / start bonded device and verify that primary MAC address is
2974 * propagated to bonded device and slaves */
2976 rte_eth_dev_stop(test_params->bonded_port_id);
2978 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2981 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2982 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2983 printf("bonded port (%d) mac address not set to that of primary port\n",
2984 test_params->bonded_port_id);
2988 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2989 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2990 printf("slave port (%d) mac address not set to that of primary port\n",
2991 test_params->slave_port_ids[0]);
2995 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2996 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2997 printf("slave port (%d) mac address not set to that of primary port\n",
2998 test_params->slave_port_ids[1]);
3002 /* Set explicit MAC address */
3003 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3004 (struct ether_addr *)bonded_mac) != 0)
3007 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3008 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3009 printf("bonded port (%d) mac address not set to that of bonded port\n",
3010 test_params->bonded_port_id);
3014 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3015 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3016 printf("slave port (%d) mac address not as expected\n",
3017 test_params->slave_port_ids[0]);
3021 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3022 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3023 printf("slave port (%d) mac address not set to that of bonded port\n",
3024 test_params->slave_port_ids[1]);
3028 /* Clean up and remove slaves from bonded device */
3029 return remove_slaves_and_stop_bonded_device();
3032 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3035 test_balance_verify_slave_link_status_change_behaviour(void)
3037 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3038 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3039 struct rte_eth_stats port_stats;
3041 uint8_t slaves[RTE_MAX_ETHPORTS];
3043 int i, j, burst_size, slave_count;
3045 memset(pkt_burst, 0, sizeof(pkt_burst));
3047 /* Initialize bonded device with 4 slaves in round robin mode */
3048 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
3049 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
3052 if (rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
3053 BALANCE_XMIT_POLICY_LAYER2)) {
3054 printf("Failed to set balance xmit policy.\n");
3058 /* Verify Current Slaves Count /Active Slave Count is */
3059 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3061 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3062 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
3063 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3067 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3068 slaves, RTE_MAX_ETHPORTS);
3069 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3070 printf("Number of active slaves (%d) is not as expected (%d).\n",
3071 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3075 /* Set 2 slaves link status to down */
3076 virtual_ethdev_simulate_link_status_interrupt(
3077 test_params->slave_port_ids[1], 0);
3078 virtual_ethdev_simulate_link_status_interrupt(
3079 test_params->slave_port_ids[3], 0);
3081 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3082 slaves, RTE_MAX_ETHPORTS) != 2) {
3083 printf("Number of active slaves (%d) is not as expected (%d).\n",
3088 /* Send to sets of packet burst and verify that they are balanced across
3092 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
3094 printf("generate_test_burst failed\n");
3098 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3100 printf("generate_test_burst failed\n");
3104 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3105 burst_size) != burst_size) {
3106 printf("rte_eth_tx_burst failed\n");
3110 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3111 burst_size) != burst_size) {
3112 printf("rte_eth_tx_burst failed\n");
3116 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3117 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3118 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3119 test_params->bonded_port_id, (int)port_stats.opackets,
3120 burst_size + burst_size);
3124 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3125 if (port_stats.opackets != (uint64_t)burst_size) {
3126 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3127 test_params->slave_port_ids[0], (int)port_stats.opackets,
3132 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3133 if (port_stats.opackets != (uint64_t)burst_size) {
3134 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3135 test_params->slave_port_ids[2], (int)port_stats.opackets,
3140 /* verify that all packets get send on primary slave when no other slaves
3142 virtual_ethdev_simulate_link_status_interrupt(
3143 test_params->slave_port_ids[2], 0);
3145 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
3146 RTE_MAX_ETHPORTS) != 1) {
3147 printf("Number of active slaves (%d) is not as expected (%d).\n",
3152 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3154 printf("generate_test_burst failed\n");
3158 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3159 burst_size) != burst_size) {
3160 printf("rte_eth_tx_burst failed\n");
3164 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3165 if (port_stats.opackets != (uint64_t)(burst_size + burst_size +
3167 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3168 test_params->bonded_port_id, (int)port_stats.opackets,
3169 burst_size + burst_size + burst_size);
3173 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3174 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3175 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3176 test_params->slave_port_ids[0], (int)port_stats.opackets,
3177 burst_size + burst_size);
3182 virtual_ethdev_simulate_link_status_interrupt(
3183 test_params->slave_port_ids[0], 0);
3184 virtual_ethdev_simulate_link_status_interrupt(
3185 test_params->slave_port_ids[1], 1);
3186 virtual_ethdev_simulate_link_status_interrupt(
3187 test_params->slave_port_ids[2], 1);
3188 virtual_ethdev_simulate_link_status_interrupt(
3189 test_params->slave_port_ids[3], 1);
3191 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3192 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
3196 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3197 &pkt_burst[i][0], burst_size);
3202 /* Verify that pkts are not received on slaves with link status down */
3204 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3207 /* Verify bonded device rx count */
3208 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3209 if (port_stats.ipackets != (uint64_t)(burst_size * 3)) {
3210 printf("(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3211 test_params->bonded_port_id, (int)port_stats.ipackets,
3216 /* free mbufs allocate for rx testing */
3217 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3218 for (j = 0; j < MAX_PKT_BURST; j++) {
3219 if (pkt_burst[i][j] != NULL) {
3220 rte_pktmbuf_free(pkt_burst[i][j]);
3221 pkt_burst[i][j] = NULL;
3226 /* Clean up and remove slaves from bonded device */
3227 return remove_slaves_and_stop_bonded_device();
3230 /** Broadcast Mode Tests */
3233 test_broadcast_tx_burst(void)
3235 int i, pktlen, retval, burst_size, generated_burst_size, nb_tx;
3236 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3238 struct rte_eth_stats port_stats;
3240 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 2, 1);
3242 printf("Failed to initialize_bonded_device_with_slaves.\n");
3246 initialize_eth_header(test_params->pkt_eth_hdr,
3247 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3249 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3251 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3252 dst_addr_0, pktlen);
3254 burst_size = 20 * test_params->bonded_slave_count;
3256 if (burst_size > MAX_PKT_BURST) {
3257 printf("Burst size specified is greater than supported.\n");
3261 /* Generate a burst of packets to transmit */
3262 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
3263 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3264 1, test_params->pkt_udp_hdr, burst_size);
3265 if (generated_burst_size != burst_size)
3268 /* Send burst on bonded port */
3269 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3271 if (nb_tx != burst_size * test_params->bonded_slave_count) {
3272 printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
3273 test_params->bonded_port_id,
3278 /* Verify bonded port tx stats */
3279 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3280 if (port_stats.opackets != (uint64_t)burst_size *
3281 test_params->bonded_slave_count) {
3282 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3283 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3287 /* Verify slave ports tx stats */
3288 for (i = 0; i < test_params->bonded_slave_count; i++) {
3289 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3290 if (port_stats.opackets != (uint64_t)burst_size) {
3291 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3292 test_params->bonded_port_id,
3293 (unsigned int)port_stats.opackets, burst_size);
3297 /* Put all slaves down and try and transmit */
3298 for (i = 0; i < test_params->bonded_slave_count; i++) {
3300 virtual_ethdev_simulate_link_status_interrupt(
3301 test_params->slave_port_ids[i], 0);
3304 /* Send burst on bonded port */
3305 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3310 /* Clean up and remove slaves from bonded device */
3311 return remove_slaves_and_stop_bonded_device();
3314 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3317 test_broadcast_rx_burst(void)
3319 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3321 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3322 struct rte_eth_stats port_stats;
3324 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3327 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3329 /* Initialize bonded device with 4 slaves in round robin mode */
3330 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 3, 1) != 0)
3334 /* Generate test bursts of packets to transmit */
3335 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3336 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0,
3337 0) != burst_size[i])
3341 /* Add rx data to slave 0 */
3342 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3343 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3344 &gen_pkt_burst[i][0], burst_size[i]);
3348 /* Call rx burst on bonded device */
3349 /* Send burst on bonded port */
3350 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3352 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3353 printf("round-robin rx burst failed");
3357 /* Verify bonded device rx count */
3358 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3359 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3361 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3362 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3363 burst_size[0] + burst_size[1] + burst_size[2]);
3368 /* Verify bonded slave devices rx counts */
3369 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3370 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3371 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3372 test_params->slave_port_ids[0],
3373 (unsigned int)port_stats.ipackets, burst_size[0]);
3377 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3378 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3379 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3380 test_params->slave_port_ids[1],
3381 (unsigned int)port_stats.ipackets, burst_size[1]);
3385 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3386 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3387 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3388 test_params->slave_port_ids[2],
3389 (unsigned int)port_stats.ipackets,
3394 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3395 if (port_stats.ipackets != 0) {
3396 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3397 test_params->slave_port_ids[3],
3398 (unsigned int)port_stats.ipackets, 0);
3402 /* free mbufs allocate for rx testing */
3403 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3404 for (j = 0; j < MAX_PKT_BURST; j++) {
3405 if (gen_pkt_burst[i][j] != NULL) {
3406 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3407 gen_pkt_burst[i][j] = NULL;
3412 /* Clean up and remove slaves from bonded device */
3413 return remove_slaves_and_stop_bonded_device();
3417 test_broadcast_verify_promiscuous_enable_disable(void)
3419 int i, promiscuous_en;
3421 /* Initialize bonded device with 4 slaves in round robin mode */
3422 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 0)
3425 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3427 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3428 if (promiscuous_en != 1) {
3429 printf("Port (%d) promiscuous mode not enabled\n",
3430 test_params->bonded_port_id);
3434 for (i = 0; i < test_params->bonded_slave_count; i++) {
3435 promiscuous_en = rte_eth_promiscuous_get(
3436 test_params->slave_port_ids[i]);
3437 if (promiscuous_en != 1) {
3438 printf("slave port (%d) promiscuous mode not enabled\n",
3439 test_params->slave_port_ids[i]);
3444 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3446 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3447 if (promiscuous_en != 0) {
3448 printf("Port (%d) promiscuous mode not disabled\n",
3449 test_params->bonded_port_id);
3453 for (i = 0; i < test_params->bonded_slave_count; i++) {
3454 promiscuous_en = rte_eth_promiscuous_get(
3455 test_params->slave_port_ids[i]);
3456 if (promiscuous_en != 0) {
3457 printf("slave port (%d) promiscuous mode not disabled\n",
3458 test_params->slave_port_ids[i]);
3463 /* Clean up and remove slaves from bonded device */
3464 return remove_slaves_and_stop_bonded_device();
3468 test_broadcast_verify_mac_assignment(void)
3470 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3474 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3475 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3477 /* Initialize bonded device with 4 slaves in round robin mode */
3478 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 4, 1) != 0)
3481 /* Verify that all MACs are the same as first slave added to bonded
3483 for (i = 0; i < test_params->bonded_slave_count; i++) {
3484 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3485 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3486 sizeof(read_mac_addr))) {
3487 printf("slave port (%d) mac address not set to that of primary port\n",
3488 test_params->slave_port_ids[i]);
3493 /* change primary and verify that MAC addresses haven't changed */
3494 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
3495 test_params->slave_port_ids[2]);
3497 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3498 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3502 for (i = 0; i < test_params->bonded_slave_count; i++) {
3503 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3504 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
3505 sizeof(read_mac_addr))) {
3506 printf("slave port (%d) mac address has changed to that of primary"
3507 "port without stop/start toggle of bonded device\n",
3508 test_params->slave_port_ids[i]);
3513 /* stop / start bonded device and verify that primary MAC address is
3514 * propagated to bonded device and slaves */
3516 rte_eth_dev_stop(test_params->bonded_port_id);
3518 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3521 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3522 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3523 printf("bonded port (%d) mac address not set to that of new primary"
3524 " port\n", test_params->slave_port_ids[i]);
3528 for (i = 0; i < test_params->bonded_slave_count; i++) {
3529 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3530 if (memcmp(&expected_mac_addr_1, &read_mac_addr,
3531 sizeof(read_mac_addr))) {
3532 printf("slave port (%d) mac address not set to that of new primary"
3533 "port\n", test_params->slave_port_ids[i]);
3538 /* Set explicit MAC address */
3539 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3540 (struct ether_addr *)bonded_mac) != 0)
3543 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3544 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3545 printf("bonded port (%d) mac address not set to that of new primary port\n",
3546 test_params->slave_port_ids[i]);
3550 for (i = 0; i < test_params->bonded_slave_count; i++) {
3551 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3552 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3553 printf("slave port (%d) mac address not set to that of new primary port\n",
3554 test_params->slave_port_ids[i]);
3559 /* Clean up and remove slaves from bonded device */
3560 return remove_slaves_and_stop_bonded_device();
3563 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3565 test_broadcast_verify_slave_link_status_change_behaviour(void)
3567 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3568 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3569 struct rte_eth_stats port_stats;
3571 uint8_t slaves[RTE_MAX_ETHPORTS];
3573 int i, j, burst_size, slave_count;
3575 memset(pkt_burst, 0, sizeof(pkt_burst));
3577 /* Initialize bonded device with 4 slaves in round robin mode */
3578 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST,
3579 BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
3582 /* Verify Current Slaves Count /Active Slave Count is */
3583 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3585 if (slave_count != 4) {
3586 printf("Number of slaves (%d) is not as expected (%d).\n",
3591 slave_count = rte_eth_bond_active_slaves_get(
3592 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
3593 if (slave_count != 4) {
3594 printf("Number of active slaves (%d) is not as expected (%d).\n",
3599 /* Set 2 slaves link status to down */
3600 virtual_ethdev_simulate_link_status_interrupt(
3601 test_params->slave_port_ids[1], 0);
3602 virtual_ethdev_simulate_link_status_interrupt(
3603 test_params->slave_port_ids[3], 0);
3605 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3606 slaves, RTE_MAX_ETHPORTS);
3607 if (slave_count != 2) {
3608 printf("Number of active slaves (%d) is not as expected (%d).\n",
3613 for (i = 0; i < test_params->bonded_slave_count; i++)
3614 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3616 /* Verify that pkts are not sent on slaves with link status down */
3619 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0) !=
3621 printf("generate_test_burst failed\n");
3625 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3626 burst_size) != (burst_size * slave_count)) {
3627 printf("rte_eth_tx_burst failed\n");
3631 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3632 if (port_stats.opackets != (uint64_t)(burst_size * slave_count)) {
3633 printf("(%d) port_stats.opackets (%d) not as expected (%d)\n",
3634 test_params->bonded_port_id, (int)port_stats.opackets,
3635 burst_size * slave_count);
3639 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3640 if (port_stats.opackets != (uint64_t)burst_size) {
3641 printf("(%d) port_stats.opackets not as expected\n",
3642 test_params->slave_port_ids[0]);
3646 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3647 if (port_stats.opackets != 0) {
3648 printf("(%d) port_stats.opackets not as expected\n",
3649 test_params->slave_port_ids[1]);
3653 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3654 if (port_stats.opackets != (uint64_t)burst_size) {
3655 printf("(%d) port_stats.opackets not as expected\n",
3656 test_params->slave_port_ids[2]);
3660 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3661 if (port_stats.opackets != 0) {
3662 printf("(%d) port_stats.opackets not as expected\n",
3663 test_params->slave_port_ids[3]);
3667 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3668 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0) !=
3673 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3674 &pkt_burst[i][0], burst_size);
3677 /* Verify that pkts are not received on slaves with link status down */
3679 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3681 burst_size + burst_size) {
3682 printf("rte_eth_rx_burst\n");
3686 /* Verify bonded device rx count */
3687 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3688 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
3689 printf("(%d) port_stats.ipackets not as expected\n",
3690 test_params->bonded_port_id);
3694 /* free mbufs allocate for rx testing */
3695 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3696 for (j = 0; j < MAX_PKT_BURST; j++) {
3697 if (pkt_burst[i][j] != NULL) {
3698 rte_pktmbuf_free(pkt_burst[i][j]);
3699 pkt_burst[i][j] = NULL;
3704 /* Clean up and remove slaves from bonded device */
3705 return remove_slaves_and_stop_bonded_device();
3709 test_reconfigure_bonded_device(void)
3711 test_params->nb_rx_q = 4;
3712 test_params->nb_tx_q = 4;
3714 if (configure_ethdev(test_params->bonded_port_id, 0) != 0) {
3715 printf("failed to reconfigure bonded device");
3720 test_params->nb_rx_q = 2;
3721 test_params->nb_tx_q = 2;
3723 if (configure_ethdev(test_params->bonded_port_id, 0) != 0) {
3724 printf("failed to reconfigure bonded device with less rx/tx queues");
3733 test_close_bonded_device(void)
3735 rte_eth_dev_close(test_params->bonded_port_id);
3740 testsuite_teardown(void)
3742 if (test_params->pkt_eth_hdr != NULL) {
3743 free(test_params->pkt_eth_hdr);
3744 test_params->pkt_eth_hdr = NULL;
3747 /* Clean up and remove slaves from bonded device */
3748 return remove_slaves_and_stop_bonded_device();
3752 static struct unit_test_suite link_bonding_test_suite = {
3753 .suite_name = "Link Bonding Unit Test Suite",
3754 .setup = test_setup,
3755 .teardown = testsuite_teardown,
3756 .unit_test_cases = {
3757 TEST_CASE(test_create_bonded_device),
3758 TEST_CASE(test_create_bonded_device_with_invalid_params),
3759 TEST_CASE(test_add_slave_to_bonded_device),
3760 TEST_CASE(test_add_slave_to_invalid_bonded_device),
3761 TEST_CASE(test_remove_slave_from_bonded_device),
3762 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
3763 TEST_CASE(test_get_slaves_from_bonded_device),
3764 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
3765 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
3766 TEST_CASE(test_start_bonded_device),
3767 TEST_CASE(test_stop_bonded_device),
3768 TEST_CASE(test_set_bonding_mode),
3769 TEST_CASE(test_set_primary_slave),
3770 TEST_CASE(test_set_explicit_bonded_mac),
3771 TEST_CASE(test_adding_slave_after_bonded_device_started),
3772 TEST_CASE(test_roundrobin_tx_burst),
3773 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
3774 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
3775 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
3776 TEST_CASE(test_roundrobin_verify_mac_assignment),
3777 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
3778 TEST_CASE(test_activebackup_tx_burst),
3779 TEST_CASE(test_activebackup_rx_burst),
3780 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
3781 TEST_CASE(test_activebackup_verify_mac_assignment),
3782 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
3783 TEST_CASE(test_balance_xmit_policy_configuration),
3784 TEST_CASE(test_balance_l2_tx_burst),
3785 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
3786 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
3787 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
3788 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
3789 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
3790 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
3791 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
3792 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
3793 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
3794 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
3795 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
3796 TEST_CASE(test_balance_rx_burst),
3797 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
3798 TEST_CASE(test_balance_verify_mac_assignment),
3799 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
3800 TEST_CASE(test_broadcast_tx_burst),
3801 TEST_CASE(test_broadcast_rx_burst),
3802 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
3803 TEST_CASE(test_broadcast_verify_mac_assignment),
3804 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
3805 TEST_CASE(test_reconfigure_bonded_device),
3806 TEST_CASE(test_close_bonded_device),
3808 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
3814 test_link_bonding(void)
3816 return unit_test_suite_runner(&link_bonding_test_suite);
3819 static struct test_command link_bonding_cmd = {
3820 .command = "link_bonding_autotest",
3821 .callback = test_link_bonding,
3823 REGISTER_TEST_COMMAND(link_bonding_cmd);