4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include <sys/queue.h>
44 #include <rte_byteorder.h>
45 #include <rte_common.h>
46 #include <rte_debug.h>
47 #include <rte_ethdev.h>
49 #include <rte_lcore.h>
50 #include <rte_memory.h>
51 #include <rte_string_fns.h>
52 #include <rte_eth_bond.h>
54 #include "virtual_pmd.h"
55 #include "packet_burst_generator.h"
59 #define TEST_MAX_NUMBER_OF_PORTS (16)
61 #define RX_RING_SIZE 128
62 #define RX_FREE_THRESH 32
67 #define TX_RING_SIZE 512
68 #define TX_FREE_THRESH 32
72 #define TX_RSBIT_THRESH 32
73 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
74 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
75 ETH_TXQ_FLAGS_NOXSUMTCP)
77 #define MBUF_PAYLOAD_SIZE (2048)
78 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
79 #define MBUF_CACHE_SIZE (250)
80 #define BURST_SIZE (32)
82 #define DEFAULT_MBUF_DATA_SIZE (2048)
83 #define RTE_TEST_RX_DESC_MAX (2048)
84 #define RTE_TEST_TX_DESC_MAX (2048)
85 #define MAX_PKT_BURST (512)
86 #define DEF_PKT_BURST (16)
88 #define BONDED_DEV_NAME ("unit_test_bonded_device")
90 #define INVALID_SOCKET_ID (-1)
91 #define INVALID_PORT_ID (-1)
92 #define INVALID_BONDING_MODE (-1)
95 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
96 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
98 struct link_bonding_unittest_params {
99 int8_t bonded_port_id;
100 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
101 uint8_t bonded_slave_count;
102 uint8_t bonding_mode;
107 struct rte_mempool *mbuf_pool;
109 struct ether_addr *default_slave_mac;
110 struct ether_addr *default_bonded_mac;
113 struct ether_hdr *pkt_eth_hdr;
114 struct ipv4_hdr *pkt_ipv4_hdr;
115 struct ipv6_hdr *pkt_ipv6_hdr;
116 struct udp_hdr *pkt_udp_hdr;
120 static struct ipv4_hdr pkt_ipv4_hdr;
121 static struct ipv6_hdr pkt_ipv6_hdr;
122 static struct udp_hdr pkt_udp_hdr;
124 static struct link_bonding_unittest_params default_params = {
125 .bonded_port_id = -1,
126 .slave_port_ids = { -1 },
127 .bonded_slave_count = 0,
128 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
135 .default_slave_mac = (struct ether_addr *)slave_mac,
136 .default_bonded_mac = (struct ether_addr *)bonded_mac,
139 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
140 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
141 .pkt_udp_hdr = &pkt_udp_hdr
145 static struct link_bonding_unittest_params *test_params = &default_params;
147 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
148 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
151 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
152 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
155 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
156 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
157 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
158 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
159 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
160 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
162 static uint16_t src_port = 1024;
163 static uint16_t dst_port_0 = 1024;
164 static uint16_t dst_port_1 = 2024;
166 static uint16_t vlan_id = 0x100;
168 struct rte_eth_rxmode rx_mode = {
169 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
171 .header_split = 0, /**< Header Split disabled. */
172 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
173 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
174 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
175 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
176 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
177 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
180 struct rte_fdir_conf fdir_conf = {
181 .mode = RTE_FDIR_MODE_NONE,
182 .pballoc = RTE_FDIR_PBALLOC_64K,
183 .status = RTE_FDIR_REPORT_STATUS,
184 .flexbytes_offset = 0x6,
188 static struct rte_eth_conf default_pmd_conf = {
190 .mq_mode = ETH_MQ_RX_NONE,
191 .max_rx_pkt_len = ETHER_MAX_LEN,
193 .header_split = 0, /**< Header Split disabled */
194 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
195 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
196 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
197 .hw_strip_crc = 0, /**< CRC stripped by hardware */
200 .mq_mode = ETH_MQ_TX_NONE,
205 static const struct rte_eth_rxconf rx_conf_default = {
207 .pthresh = RX_PTHRESH,
208 .hthresh = RX_HTHRESH,
209 .wthresh = RX_WTHRESH,
211 .rx_free_thresh = RX_FREE_THRESH,
215 static struct rte_eth_txconf tx_conf_default = {
217 .pthresh = TX_PTHRESH,
218 .hthresh = TX_HTHRESH,
219 .wthresh = TX_WTHRESH,
221 .tx_free_thresh = TX_FREE_THRESH,
222 .tx_rs_thresh = TX_RSBIT_THRESH,
223 .txq_flags = TX_Q_FLAGS
228 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
233 default_pmd_conf.intr_conf.lsc = 1;
235 default_pmd_conf.intr_conf.lsc = 0;
237 if (rte_eth_dev_configure(port_id, test_params->nb_rx_q,
238 test_params->nb_tx_q, &default_pmd_conf) != 0) {
242 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++) {
243 if (rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
244 rte_eth_dev_socket_id(port_id), &rx_conf_default,
245 test_params->mbuf_pool) < 0) {
250 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++) {
251 if (rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
252 rte_eth_dev_socket_id(port_id), &tx_conf_default) < 0) {
253 printf("Failed to setup tx queue (%d).\n", q_id);
259 if (rte_eth_dev_start(port_id) < 0) {
260 printf("Failed to start device (%d).\n", port_id);
267 printf("Failed to configure ethdev %d\n", port_id);
271 static int slaves_initialized;
276 int i, retval, nb_mbuf_per_pool;
277 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
279 /* Allocate ethernet packet header with space for VLAN header */
280 if (test_params->pkt_eth_hdr == NULL) {
281 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
282 sizeof(struct vlan_hdr));
284 if (test_params->pkt_eth_hdr == NULL) {
285 printf("ethernet header struct allocation failed!\n");
290 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
291 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
292 if (test_params->mbuf_pool == NULL) {
293 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
294 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
295 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
297 if (test_params->mbuf_pool == NULL) {
298 printf("rte_mempool_create failed\n");
303 /* Create / Initialize virtual eth devs */
304 if (!slaves_initialized) {
305 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
306 char pmd_name[RTE_ETH_NAME_MAX_LEN];
308 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
310 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
312 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
313 mac_addr, rte_socket_id());
314 if (test_params->slave_port_ids[i] < 0) {
315 printf("Failed to create virtual virtual ethdev %s\n", pmd_name);
319 printf("Created virtual ethdev %s\n", pmd_name);
321 retval = configure_ethdev(test_params->slave_port_ids[i], 1, 0);
323 printf("Failed to configure virtual ethdev %s\n", pmd_name);
327 printf("Configured virtual ethdev %s\n", pmd_name);
329 slaves_initialized = 1;
336 test_create_bonded_device(void)
338 int current_slave_count;
340 uint8_t slaves[RTE_MAX_ETHPORTS];
342 /* Don't try to recreate bonded device if re-running test suite*/
343 if (test_params->bonded_port_id == -1) {
344 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
345 test_params->bonding_mode, rte_socket_id());
347 TEST_ASSERT(test_params->bonded_port_id >= 0,
348 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
350 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
351 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
354 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
355 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
356 test_params->bonded_port_id, test_params->bonding_mode);
358 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
359 slaves, RTE_MAX_ETHPORTS);
361 TEST_ASSERT(current_slave_count == 0,
362 "Number of slaves %d is great than expected %d.",
363 current_slave_count, 0);
365 current_slave_count = rte_eth_bond_active_slaves_get(
366 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
368 TEST_ASSERT(current_slave_count == 0,
369 "Number of active slaves %d is great than expected %d.",
370 current_slave_count, 0);
377 test_create_bonded_device_with_invalid_params(void)
381 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
384 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
387 printf("Created bonded device unexpectedly.\n");
391 test_params->bonding_mode = INVALID_BONDING_MODE;
393 /* Invalid bonding mode */
394 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
397 printf("Created bonded device unexpectedly.\n");
401 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
403 /* Invalid socket id */
404 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
407 printf("Created bonded device unexpectedly.\n");
415 test_add_slave_to_bonded_device(void)
417 int retval, current_slave_count;
419 uint8_t slaves[RTE_MAX_ETHPORTS];
421 retval = rte_eth_bond_slave_add(test_params->bonded_port_id,
422 test_params->slave_port_ids[test_params->bonded_slave_count]);
424 printf("Failed to add slave (%d) to bonded port (%d).\n",
425 test_params->bonded_port_id,
426 test_params->slave_port_ids[test_params->bonded_slave_count]);
430 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
431 slaves, RTE_MAX_ETHPORTS);
432 if (current_slave_count != test_params->bonded_slave_count + 1) {
433 printf("Number of slaves (%d) is greater than expected (%d).\n",
434 current_slave_count, test_params->bonded_slave_count + 1);
438 current_slave_count = rte_eth_bond_active_slaves_get(
439 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
440 if (current_slave_count != 0) {
441 printf("Number of active slaves (%d) is not as expected (%d).\n",
442 current_slave_count, 0);
446 test_params->bonded_slave_count++;
452 test_add_slave_to_invalid_bonded_device(void)
456 /* Invalid port ID */
457 retval = rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
458 test_params->slave_port_ids[test_params->bonded_slave_count]);
460 printf("Expected call to failed as invalid port specified.\n");
464 /* Non bonded device */
465 retval = rte_eth_bond_slave_add(test_params->slave_port_ids[0],
466 test_params->slave_port_ids[test_params->bonded_slave_count]);
468 printf("Expected call to failed as invalid port specified.\n");
477 test_remove_slave_from_bonded_device(void)
479 int retval, current_slave_count;
480 struct ether_addr read_mac_addr, *mac_addr;
481 uint8_t slaves[RTE_MAX_ETHPORTS];
483 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id,
484 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
486 printf("\t Failed to remove slave %d from bonded port (%d).\n",
487 test_params->slave_port_ids[test_params->bonded_slave_count-1],
488 test_params->bonded_port_id);
493 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
494 slaves, RTE_MAX_ETHPORTS);
495 if (current_slave_count != test_params->bonded_slave_count - 1) {
496 printf("Number of slaves (%d) is great than expected (%d).\n",
497 current_slave_count, 0);
502 mac_addr = (struct ether_addr *)slave_mac;
503 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
504 test_params->slave_port_ids[test_params->bonded_slave_count-1];
507 test_params->slave_port_ids[test_params->bonded_slave_count-1],
509 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
510 printf("bonded port mac address not set to that of primary port\n");
515 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
517 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
520 test_params->bonded_slave_count--;
526 test_remove_slave_from_invalid_bonded_device(void)
530 /* Invalid port ID */
531 retval = rte_eth_bond_slave_remove(test_params->bonded_port_id + 5,
532 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
534 printf("Expected call to failed as invalid port specified.\n");
538 /* Non bonded device */
539 retval = rte_eth_bond_slave_remove(test_params->slave_port_ids[0],
540 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
542 printf("Expected call to failed as invalid port specified.\n");
549 static int bonded_id = 2;
552 test_add_already_bonded_slave_to_bonded_device(void)
554 int retval, port_id, current_slave_count;
555 uint8_t slaves[RTE_MAX_ETHPORTS];
556 char pmd_name[RTE_ETH_NAME_MAX_LEN];
558 test_add_slave_to_bonded_device();
560 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
561 slaves, RTE_MAX_ETHPORTS);
562 if (current_slave_count != 1) {
563 printf("Number of slaves (%d) is not that expected (%d).\n",
564 current_slave_count, 1);
568 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
570 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
573 printf("Failed to create bonded device.\n");
577 retval = rte_eth_bond_slave_add(port_id,
578 test_params->slave_port_ids[test_params->bonded_slave_count - 1]);
580 printf("Added slave (%d) to bonded port (%d) unexpectedly.\n",
581 test_params->slave_port_ids[test_params->bonded_slave_count-1],
586 return test_remove_slave_from_bonded_device();
591 test_get_slaves_from_bonded_device(void)
593 int retval, current_slave_count;
595 uint8_t slaves[RTE_MAX_ETHPORTS];
597 retval = test_add_slave_to_bonded_device();
601 /* Invalid port id */
602 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
604 if (current_slave_count >= 0)
607 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
608 slaves, RTE_MAX_ETHPORTS);
609 if (current_slave_count >= 0)
612 /* Invalid slaves pointer */
613 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
614 NULL, RTE_MAX_ETHPORTS);
615 if (current_slave_count >= 0)
618 current_slave_count = rte_eth_bond_active_slaves_get(
619 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
620 if (current_slave_count >= 0)
623 /* non bonded device*/
624 current_slave_count = rte_eth_bond_slaves_get(
625 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
626 if (current_slave_count >= 0)
629 current_slave_count = rte_eth_bond_active_slaves_get(
630 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
631 if (current_slave_count >= 0)
634 retval = test_remove_slave_from_bonded_device();
643 test_add_remove_multiple_slaves_to_from_bonded_device(void)
647 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
648 if (test_add_slave_to_bonded_device() != 0)
652 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
653 if (test_remove_slave_from_bonded_device() != 0)
661 enable_bonded_slaves(void)
665 for (i = 0; i < test_params->bonded_slave_count; i++) {
666 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
669 virtual_ethdev_simulate_link_status_interrupt(
670 test_params->slave_port_ids[i], 1);
675 test_start_bonded_device(void)
677 struct rte_eth_link link_status;
679 int current_slave_count, current_bonding_mode, primary_port;
680 uint8_t slaves[RTE_MAX_ETHPORTS];
682 /* Add slave to bonded device*/
683 if (test_add_slave_to_bonded_device() != 0)
686 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
687 "Failed to start bonded pmd eth device %d.",
688 test_params->bonded_port_id);
690 /* Change link status of virtual pmd so it will be added to the active
691 * slave list of the bonded device*/
692 virtual_ethdev_simulate_link_status_interrupt(
693 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
695 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
696 slaves, RTE_MAX_ETHPORTS);
697 if (current_slave_count != test_params->bonded_slave_count) {
698 printf("Number of slaves (%d) is not expected value (%d).\n",
699 current_slave_count, test_params->bonded_slave_count);
703 current_slave_count = rte_eth_bond_active_slaves_get(
704 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
705 if (current_slave_count != test_params->bonded_slave_count) {
706 printf("Number of active slaves (%d) is not expected value (%d).\n",
707 current_slave_count, test_params->bonded_slave_count);
711 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
712 if (current_bonding_mode != test_params->bonding_mode) {
713 printf("Bonded device mode (%d) is not expected value (%d).\n",
714 current_bonding_mode, test_params->bonding_mode);
719 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
720 if (primary_port != test_params->slave_port_ids[0]) {
721 printf("Primary port (%d) is not expected value (%d).\n",
722 primary_port, test_params->slave_port_ids[0]);
727 rte_eth_link_get(test_params->bonded_port_id, &link_status);
728 if (!link_status.link_status) {
729 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
730 test_params->bonded_port_id, link_status.link_status, 1);
739 test_stop_bonded_device(void)
741 int current_slave_count;
742 uint8_t slaves[RTE_MAX_ETHPORTS];
744 struct rte_eth_link link_status;
746 rte_eth_dev_stop(test_params->bonded_port_id);
748 rte_eth_link_get(test_params->bonded_port_id, &link_status);
749 if (link_status.link_status) {
750 printf("Bonded port (%d) status (%d) is not expected value (%d).\n",
751 test_params->bonded_port_id, link_status.link_status, 0);
755 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
756 slaves, RTE_MAX_ETHPORTS);
757 if (current_slave_count != test_params->bonded_slave_count) {
758 printf("Number of slaves (%d) is not expected value (%d).\n",
759 current_slave_count, test_params->bonded_slave_count);
763 current_slave_count = rte_eth_bond_active_slaves_get(
764 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
765 if (current_slave_count != 0) {
766 printf("Number of active slaves (%d) is not expected value (%d).\n",
767 current_slave_count, 0);
774 static int remove_slaves_and_stop_bonded_device(void)
776 /* Clean up and remove slaves from bonded device */
777 while (test_params->bonded_slave_count > 0) {
778 if (test_remove_slave_from_bonded_device() != 0) {
779 printf("test_remove_slave_from_bonded_device failed\n");
784 rte_eth_dev_stop(test_params->bonded_port_id);
785 rte_eth_stats_reset(test_params->bonded_port_id);
786 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
792 test_set_bonding_mode(void)
795 int retval, bonding_mode;
797 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
798 BONDING_MODE_ACTIVE_BACKUP,
799 BONDING_MODE_BALANCE,
800 #ifdef RTE_MBUF_REFCNT
801 BONDING_MODE_BROADCAST
805 /* Test supported link bonding modes */
806 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
807 /* Invalid port ID */
808 retval = rte_eth_bond_mode_set(INVALID_PORT_ID, bonding_modes[i]);
810 printf("Expected call to failed as invalid port (%d) specified.\n",
815 /* Non bonded device */
816 retval = rte_eth_bond_mode_set(test_params->slave_port_ids[0],
819 printf("Expected call to failed as invalid port (%d) specified.\n",
820 test_params->slave_port_ids[0]);
824 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
827 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
828 test_params->bonded_port_id, bonding_modes[i]);
832 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
833 if (bonding_mode != bonding_modes[i]) {
834 printf("Link bonding mode (%d) of port (%d) is not expected value (%d).\n",
835 bonding_mode, test_params->bonded_port_id,
841 /* Invalid port ID */
842 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
843 if (bonding_mode >= 0) {
844 printf("Expected call to failed as invalid port (%d) specified.\n",
850 /* Non bonded device */
851 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
852 if (bonding_mode >= 0) {
853 printf("Expected call to failed as invalid port (%d) specified.\n",
854 test_params->slave_port_ids[0]);
860 return remove_slaves_and_stop_bonded_device();
864 test_set_primary_slave(void)
867 struct ether_addr read_mac_addr;
868 struct ether_addr *expected_mac_addr;
870 /* Add 4 slaves to bonded device */
871 for (i = test_params->bonded_slave_count; i < 4; i++) {
872 retval = test_add_slave_to_bonded_device();
874 printf("Failed to add slave to bonded device.\n");
878 retval = rte_eth_bond_mode_set(test_params->bonded_port_id,
879 BONDING_MODE_ROUND_ROBIN);
881 printf("Failed to set link bonding mode on port (%d) to (%d).\n",
882 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
886 /* Invalid port ID */
887 retval = rte_eth_bond_primary_set(INVALID_PORT_ID,
888 test_params->slave_port_ids[i]);
890 printf("Expected call to failed as invalid port specified.\n");
894 /* Set slave as primary
895 * Verify slave it is now primary slave
896 * Verify that MAC address of bonded device is that of primary slave
897 * Verify that MAC address of all bonded slaves are that of primary slave
899 for (i = 0; i < 4; i++) {
901 /* Non bonded device */
902 retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
903 test_params->slave_port_ids[i]);
905 printf("Expected call to failed as invalid port specified.\n");
909 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
910 test_params->slave_port_ids[i]);
912 printf("Failed to set bonded port (%d) primary port to (%d)\n",
913 test_params->bonded_port_id,
914 test_params->slave_port_ids[i]);
918 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
920 printf("Failed to read primary port from bonded port (%d)\n",
921 test_params->bonded_port_id);
923 } else if (retval != test_params->slave_port_ids[i]) {
924 printf("Bonded port (%d) primary port (%d) not expected value (%d)\n",
925 test_params->bonded_port_id, retval,
926 test_params->slave_port_ids[i]);
930 /* stop/start bonded eth dev to apply new MAC */
931 rte_eth_dev_stop(test_params->bonded_port_id);
932 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
935 expected_mac_addr = (struct ether_addr *)&slave_mac;
936 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
937 test_params->slave_port_ids[i];
939 /* Check primary slave MAC */
940 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
941 if (memcmp(expected_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
942 printf("bonded port mac address not set to that of primary port\n");
946 /* Check bonded MAC */
947 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
948 if (memcmp(&read_mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
949 printf("bonded port mac address not set to that of primary port\n");
953 /* Check other slaves MACs */
954 for (j = 0; j < 4; j++) {
956 rte_eth_macaddr_get(test_params->slave_port_ids[j],
958 if (memcmp(expected_mac_addr, &read_mac_addr,
959 sizeof(read_mac_addr))) {
960 printf("slave port mac address not set to that of primary port\n");
968 /* Test with none existent port */
969 retval = rte_eth_bond_primary_get(test_params->bonded_port_id + 10);
971 printf("read primary port from expectedly\n");
975 /* Test with slave port */
976 retval = rte_eth_bond_primary_get(test_params->slave_port_ids[0]);
978 printf("read primary port from expectedly\n");
982 if (remove_slaves_and_stop_bonded_device() != 0)
986 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
988 printf("read primary port from expectedly\n");
996 test_set_explicit_bonded_mac(void)
999 struct ether_addr read_mac_addr;
1000 struct ether_addr *mac_addr;
1002 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
1004 mac_addr = (struct ether_addr *)explicit_bonded_mac;
1006 /* Invalid port ID */
1007 retval = rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr);
1009 printf("Expected call to failed as invalid port specified.\n");
1013 /* Non bonded device */
1014 retval = rte_eth_bond_mac_address_set(test_params->slave_port_ids[0],
1017 printf("Expected call to failed as invalid port specified.\n");
1021 /* NULL MAC address */
1022 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id, NULL);
1024 printf("Expected call to failed as NULL MAC specified\n");
1028 retval = rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1031 printf("Failed to set MAC address on bonded port (%d)\n",
1032 test_params->bonded_port_id);
1036 /* Add 4 slaves to bonded device */
1037 for (i = test_params->bonded_slave_count; i < 4; i++) {
1038 retval = test_add_slave_to_bonded_device();
1040 printf("Failed to add slave to bonded device.\n");
1045 /* Check bonded MAC */
1046 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1047 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1048 printf("bonded port mac address not set to that of primary port\n");
1052 /* Check other slaves MACs */
1053 for (i = 0; i < 4; i++) {
1054 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1055 if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
1056 printf("slave port mac address not set to that of primary port\n");
1061 /* test resetting mac address on bonded device */
1062 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1063 printf("Failed to reset MAC address on bonded port (%d)\n",
1064 test_params->bonded_port_id);
1069 if (rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]) == 0) {
1070 printf("Reset MAC address on bonded port (%d) unexpectedly\n",
1071 test_params->slave_port_ids[1]);
1076 /* test resetting mac address on bonded device with no slaves */
1078 if (remove_slaves_and_stop_bonded_device() != 0)
1081 if (rte_eth_bond_mac_address_reset(test_params->bonded_port_id) != 0) {
1082 printf("Failed to reset MAC address on bonded port (%d)\n",
1083 test_params->bonded_port_id);
1093 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1094 uint8_t number_of_slaves, uint8_t enable_slave)
1096 /* configure bonded device */
1097 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1098 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1099 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1102 while (number_of_slaves > test_params->bonded_slave_count) {
1103 /* Add slaves to bonded device */
1104 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1105 "Failed to add slave (%d to bonding port (%d).",
1106 test_params->bonded_slave_count - 1,
1107 test_params->bonded_port_id);
1110 /* Set link bonding mode */
1111 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1113 "Failed to set link bonding mode on port (%d) to (%d).",
1114 test_params->bonded_port_id, bonding_mode);
1116 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1117 "Failed to start bonded pmd eth device %d.",
1118 test_params->bonded_port_id);
1121 enable_bonded_slaves();
1127 test_adding_slave_after_bonded_device_started(void)
1131 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 0)
1135 /* Enabled slave devices */
1136 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1137 virtual_ethdev_simulate_link_status_interrupt(
1138 test_params->slave_port_ids[i], 1);
1141 if (rte_eth_bond_slave_add(test_params->bonded_port_id,
1142 test_params->slave_port_ids[test_params->bonded_slave_count]) !=
1144 printf("\t Failed to add slave to bonded port.\n");
1148 rte_eth_stats_reset(
1149 test_params->slave_port_ids[test_params->bonded_slave_count]);
1151 test_params->bonded_slave_count++;
1153 return remove_slaves_and_stop_bonded_device();
1156 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1157 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1159 int test_lsc_interrupt_count;
1161 static pthread_mutex_t mutex;
1162 static pthread_cond_t cvar;
1165 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1166 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1168 pthread_mutex_lock(&mutex);
1169 test_lsc_interrupt_count++;
1171 pthread_cond_signal(&cvar);
1172 pthread_mutex_unlock(&mutex);
1176 lsc_timeout(int wait_us)
1183 gettimeofday(&tp, NULL);
1185 /* Convert from timeval to timespec */
1186 ts.tv_sec = tp.tv_sec;
1187 ts.tv_nsec = tp.tv_usec * 1000;
1188 ts.tv_nsec += wait_us * 1000;
1190 pthread_mutex_lock(&mutex);
1191 if (test_lsc_interrupt_count < 1)
1192 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1194 pthread_mutex_unlock(&mutex);
1200 test_status_interrupt(void)
1203 uint8_t slaves[RTE_MAX_ETHPORTS];
1205 pthread_mutex_init(&mutex, NULL);
1206 pthread_cond_init(&cvar, NULL);
1208 /* initialized bonding device with T slaves */
1209 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 1,
1210 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1) != 0)
1213 test_lsc_interrupt_count = 0;
1215 /* register link status change interrupt callback */
1216 rte_eth_dev_callback_register(test_params->bonded_port_id,
1217 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1218 &test_params->bonded_port_id);
1220 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1221 slaves, RTE_MAX_ETHPORTS);
1223 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1224 "Number of active slaves (%d) is not as expected (%d)",
1225 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1227 /* Bring all 4 slaves link status to down and test that we have received a
1229 virtual_ethdev_simulate_link_status_interrupt(
1230 test_params->slave_port_ids[0], 0);
1231 virtual_ethdev_simulate_link_status_interrupt(
1232 test_params->slave_port_ids[1], 0);
1233 virtual_ethdev_simulate_link_status_interrupt(
1234 test_params->slave_port_ids[2], 0);
1236 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1237 "Received a link status change interrupt unexpectedly");
1239 virtual_ethdev_simulate_link_status_interrupt(
1240 test_params->slave_port_ids[3], 0);
1242 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1243 "timed out waiting for interrupt");
1245 TEST_ASSERT(test_lsc_interrupt_count > 0,
1246 "Did not receive link status change interrupt");
1248 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1249 slaves, RTE_MAX_ETHPORTS);
1251 TEST_ASSERT_EQUAL(slave_count, 0,
1252 "Number of active slaves (%d) is not as expected (%d)",
1255 /* bring one slave port up so link status will change */
1256 test_lsc_interrupt_count = 0;
1258 virtual_ethdev_simulate_link_status_interrupt(
1259 test_params->slave_port_ids[0], 1);
1261 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1262 "timed out waiting for interrupt");
1264 /* test that we have received another lsc interrupt */
1265 TEST_ASSERT(test_lsc_interrupt_count > 0,
1266 "Did not receive link status change interrupt");
1268 /* Verify that calling the same slave lsc interrupt doesn't cause another
1269 * lsc interrupt from bonded device */
1270 test_lsc_interrupt_count = 0;
1272 virtual_ethdev_simulate_link_status_interrupt(
1273 test_params->slave_port_ids[0], 1);
1275 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1276 "received unexpected interrupt");
1278 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1279 "Did not receive link status change interrupt");
1282 /* unregister lsc callback before exiting */
1283 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1284 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1285 &test_params->bonded_port_id);
1287 pthread_mutex_destroy(&mutex);
1288 pthread_cond_destroy(&cvar);
1290 /* Clean up and remove slaves from bonded device */
1291 return remove_slaves_and_stop_bonded_device();
1295 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1296 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1297 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1299 uint16_t pktlen, generated_burst_size;
1303 initialize_eth_header(test_params->pkt_eth_hdr,
1304 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1307 initialize_eth_header(test_params->pkt_eth_hdr,
1308 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1312 if (toggle_udp_port)
1313 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1316 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1321 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1322 dst_addr_1, pktlen);
1324 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1325 dst_addr_0, pktlen);
1327 ip_hdr = test_params->pkt_ipv4_hdr;
1330 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1331 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1334 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1335 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1338 ip_hdr = test_params->pkt_ipv6_hdr;
1341 /* Generate burst of packets to transmit */
1342 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1343 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1344 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1346 if (generated_burst_size != burst_size) {
1347 printf("Failed to generate packet burst");
1351 return generated_burst_size;
1354 /** Round Robin Mode Tests */
1357 test_roundrobin_tx_burst(void)
1359 int i, burst_size, nb_tx;
1360 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1361 struct rte_eth_stats port_stats;
1363 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 2, 1)
1367 burst_size = 20 * test_params->bonded_slave_count;
1369 if (burst_size > MAX_PKT_BURST) {
1370 printf("Burst size specified is greater than supported.\n");
1374 /* Generate test bursts of packets to transmit */
1375 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size)
1378 /* Send burst on bonded port */
1379 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1381 if (nb_tx != burst_size)
1384 /* Verify bonded port tx stats */
1385 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1386 if (port_stats.opackets != (uint64_t)burst_size) {
1387 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1388 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1393 /* Verify slave ports tx stats */
1394 for (i = 0; i < test_params->bonded_slave_count; i++) {
1395 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1396 if (port_stats.opackets !=
1397 (uint64_t)burst_size / test_params->bonded_slave_count) {
1398 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1399 test_params->bonded_port_id,
1400 (unsigned int)port_stats.opackets,
1401 burst_size / test_params->bonded_slave_count);
1406 /* Put all slaves down and try and transmit */
1407 for (i = 0; i < test_params->bonded_slave_count; i++) {
1408 virtual_ethdev_simulate_link_status_interrupt(
1409 test_params->slave_port_ids[i], 0);
1412 /* Send burst on bonded port */
1413 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1418 /* Clean up and remove slaves from bonded device */
1419 return remove_slaves_and_stop_bonded_device();
1423 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1427 for (i = 0; i < nb_mbufs; i++) {
1428 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1429 TEST_ASSERT_EQUAL(refcnt, val,
1430 "mbuf ref count (%d)is not the expected value (%d)",
1438 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1442 for (i = 0; i < nb_mbufs; i++)
1443 rte_pktmbuf_free(mbufs[i]);
1446 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1447 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1448 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1449 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1452 test_roundrobin_tx_burst_slave_tx_fail(void)
1454 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1455 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1457 struct rte_eth_stats port_stats;
1459 int i, first_fail_idx, tx_count;
1461 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1462 BONDING_MODE_ROUND_ROBIN, 0,
1463 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1464 "Failed to intialise bonded device");
1466 /* Generate test bursts of packets to transmit */
1467 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1468 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1469 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1470 "Failed to generate test packet burst");
1472 /* Copy references to packets which we expect not to be transmitted */
1473 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1474 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1475 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1476 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1478 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1479 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1480 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1483 /* Set virtual slave to only fail transmission of
1484 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1485 virtual_ethdev_tx_burst_fn_set_success(
1486 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1489 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1490 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1491 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1493 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1494 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1496 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1497 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1498 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1499 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1500 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1502 /* Verify that failed packet are expected failed packets */
1503 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1504 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1505 "expected mbuf (%d) pointer %p not expected pointer %p",
1506 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1509 /* Verify bonded port tx stats */
1510 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1512 TEST_ASSERT_EQUAL(port_stats.opackets,
1513 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1514 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1515 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1516 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1517 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1518 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1520 /* Verify slave ports tx stats */
1521 for (i = 0; i < test_params->bonded_slave_count; i++) {
1522 int slave_expected_tx_count;
1524 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1526 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1527 test_params->bonded_slave_count;
1529 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1530 slave_expected_tx_count = slave_expected_tx_count -
1531 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1533 TEST_ASSERT_EQUAL(port_stats.opackets,
1534 (uint64_t)slave_expected_tx_count,
1535 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1536 test_params->slave_port_ids[i],
1537 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1540 /* Verify that all mbufs have a ref value of zero */
1541 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1542 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1543 "mbufs refcnts not as expected");
1545 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1547 /* Clean up and remove slaves from bonded device */
1548 return remove_slaves_and_stop_bonded_device();
1552 test_roundrobin_rx_burst_on_single_slave(void)
1554 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1555 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1557 struct rte_eth_stats port_stats;
1559 int i, j, nb_rx, burst_size = 25;
1561 /* Initialize bonded device with 4 slaves in round robin mode */
1562 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1566 /* Generate test bursts of packets to transmit */
1567 if (generate_test_burst(gen_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1571 for (i = 0; i < test_params->bonded_slave_count; i++) {
1572 /* Add rx data to slave */
1573 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1574 &gen_pkt_burst[0], burst_size);
1576 /* Call rx burst on bonded device */
1577 /* Send burst on bonded port */
1578 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1580 if (nb_rx != burst_size) {
1581 printf("round-robin rx burst failed");
1585 /* Verify bonded device rx count */
1586 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1587 if (port_stats.ipackets != (uint64_t)burst_size) {
1588 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1589 test_params->bonded_port_id,
1590 (unsigned int)port_stats.ipackets, burst_size);
1595 /* Verify bonded slave devices rx count */
1596 /* Verify slave ports tx stats */
1597 for (j = 0; j < test_params->bonded_slave_count; j++) {
1598 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1601 if (port_stats.ipackets != (uint64_t)burst_size) {
1602 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1603 test_params->slave_port_ids[i],
1604 (unsigned int)port_stats.ipackets, burst_size);
1608 if (port_stats.ipackets != 0) {
1609 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1610 test_params->slave_port_ids[i],
1611 (unsigned int)port_stats.ipackets, 0);
1616 /* Reset bonded slaves stats */
1617 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1619 /* reset bonded device stats */
1620 rte_eth_stats_reset(test_params->bonded_port_id);
1624 for (i = 0; i < MAX_PKT_BURST; i++) {
1625 if (gen_pkt_burst[i] != NULL)
1626 rte_pktmbuf_free(gen_pkt_burst[i]);
1628 if (rx_pkt_burst[i] != NULL)
1629 rte_pktmbuf_free(rx_pkt_burst[i]);
1633 /* Clean up and remove slaves from bonded device */
1634 return remove_slaves_and_stop_bonded_device();
1637 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1640 test_roundrobin_rx_burst_on_multiple_slaves(void)
1642 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1644 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1645 struct rte_eth_stats port_stats;
1647 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1651 /* Initialize bonded device with 4 slaves in round robin mode */
1652 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1656 /* Generate test bursts of packets to transmit */
1657 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1658 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0,
1659 0) != burst_size[i])
1663 /* Add rx data to slaves */
1664 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1665 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1666 &gen_pkt_burst[i][0], burst_size[i]);
1669 /* Call rx burst on bonded device */
1670 /* Send burst on bonded port */
1671 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1673 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
1674 printf("round-robin rx burst failed (%d != %d)\n", nb_rx,
1675 burst_size[0] + burst_size[1] + burst_size[2]);
1679 /* Verify bonded device rx count */
1680 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1681 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
1683 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
1684 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1685 burst_size[0] + burst_size[1] + burst_size[2]);
1690 /* Verify bonded slave devices rx counts */
1691 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1692 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
1693 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1694 test_params->slave_port_ids[0],
1695 (unsigned int)port_stats.ipackets, burst_size[0]);
1699 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1700 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
1701 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1702 test_params->slave_port_ids[1],
1703 (unsigned int)port_stats.ipackets, burst_size[1]);
1707 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1708 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
1709 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1710 test_params->slave_port_ids[2],
1711 (unsigned int)port_stats.ipackets, burst_size[2]);
1715 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1716 if (port_stats.ipackets != 0) {
1717 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
1718 test_params->slave_port_ids[3],
1719 (unsigned int)port_stats.ipackets, 0);
1724 for (i = 0; i < MAX_PKT_BURST; i++) {
1725 if (rx_pkt_burst[i] != NULL)
1726 rte_pktmbuf_free(rx_pkt_burst[i]);
1729 /* Clean up and remove slaves from bonded device */
1730 return remove_slaves_and_stop_bonded_device();
1734 test_roundrobin_verify_mac_assignment(void)
1736 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1740 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1741 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1743 /* Initialize bonded device with 4 slaves in round robin mode */
1744 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1)
1748 /* Verify that all MACs are the same as first slave added to bonded dev */
1749 for (i = 0; i < test_params->bonded_slave_count; i++) {
1750 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1751 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1752 sizeof(read_mac_addr))) {
1753 printf("slave port (%d) mac address not set to that of primary port\n",
1754 test_params->slave_port_ids[i]);
1759 /* change primary and verify that MAC addresses haven't changed */
1760 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
1761 test_params->slave_port_ids[2]);
1763 printf("Failed to set bonded port (%d) primary port to (%d)\n",
1764 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1768 for (i = 0; i < test_params->bonded_slave_count; i++) {
1769 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1770 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
1771 sizeof(read_mac_addr))) {
1772 printf("slave port (%d) mac address has changed to that of primary port without stop/start toggle of bonded device\n",
1773 test_params->slave_port_ids[i]);
1778 /* stop / start bonded device and verify that primary MAC address is
1779 * propagate to bonded device and slaves */
1781 rte_eth_dev_stop(test_params->bonded_port_id);
1783 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
1786 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1787 if (memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr))) {
1788 printf("bonded port (%d) mac address not set to that of new primary port\n",
1789 test_params->slave_port_ids[i]);
1793 for (i = 0; i < test_params->bonded_slave_count; i++) {
1794 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1795 if (memcmp(&expected_mac_addr_2, &read_mac_addr,
1796 sizeof(read_mac_addr))) {
1797 printf("slave port (%d) mac address not set to that of new primary port\n",
1798 test_params->slave_port_ids[i]);
1803 /* Set explicit MAC address */
1804 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
1805 (struct ether_addr *)bonded_mac) != 0) {
1809 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1810 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1811 printf("bonded port (%d) mac address not set to that of new primary port\n",
1812 test_params->slave_port_ids[i]);
1816 for (i = 0; i < test_params->bonded_slave_count; i++) {
1817 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1818 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
1819 printf("slave port (%d) mac address not set to that of new primary port\n",
1820 test_params->slave_port_ids[i]);
1825 /* Clean up and remove slaves from bonded device */
1826 return remove_slaves_and_stop_bonded_device();
1830 test_roundrobin_verify_promiscuous_enable_disable(void)
1832 int i, promiscuous_en;
1834 /* Initialize bonded device with 4 slaves in round robin mode */
1835 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 1) !=
1839 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1841 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1842 if (promiscuous_en != 1) {
1843 printf("Port (%d) promiscuous mode not enabled\n",
1844 test_params->bonded_port_id);
1848 for (i = 0; i < test_params->bonded_slave_count; i++) {
1849 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1850 if (promiscuous_en != 1) {
1851 printf("slave port (%d) promiscuous mode not enabled\n",
1852 test_params->slave_port_ids[i]);
1857 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1859 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1860 if (promiscuous_en != 0) {
1861 printf("Port (%d) promiscuous mode not disabled\n",
1862 test_params->bonded_port_id);
1866 for (i = 0; i < test_params->bonded_slave_count; i++) {
1867 promiscuous_en = rte_eth_promiscuous_get(test_params->slave_port_ids[i]);
1868 if (promiscuous_en != 0) {
1869 printf("slave port (%d) promiscuous mode not disabled\n",
1870 test_params->slave_port_ids[i]);
1875 /* Clean up and remove slaves from bonded device */
1876 return remove_slaves_and_stop_bonded_device();
1879 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1880 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1883 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1885 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1886 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1887 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1889 struct rte_eth_stats port_stats;
1890 uint8_t slaves[RTE_MAX_ETHPORTS];
1892 int i, burst_size, slave_count;
1894 /* NULL all pointers in array to simplify cleanup */
1895 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1897 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1898 * in round robin mode */
1899 if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0,
1900 TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
1903 /* Verify Current Slaves Count /Active Slave Count is */
1904 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1906 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1907 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
1908 TEST_RR_LINK_STATUS_SLAVE_COUNT);
1912 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1913 slaves, RTE_MAX_ETHPORTS);
1914 if (slave_count != TEST_RR_LINK_STATUS_SLAVE_COUNT) {
1915 printf("Number of active slaves (%d) is not as expected (%d).\n",
1916 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1920 /* Set 2 slaves eth_devs link status to down */
1921 virtual_ethdev_simulate_link_status_interrupt(
1922 test_params->slave_port_ids[1], 0);
1923 virtual_ethdev_simulate_link_status_interrupt(
1924 test_params->slave_port_ids[3], 0);
1926 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1927 slaves, RTE_MAX_ETHPORTS) !=
1928 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) {
1929 printf("Number of active slaves (%d) is not as expected (%d).\n",
1930 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1936 /* Verify that pkts are not sent on slaves with link status down:
1938 * 1. Generate test burst of traffic
1939 * 2. Transmit burst on bonded eth_dev
1940 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1941 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1943 if (generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0) !=
1945 printf("generate_test_burst failed\n");
1949 rte_eth_stats_reset(test_params->bonded_port_id);
1951 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1952 burst_size) != burst_size) {
1953 printf("rte_eth_tx_burst failed\n");
1957 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1958 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1959 "Port (%d) opackets stats (%d) not expected (%d) value",
1960 test_params->bonded_port_id, (int)port_stats.opackets,
1963 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1964 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1965 "Port (%d) opackets stats (%d) not expected (%d) value",
1966 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1968 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1969 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1970 "Port (%d) opackets stats (%d) not expected (%d) value",
1971 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1973 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1974 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1975 "Port (%d) opackets stats (%d) not expected (%d) value",
1976 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1978 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1979 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1980 "Port (%d) opackets stats (%d) not expected (%d) value",
1981 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1983 /* Verify that pkts are not sent on slaves with link status down:
1985 * 1. Generate test bursts of traffic
1986 * 2. Add bursts on to virtual eth_devs
1987 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1988 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1989 * 4. Verify stats for bonded eth_dev
1990 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1992 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1993 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0)
1997 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1998 &gen_pkt_burst[i][0], burst_size);
2001 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2002 MAX_PKT_BURST) != burst_size + burst_size) {
2003 printf("rte_eth_rx_burst\n");
2007 /* Verify bonded device rx count */
2008 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2009 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
2010 printf("(%d) port_stats.ipackets not as expected\n",
2011 test_params->bonded_port_id);
2016 for (i = 0; i < MAX_PKT_BURST; i++) {
2017 if (rx_pkt_burst[i] != NULL)
2018 rte_pktmbuf_free(rx_pkt_burst[i]);
2020 if (gen_pkt_burst[1][i] != NULL)
2021 rte_pktmbuf_free(gen_pkt_burst[1][i]);
2023 if (gen_pkt_burst[3][i] != NULL)
2024 rte_pktmbuf_free(gen_pkt_burst[1][i]);
2027 /* Clean up and remove slaves from bonded device */
2028 return remove_slaves_and_stop_bonded_device();
2031 /** Active Backup Mode Tests */
2034 test_activebackup_tx_burst(void)
2036 int i, retval, pktlen, primary_port, burst_size, generated_burst_size, nb_tx;
2037 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2038 struct rte_eth_stats port_stats;
2040 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1);
2042 printf("Failed to initialize_bonded_device_with_slaves.\n");
2046 initialize_eth_header(test_params->pkt_eth_hdr,
2047 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2048 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2050 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2051 dst_addr_0, pktlen);
2053 burst_size = 20 * test_params->bonded_slave_count;
2055 if (burst_size > MAX_PKT_BURST) {
2056 printf("Burst size specified is greater than supported.\n");
2060 /* Generate a burst of packets to transmit */
2061 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
2062 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
2063 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1);
2064 if (generated_burst_size != burst_size)
2067 /* Send burst on bonded port */
2068 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2070 if (nb_tx != burst_size)
2073 /* Verify bonded port tx stats */
2074 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2075 if (port_stats.opackets != (uint64_t)burst_size) {
2076 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2077 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2082 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2084 /* Verify slave ports tx stats */
2085 for (i = 0; i < test_params->bonded_slave_count; i++) {
2086 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2087 if (test_params->slave_port_ids[i] == primary_port) {
2088 if (port_stats.opackets != (uint64_t)burst_size) {
2089 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2090 test_params->bonded_port_id,
2091 (unsigned int)port_stats.opackets,
2092 burst_size / test_params->bonded_slave_count);
2096 if (port_stats.opackets != 0) {
2097 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2098 test_params->bonded_port_id,
2099 (unsigned int)port_stats.opackets, 0);
2105 /* Put all slaves down and try and transmit */
2106 for (i = 0; i < test_params->bonded_slave_count; i++) {
2108 virtual_ethdev_simulate_link_status_interrupt(
2109 test_params->slave_port_ids[i], 0);
2112 /* Send burst on bonded port */
2113 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2118 /* Clean up and remove slaves from bonded device */
2119 return remove_slaves_and_stop_bonded_device();
2122 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2125 test_activebackup_rx_burst(void)
2127 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2128 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2130 struct rte_eth_stats port_stats;
2134 int i, j, nb_rx, burst_size = 17;
2136 /* Initialize bonded device with 4 slaves in round robin mode */
2137 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2138 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2143 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2144 if (primary_port < 0) {
2145 printf("failed to get primary slave for bonded port (%d)",
2146 test_params->bonded_port_id);
2149 for (i = 0; i < test_params->bonded_slave_count; i++) {
2150 /* Generate test bursts of packets to transmit */
2151 if (generate_test_burst(&gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0)
2156 /* Add rx data to slave */
2157 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2158 &gen_pkt_burst[0], burst_size);
2160 /* Call rx burst on bonded device */
2161 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
2162 &rx_pkt_burst[0], MAX_PKT_BURST);
2164 printf("rte_eth_rx_burst failed\n");
2168 if (test_params->slave_port_ids[i] == primary_port) {
2169 /* Verify bonded device rx count */
2170 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2171 if (port_stats.ipackets != (uint64_t)burst_size) {
2172 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
2173 test_params->bonded_port_id,
2174 (unsigned int)port_stats.ipackets, burst_size);
2178 /* Verify bonded slave devices rx count */
2179 for (j = 0; j < test_params->bonded_slave_count; j++) {
2180 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2182 if (port_stats.ipackets != (uint64_t)burst_size) {
2183 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2184 test_params->slave_port_ids[i],
2185 (unsigned int)port_stats.ipackets, burst_size);
2189 if (port_stats.ipackets != 0) {
2190 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2191 test_params->slave_port_ids[i],
2192 (unsigned int)port_stats.ipackets, 0);
2198 for (j = 0; j < test_params->bonded_slave_count; j++) {
2199 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2200 if (port_stats.ipackets != 0) {
2201 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
2202 test_params->slave_port_ids[i],
2203 (unsigned int)port_stats.ipackets, 0);
2210 for (i = 0; i < MAX_PKT_BURST; i++) {
2211 if (rx_pkt_burst[i] != NULL) {
2212 rte_pktmbuf_free(rx_pkt_burst[i]);
2213 rx_pkt_burst[i] = NULL;
2217 /* reset bonded device stats */
2218 rte_eth_stats_reset(test_params->bonded_port_id);
2221 /* Clean up and remove slaves from bonded device */
2222 return remove_slaves_and_stop_bonded_device();
2226 test_activebackup_verify_promiscuous_enable_disable(void)
2228 int i, primary_port, promiscuous_en;
2230 /* Initialize bonded device with 4 slaves in round robin mode */
2231 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1)
2235 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2236 if (primary_port < 0) {
2237 printf("failed to get primary slave for bonded port (%d)",
2238 test_params->bonded_port_id);
2241 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2243 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2244 if (promiscuous_en != 1) {
2245 printf("Port (%d) promiscuous mode not enabled\n",
2246 test_params->bonded_port_id);
2250 for (i = 0; i < test_params->bonded_slave_count; i++) {
2251 promiscuous_en = rte_eth_promiscuous_get(
2252 test_params->slave_port_ids[i]);
2253 if (primary_port == test_params->slave_port_ids[i]) {
2254 if (promiscuous_en != 1) {
2255 printf("slave port (%d) promiscuous mode not enabled\n",
2256 test_params->slave_port_ids[i]);
2260 if (promiscuous_en != 0) {
2261 printf("slave port (%d) promiscuous mode enabled\n",
2262 test_params->slave_port_ids[i]);
2269 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2271 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
2272 if (promiscuous_en != 0) {
2273 printf("Port (%d) promiscuous mode not disabled\n",
2274 test_params->bonded_port_id);
2278 for (i = 0; i < test_params->bonded_slave_count; i++) {
2279 promiscuous_en = rte_eth_promiscuous_get(
2280 test_params->slave_port_ids[i]);
2281 if (promiscuous_en != 0) {
2282 printf("slave port (%d) promiscuous mode not disabled\n",
2283 test_params->slave_port_ids[i]);
2288 /* Clean up and remove slaves from bonded device */
2289 return remove_slaves_and_stop_bonded_device();
2293 test_activebackup_verify_mac_assignment(void)
2295 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2297 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2298 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2300 /* Initialize bonded device with 2 slaves in active backup mode */
2301 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1)
2305 /* Verify that bonded MACs is that of first slave and that the other slave
2306 * MAC hasn't been changed */
2307 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2308 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2309 printf("bonded port (%d) mac address not set to that of primary port\n",
2310 test_params->bonded_port_id);
2314 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2315 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2316 printf("slave port (%d) mac address not set to that of primary port\n",
2317 test_params->slave_port_ids[0]);
2321 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2322 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2323 printf("slave port (%d) mac address not as expected\n",
2324 test_params->slave_port_ids[1]);
2328 /* change primary and verify that MAC addresses haven't changed */
2329 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
2330 test_params->slave_port_ids[1]) != 0) {
2331 printf("Failed to set bonded port (%d) primary port to (%d)\n",
2332 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2336 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2337 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2338 printf("bonded port (%d) mac address not set to that of primary port\n",
2339 test_params->bonded_port_id);
2343 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2344 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2345 printf("slave port (%d) mac address not set to that of primary port\n",
2346 test_params->slave_port_ids[0]);
2350 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2351 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2352 printf("slave port (%d) mac address not as expected\n",
2353 test_params->slave_port_ids[1]);
2357 /* stop / start bonded device and verify that primary MAC address is
2358 * propagated to bonded device and slaves */
2360 rte_eth_dev_stop(test_params->bonded_port_id);
2362 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
2365 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2366 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2367 printf("bonded port (%d) mac address not set to that of primary port\n",
2368 test_params->bonded_port_id);
2372 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2373 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2374 printf("slave port (%d) mac address not as expected\n",
2375 test_params->slave_port_ids[0]);
2379 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2380 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
2381 printf("slave port (%d) mac address not set to that of primary port\n",
2382 test_params->slave_port_ids[1]);
2386 /* Set explicit MAC address */
2387 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
2388 (struct ether_addr *)bonded_mac) != 0) {
2392 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2393 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2394 printf("bonded port (%d) mac address not set to that of bonded port\n",
2395 test_params->bonded_port_id);
2399 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2400 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
2401 printf("slave port (%d) mac address not as expected\n",
2402 test_params->slave_port_ids[0]);
2406 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2407 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
2408 printf("slave port (%d) mac address not set to that of bonded port\n",
2409 test_params->slave_port_ids[1]);
2413 /* Clean up and remove slaves from bonded device */
2414 return remove_slaves_and_stop_bonded_device();
2418 test_activebackup_verify_slave_link_status_change_failover(void)
2420 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2421 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2422 struct rte_eth_stats port_stats;
2424 uint8_t slaves[RTE_MAX_ETHPORTS];
2426 int i, j, burst_size, slave_count, primary_port;
2430 memset(pkt_burst, 0, sizeof(pkt_burst));
2432 /* Generate packet burst for testing */
2433 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
2435 printf("generate_test_burst failed\n");
2439 /* Initialize bonded device with 4 slaves in round robin mode */
2440 if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2441 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
2445 /* Verify Current Slaves Count /Active Slave Count is */
2446 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2448 if (slave_count != 4) {
2449 printf("Number of slaves (%d) is not as expected (%d).\n",
2454 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2455 slaves, RTE_MAX_ETHPORTS);
2456 if (slave_count != 4) {
2457 printf("Number of active slaves (%d) is not as expected (%d).\n",
2462 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2463 if (primary_port != test_params->slave_port_ids[0])
2464 printf("Primary port not as expected");
2466 /* Bring 2 slaves down and verify active slave count */
2467 virtual_ethdev_simulate_link_status_interrupt(
2468 test_params->slave_port_ids[1], 0);
2469 virtual_ethdev_simulate_link_status_interrupt(
2470 test_params->slave_port_ids[3], 0);
2472 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2473 RTE_MAX_ETHPORTS) != 2) {
2474 printf("Number of active slaves (%d) is not as expected (%d).\n",
2479 virtual_ethdev_simulate_link_status_interrupt(
2480 test_params->slave_port_ids[1], 1);
2481 virtual_ethdev_simulate_link_status_interrupt(
2482 test_params->slave_port_ids[3], 1);
2485 /* Bring primary port down, verify that active slave count is 3 and primary
2487 virtual_ethdev_simulate_link_status_interrupt(
2488 test_params->slave_port_ids[0], 0);
2490 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
2491 RTE_MAX_ETHPORTS) != 3) {
2492 printf("Number of active slaves (%d) is not as expected (%d).\n",
2497 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2498 if (primary_port != test_params->slave_port_ids[2])
2499 printf("Primary port not as expected");
2501 /* Verify that pkts are sent on new primary slave */
2503 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size)
2505 printf("rte_eth_tx_burst failed\n");
2509 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2510 if (port_stats.opackets != (uint64_t)burst_size) {
2511 printf("(%d) port_stats.opackets not as expected\n",
2512 test_params->slave_port_ids[2]);
2516 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2517 if (port_stats.opackets != 0) {
2518 printf("(%d) port_stats.opackets not as expected\n",
2519 test_params->slave_port_ids[0]);
2522 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2523 if (port_stats.opackets != 0) {
2524 printf("(%d) port_stats.opackets not as expected\n",
2525 test_params->slave_port_ids[1]);
2528 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2529 if (port_stats.opackets != 0) {
2530 printf("(%d) port_stats.opackets not as expected\n",
2531 test_params->slave_port_ids[3]);
2535 /* Generate packet burst for testing */
2537 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2538 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
2542 virtual_ethdev_add_mbufs_to_rx_queue(
2543 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2546 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
2547 MAX_PKT_BURST) != burst_size) {
2548 printf("rte_eth_rx_burst\n");
2552 /* Verify bonded device rx count */
2553 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2554 if (port_stats.ipackets != (uint64_t)burst_size) {
2555 printf("(%d) port_stats.ipackets not as expected\n",
2556 test_params->bonded_port_id);
2560 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2561 if (port_stats.opackets != (uint64_t)burst_size) {
2562 printf("(%d) port_stats.opackets not as expected\n",
2563 test_params->slave_port_ids[2]);
2567 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2568 if (port_stats.opackets != 0) {
2569 printf("(%d) port_stats.opackets not as expected\n",
2570 test_params->slave_port_ids[0]);
2574 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2575 if (port_stats.opackets != 0) {
2576 printf("(%d) port_stats.opackets not as expected\n",
2577 test_params->slave_port_ids[1]);
2581 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2582 if (port_stats.opackets != 0) {
2583 printf("(%d) port_stats.opackets not as expected\n",
2584 test_params->slave_port_ids[3]);
2590 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2591 for (j = 0; j < MAX_PKT_BURST; j++) {
2592 if (pkt_burst[i][j] != NULL) {
2593 rte_pktmbuf_free(pkt_burst[i][j]);
2594 pkt_burst[i][j] = NULL;
2600 /* Clean up and remove slaves from bonded device */
2601 return remove_slaves_and_stop_bonded_device();
2604 /** Balance Mode Tests */
2607 test_balance_xmit_policy_configuration(void)
2611 retval = initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
2614 printf("Failed to initialize_bonded_device_with_slaves.\n");
2618 /* Invalid port id */
2619 retval = rte_eth_bond_xmit_policy_set(INVALID_PORT_ID,
2620 BALANCE_XMIT_POLICY_LAYER2);
2622 printf("Expected call to failed as invalid port specified.\n");
2626 /* Set xmit policy on non bonded device */
2627 retval = rte_eth_bond_xmit_policy_set(test_params->slave_port_ids[0],
2628 BALANCE_XMIT_POLICY_LAYER2);
2630 printf("Expected call to failed as invalid port specified.\n");
2634 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2635 BALANCE_XMIT_POLICY_LAYER2);
2637 printf("Failed to set balance xmit policy.\n");
2640 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2641 BALANCE_XMIT_POLICY_LAYER2) {
2642 printf("balance xmit policy not as expected.\n");
2646 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2647 BALANCE_XMIT_POLICY_LAYER23);
2649 printf("Failed to set balance xmit policy.\n");
2652 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2653 BALANCE_XMIT_POLICY_LAYER23) {
2654 printf("balance xmit policy not as expected.\n");
2658 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2659 BALANCE_XMIT_POLICY_LAYER34);
2661 printf("Failed to set balance xmit policy.\n");
2664 if (rte_eth_bond_xmit_policy_get(test_params->bonded_port_id) !=
2665 BALANCE_XMIT_POLICY_LAYER34) {
2666 printf("balance xmit policy not as expected.\n");
2670 /* Invalid port id */
2671 if (rte_eth_bond_xmit_policy_get(INVALID_PORT_ID) >= 0)
2674 /* Clean up and remove slaves from bonded device */
2675 return remove_slaves_and_stop_bonded_device();
2678 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2681 test_balance_l2_tx_burst(void)
2683 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2684 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2689 struct rte_eth_stats port_stats;
2691 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
2692 TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1);
2694 printf("Failed to initialize_bonded_device_with_slaves.\n");
2698 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2699 BALANCE_XMIT_POLICY_LAYER2);
2701 printf("Failed to set balance xmit policy.\n");
2706 initialize_eth_header(test_params->pkt_eth_hdr,
2707 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2708 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2710 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2711 dst_addr_0, pktlen);
2713 /* Generate a burst 1 of packets to transmit */
2714 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2715 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2716 test_params->pkt_udp_hdr, burst_size[0],
2717 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[0])
2720 initialize_eth_header(test_params->pkt_eth_hdr,
2721 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2723 /* Generate a burst 2 of packets to transmit */
2724 if (generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2725 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2726 test_params->pkt_udp_hdr, burst_size[1],
2727 PACKET_BURST_GEN_PKT_LEN, 1) != burst_size[1])
2730 /* Send burst 1 on bonded port */
2731 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2732 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[i][0],
2733 burst_size[i]) != burst_size[i])
2736 /* Verify bonded port tx stats */
2737 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2738 if (port_stats.opackets != (uint64_t)(burst_size[0] + burst_size[1])) {
2739 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2740 test_params->bonded_port_id,
2741 (unsigned int)port_stats.opackets, burst_size[0] + burst_size[1]);
2746 /* Verify slave ports tx stats */
2747 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2748 if (port_stats.opackets != (uint64_t)burst_size[0]) {
2749 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2750 test_params->slave_port_ids[0],
2751 (unsigned int)port_stats.opackets, burst_size[0]);
2755 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2756 if (port_stats.opackets != (uint64_t)burst_size[1]) {
2757 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2758 test_params->slave_port_ids[1], (
2759 unsigned int)port_stats.opackets, burst_size[1]);
2763 /* Put all slaves down and try and transmit */
2764 for (i = 0; i < test_params->bonded_slave_count; i++) {
2766 virtual_ethdev_simulate_link_status_interrupt(
2767 test_params->slave_port_ids[i], 0);
2770 /* Send burst on bonded port */
2771 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkts_burst[0][0],
2772 burst_size[0]) != 0)
2775 /* Clean up and remove slaves from bonded device */
2776 return remove_slaves_and_stop_bonded_device();
2780 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2781 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2784 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2786 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2787 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2789 struct rte_eth_stats port_stats;
2791 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1);
2793 printf("Failed to initialize_bonded_device_with_slaves.\n");
2797 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2798 BALANCE_XMIT_POLICY_LAYER23);
2800 printf("Failed to set balance xmit policy.\n");
2807 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2808 printf("Burst size specified is greater than supported.\n");
2812 /* Generate test bursts of packets to transmit */
2813 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4,
2814 0, 0, 0) != burst_size_1)
2817 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2818 toggle_mac_addr, toggle_ip_addr, 0) != burst_size_2)
2821 /* Send burst 1 on bonded port */
2822 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2824 if (nb_tx_1 != burst_size_1)
2827 /* Send burst 2 on bonded port */
2828 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2830 if (nb_tx_2 != burst_size_2)
2833 /* Verify bonded port tx stats */
2834 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2835 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2836 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2837 test_params->bonded_port_id,
2838 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2842 /* Verify slave ports tx stats */
2843 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2844 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2845 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2846 test_params->slave_port_ids[0],
2847 (unsigned int)port_stats.opackets, nb_tx_1);
2851 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2852 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2853 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2854 test_params->slave_port_ids[1],
2855 (unsigned int)port_stats.opackets, nb_tx_2);
2859 /* Put all slaves down and try and transmit */
2860 for (i = 0; i < test_params->bonded_slave_count; i++) {
2862 virtual_ethdev_simulate_link_status_interrupt(
2863 test_params->slave_port_ids[i], 0);
2866 /* Send burst on bonded port */
2867 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2872 /* Clean up and remove slaves from bonded device */
2873 return remove_slaves_and_stop_bonded_device();
2877 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2879 return balance_l23_tx_burst(0, 1, 1, 0);
2883 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2885 return balance_l23_tx_burst(1, 1, 0, 1);
2889 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2891 return balance_l23_tx_burst(0, 0, 0, 1);
2895 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2897 return balance_l23_tx_burst(1, 0, 0, 1);
2901 test_balance_l23_tx_burst_toggle_mac_addr(void)
2903 return balance_l23_tx_burst(0, 0, 1, 0);
2907 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2908 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2909 uint8_t toggle_udp_port)
2912 int burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2914 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2915 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2917 struct rte_eth_stats port_stats;
2919 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1);
2921 printf("Failed to initialize_bonded_device_with_slaves.\n");
2925 retval = rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
2926 BALANCE_XMIT_POLICY_LAYER34);
2928 printf("Failed to set balance xmit policy.\n");
2935 if (burst_size_1 > MAX_PKT_BURST || burst_size_2 > MAX_PKT_BURST) {
2936 printf("Burst size specified is greater than supported.\n");
2940 /* Generate test bursts of packets to transmit */
2941 if (generate_test_burst(pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0,
2942 0, 0) != burst_size_1)
2945 if (generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2946 toggle_mac_addr, toggle_ip_addr, toggle_udp_port) != burst_size_2)
2949 /* Send burst 1 on bonded port */
2950 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2952 if (nb_tx_1 != burst_size_1)
2955 /* Send burst 2 on bonded port */
2956 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2958 if (nb_tx_2 != burst_size_2)
2962 /* Verify bonded port tx stats */
2963 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2964 if (port_stats.opackets != (uint64_t)(nb_tx_1 + nb_tx_2)) {
2965 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
2966 test_params->bonded_port_id,
2967 (unsigned int)port_stats.opackets, nb_tx_1 + nb_tx_2);
2971 /* Verify slave ports tx stats */
2972 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2973 if (port_stats.opackets != (uint64_t)nb_tx_1) {
2974 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2975 test_params->slave_port_ids[0],
2976 (unsigned int)port_stats.opackets, nb_tx_1);
2980 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2981 if (port_stats.opackets != (uint64_t)nb_tx_2) {
2982 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2983 test_params->slave_port_ids[1],
2984 (unsigned int)port_stats.opackets, nb_tx_2);
2988 /* Put all slaves down and try and transmit */
2989 for (i = 0; i < test_params->bonded_slave_count; i++) {
2991 virtual_ethdev_simulate_link_status_interrupt(
2992 test_params->slave_port_ids[i], 0);
2995 /* Send burst on bonded port */
2996 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3001 /* Clean up and remove slaves from bonded device */
3002 return remove_slaves_and_stop_bonded_device();
3006 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
3008 return balance_l34_tx_burst(0, 1, 0, 1, 0);
3012 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
3014 return balance_l34_tx_burst(0, 1, 0, 0, 1);
3018 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
3020 return balance_l34_tx_burst(1, 1, 0, 1, 0);
3024 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
3026 return balance_l34_tx_burst(0, 0, 0, 1, 0);
3030 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
3032 return balance_l34_tx_burst(1, 0, 0, 1, 0);
3036 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
3038 return balance_l34_tx_burst(0, 0, 0, 0, 1);
3041 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
3042 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
3043 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
3044 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
3045 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
3048 test_balance_tx_burst_slave_tx_fail(void)
3050 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
3051 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
3053 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
3055 struct rte_eth_stats port_stats;
3057 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
3059 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3060 BONDING_MODE_BALANCE, 0,
3061 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3062 "Failed to intialise bonded device");
3064 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3065 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3066 "Failed to set balance xmit policy.");
3069 /* Generate test bursts for transmission */
3070 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
3071 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
3072 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
3073 "Failed to generate test packet burst 1");
3075 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3076 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
3078 /* copy mbuf referneces for expected transmission failures */
3079 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
3080 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
3082 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
3083 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
3084 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3085 "Failed to generate test packet burst 2");
3088 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3089 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3090 virtual_ethdev_tx_burst_fn_set_success(
3091 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3094 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3095 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3096 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3099 /* Transmit burst 1 */
3100 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3101 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3103 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3104 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3105 "Transmitted (%d) packets, expected to transmit (%d) packets",
3106 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3107 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3109 /* Verify that failed packet are expected failed packets */
3110 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3111 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3112 "expected mbuf (%d) pointer %p not expected pointer %p",
3113 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3116 /* Transmit burst 2 */
3117 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3118 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3120 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3121 "Transmitted (%d) packets, expected to transmit (%d) packets",
3122 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3125 /* Verify bonded port tx stats */
3126 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3128 TEST_ASSERT_EQUAL(port_stats.opackets,
3129 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3130 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3131 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3132 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3133 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3134 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3135 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3136 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3138 /* Verify slave ports tx stats */
3140 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3142 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3143 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3144 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3145 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3146 test_params->slave_port_ids[0],
3147 (unsigned int)port_stats.opackets,
3148 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3149 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3154 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3156 TEST_ASSERT_EQUAL(port_stats.opackets,
3157 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3158 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3159 test_params->slave_port_ids[1],
3160 (unsigned int)port_stats.opackets,
3161 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3163 /* Verify that all mbufs have a ref value of zero */
3164 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3165 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3166 "mbufs refcnts not as expected");
3168 free_mbufs(&pkts_burst_1[tx_count_1],
3169 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3171 /* Clean up and remove slaves from bonded device */
3172 return remove_slaves_and_stop_bonded_device();
3175 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3178 test_balance_rx_burst(void)
3180 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3182 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3183 struct rte_eth_stats port_stats;
3185 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3188 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3190 /* Initialize bonded device with 4 slaves in round robin mode */
3191 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 3, 1)
3195 /* Generate test bursts of packets to transmit */
3196 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3197 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3198 0, 0) != burst_size[i])
3201 /* Add rx data to slaves */
3202 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3203 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3204 &gen_pkt_burst[i][0], burst_size[i]);
3207 /* Call rx burst on bonded device */
3208 /* Send burst on bonded port */
3209 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3211 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3212 printf("balance rx burst failed\n");
3216 /* Verify bonded device rx count */
3217 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3218 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3220 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3221 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3222 burst_size[0] + burst_size[1] + burst_size[2]);
3227 /* Verify bonded slave devices rx counts */
3228 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3229 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3230 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3231 test_params->slave_port_ids[0],
3232 (unsigned int)port_stats.ipackets, burst_size[0]);
3236 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3237 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3238 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3239 test_params->slave_port_ids[1],
3240 (unsigned int)port_stats.ipackets, burst_size[1]);
3244 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3245 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3246 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3247 test_params->slave_port_ids[2],
3248 (unsigned int)port_stats.ipackets, burst_size[2]);
3252 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3253 if (port_stats.ipackets != 0) {
3254 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3255 test_params->slave_port_ids[3],
3256 (unsigned int)port_stats.ipackets, 0);
3261 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3262 for (j = 0; j < MAX_PKT_BURST; j++) {
3263 if (gen_pkt_burst[i][j] != NULL) {
3264 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3265 gen_pkt_burst[i][j] = NULL;
3270 /* Clean up and remove slaves from bonded device */
3271 return remove_slaves_and_stop_bonded_device();
3275 test_balance_verify_promiscuous_enable_disable(void)
3277 int i, promiscuous_en;
3279 /* Initialize bonded device with 4 slaves in round robin mode */
3280 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) != 0)
3283 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3285 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3286 if (promiscuous_en != 1) {
3287 printf("Port (%d) promiscuous mode not enabled\n",
3288 test_params->bonded_port_id);
3292 for (i = 0; i < test_params->bonded_slave_count; i++) {
3293 promiscuous_en = rte_eth_promiscuous_get(
3294 test_params->slave_port_ids[i]);
3295 if (promiscuous_en != 1) {
3296 printf("slave port (%d) promiscuous mode not enabled\n",
3297 test_params->slave_port_ids[i]);
3302 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3304 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3305 if (promiscuous_en != 0) {
3306 printf("Port (%d) promiscuous mode not disabled\n",
3307 test_params->bonded_port_id);
3311 for (i = 0; i < test_params->bonded_slave_count; i++) {
3312 promiscuous_en = rte_eth_promiscuous_get(
3313 test_params->slave_port_ids[i]);
3314 if (promiscuous_en != 0) {
3315 printf("slave port (%d) promiscuous mode not disabled\n",
3316 test_params->slave_port_ids[i]);
3321 /* Clean up and remove slaves from bonded device */
3322 return remove_slaves_and_stop_bonded_device();
3326 test_balance_verify_mac_assignment(void)
3328 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3330 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3331 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3333 /* Initialize bonded device with 2 slaves in active backup mode */
3334 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1) != 0)
3337 /* Verify that bonded MACs is that of first slave and that the other slave
3338 * MAC hasn't been changed */
3339 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3340 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3341 printf("bonded port (%d) mac address not set to that of primary port\n",
3342 test_params->bonded_port_id);
3346 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3347 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3348 printf("slave port (%d) mac address not set to that of primary port\n",
3349 test_params->slave_port_ids[0]);
3353 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3354 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3355 printf("slave port (%d) mac address not set to that of primary port\n",
3356 test_params->slave_port_ids[1]);
3360 /* change primary and verify that MAC addresses haven't changed */
3361 if (rte_eth_bond_primary_set(test_params->bonded_port_id,
3362 test_params->slave_port_ids[1]) != 0) {
3363 printf("Failed to set bonded port (%d) primary port to (%d)\n",
3364 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3368 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3369 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3370 printf("bonded port (%d) mac address not set to that of primary port\n",
3371 test_params->bonded_port_id);
3375 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3376 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3377 printf("slave port (%d) mac address not set to that of primary port\n",
3378 test_params->slave_port_ids[0]);
3382 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3383 if (memcmp(&expected_mac_addr_0, &read_mac_addr, sizeof(read_mac_addr))) {
3384 printf("slave port (%d) mac address not set to that of primary port\n",
3385 test_params->slave_port_ids[1]);
3389 /* stop / start bonded device and verify that primary MAC address is
3390 * propagated to bonded device and slaves */
3392 rte_eth_dev_stop(test_params->bonded_port_id);
3394 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
3397 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3398 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3399 printf("bonded port (%d) mac address not set to that of primary port\n",
3400 test_params->bonded_port_id);
3404 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3405 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3406 printf("slave port (%d) mac address not set to that of primary port\n",
3407 test_params->slave_port_ids[0]);
3411 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3412 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
3413 printf("slave port (%d) mac address not set to that of primary port\n",
3414 test_params->slave_port_ids[1]);
3418 /* Set explicit MAC address */
3419 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
3420 (struct ether_addr *)bonded_mac) != 0)
3423 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3424 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3425 printf("bonded port (%d) mac address not set to that of bonded port\n",
3426 test_params->bonded_port_id);
3430 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3431 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3432 printf("slave port (%d) mac address not as expected\n",
3433 test_params->slave_port_ids[0]);
3437 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3438 if (memcmp(&bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
3439 printf("slave port (%d) mac address not set to that of bonded port\n",
3440 test_params->slave_port_ids[1]);
3444 /* Clean up and remove slaves from bonded device */
3445 return remove_slaves_and_stop_bonded_device();
3448 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3451 test_balance_verify_slave_link_status_change_behaviour(void)
3453 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3454 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3455 struct rte_eth_stats port_stats;
3457 uint8_t slaves[RTE_MAX_ETHPORTS];
3459 int i, j, burst_size, slave_count;
3461 memset(pkt_burst, 0, sizeof(pkt_burst));
3463 /* Initialize bonded device with 4 slaves in round robin mode */
3464 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
3465 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
3468 if (rte_eth_bond_xmit_policy_set(test_params->bonded_port_id,
3469 BALANCE_XMIT_POLICY_LAYER2)) {
3470 printf("Failed to set balance xmit policy.\n");
3474 /* Verify Current Slaves Count /Active Slave Count is */
3475 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3477 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3478 printf("Number of slaves (%d) is not as expected (%d).\n", slave_count,
3479 TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3483 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3484 slaves, RTE_MAX_ETHPORTS);
3485 if (slave_count != TEST_BALANCE_LINK_STATUS_SLAVE_COUNT) {
3486 printf("Number of active slaves (%d) is not as expected (%d).\n",
3487 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3491 /* Set 2 slaves link status to down */
3492 virtual_ethdev_simulate_link_status_interrupt(
3493 test_params->slave_port_ids[1], 0);
3494 virtual_ethdev_simulate_link_status_interrupt(
3495 test_params->slave_port_ids[3], 0);
3497 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3498 slaves, RTE_MAX_ETHPORTS) != 2) {
3499 printf("Number of active slaves (%d) is not as expected (%d).\n",
3504 /* Send to sets of packet burst and verify that they are balanced across
3508 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0) !=
3510 printf("generate_test_burst failed\n");
3514 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3516 printf("generate_test_burst failed\n");
3520 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
3521 burst_size) != burst_size) {
3522 printf("rte_eth_tx_burst failed\n");
3526 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3527 burst_size) != burst_size) {
3528 printf("rte_eth_tx_burst failed\n");
3532 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3533 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3534 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3535 test_params->bonded_port_id, (int)port_stats.opackets,
3536 burst_size + burst_size);
3540 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3541 if (port_stats.opackets != (uint64_t)burst_size) {
3542 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3543 test_params->slave_port_ids[0], (int)port_stats.opackets,
3548 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3549 if (port_stats.opackets != (uint64_t)burst_size) {
3550 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3551 test_params->slave_port_ids[2], (int)port_stats.opackets,
3556 /* verify that all packets get send on primary slave when no other slaves
3558 virtual_ethdev_simulate_link_status_interrupt(
3559 test_params->slave_port_ids[2], 0);
3561 if (rte_eth_bond_active_slaves_get(test_params->bonded_port_id, slaves,
3562 RTE_MAX_ETHPORTS) != 1) {
3563 printf("Number of active slaves (%d) is not as expected (%d).\n",
3568 if (generate_test_burst(&pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0) !=
3570 printf("generate_test_burst failed\n");
3574 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[1][0],
3575 burst_size) != burst_size) {
3576 printf("rte_eth_tx_burst failed\n");
3580 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3581 if (port_stats.opackets != (uint64_t)(burst_size + burst_size +
3583 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3584 test_params->bonded_port_id, (int)port_stats.opackets,
3585 burst_size + burst_size + burst_size);
3589 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3590 if (port_stats.opackets != (uint64_t)(burst_size + burst_size)) {
3591 printf("(%d) port_stats.opackets (%d) not as expected (%d).\n",
3592 test_params->slave_port_ids[0], (int)port_stats.opackets,
3593 burst_size + burst_size);
3598 virtual_ethdev_simulate_link_status_interrupt(
3599 test_params->slave_port_ids[0], 0);
3600 virtual_ethdev_simulate_link_status_interrupt(
3601 test_params->slave_port_ids[1], 1);
3602 virtual_ethdev_simulate_link_status_interrupt(
3603 test_params->slave_port_ids[2], 1);
3604 virtual_ethdev_simulate_link_status_interrupt(
3605 test_params->slave_port_ids[3], 1);
3607 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3608 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
3612 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3613 &pkt_burst[i][0], burst_size);
3618 /* Verify that pkts are not received on slaves with link status down */
3620 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3623 /* Verify bonded device rx count */
3624 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3625 if (port_stats.ipackets != (uint64_t)(burst_size * 3)) {
3626 printf("(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3627 test_params->bonded_port_id, (int)port_stats.ipackets,
3632 /* free mbufs allocate for rx testing */
3633 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3634 for (j = 0; j < MAX_PKT_BURST; j++) {
3635 if (pkt_burst[i][j] != NULL) {
3636 rte_pktmbuf_free(pkt_burst[i][j]);
3637 pkt_burst[i][j] = NULL;
3642 /* Clean up and remove slaves from bonded device */
3643 return remove_slaves_and_stop_bonded_device();
3646 #ifdef RTE_MBUF_REFCNT
3647 /** Broadcast Mode Tests */
3650 test_broadcast_tx_burst(void)
3652 int i, pktlen, retval, burst_size, generated_burst_size, nb_tx;
3653 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3655 struct rte_eth_stats port_stats;
3657 retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 2, 1);
3659 printf("Failed to initialize_bonded_device_with_slaves.\n");
3663 initialize_eth_header(test_params->pkt_eth_hdr,
3664 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3666 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3668 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3669 dst_addr_0, pktlen);
3671 burst_size = 20 * test_params->bonded_slave_count;
3673 if (burst_size > MAX_PKT_BURST) {
3674 printf("Burst size specified is greater than supported.\n");
3678 /* Generate a burst of packets to transmit */
3679 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
3680 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3681 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3683 if (generated_burst_size != burst_size)
3686 /* Send burst on bonded port */
3687 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3689 if (nb_tx != burst_size) {
3690 printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
3691 test_params->bonded_port_id,
3696 /* Verify bonded port tx stats */
3697 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3698 if (port_stats.opackets != (uint64_t)burst_size *
3699 test_params->bonded_slave_count) {
3700 printf("Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3701 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3705 /* Verify slave ports tx stats */
3706 for (i = 0; i < test_params->bonded_slave_count; i++) {
3707 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3708 if (port_stats.opackets != (uint64_t)burst_size) {
3709 printf("Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3710 test_params->bonded_port_id,
3711 (unsigned int)port_stats.opackets, burst_size);
3715 /* Put all slaves down and try and transmit */
3716 for (i = 0; i < test_params->bonded_slave_count; i++) {
3718 virtual_ethdev_simulate_link_status_interrupt(
3719 test_params->slave_port_ids[i], 0);
3722 /* Send burst on bonded port */
3723 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3728 /* Clean up and remove slaves from bonded device */
3729 return remove_slaves_and_stop_bonded_device();
3733 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3734 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3735 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3736 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3739 test_broadcast_tx_burst_slave_tx_fail(void)
3741 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3742 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3744 struct rte_eth_stats port_stats;
3748 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3749 BONDING_MODE_BROADCAST, 0,
3750 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3751 "Failed to intialise bonded device");
3753 /* Generate test bursts for transmission */
3754 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3755 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3756 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3757 "Failed to generate test packet burst");
3759 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3760 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3761 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3764 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3765 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3766 virtual_ethdev_tx_burst_fn_set_success(
3767 test_params->slave_port_ids[0],
3769 virtual_ethdev_tx_burst_fn_set_success(
3770 test_params->slave_port_ids[1],
3772 virtual_ethdev_tx_burst_fn_set_success(
3773 test_params->slave_port_ids[2],
3776 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3777 test_params->slave_port_ids[0],
3778 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3780 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3781 test_params->slave_port_ids[1],
3782 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3784 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3785 test_params->slave_port_ids[2],
3786 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3788 /* Transmit burst */
3789 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3790 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3792 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3793 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3794 "Transmitted (%d) packets, expected to transmit (%d) packets",
3795 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3796 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3798 /* Verify that failed packet are expected failed packets */
3799 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3800 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3801 "expected mbuf (%d) pointer %p not expected pointer %p",
3802 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3805 /* Verify slave ports tx stats */
3807 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3809 TEST_ASSERT_EQUAL(port_stats.opackets,
3810 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3811 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3812 "Port (%d) opackets value (%u) not as expected (%d)",
3813 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3814 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3815 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3818 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3820 TEST_ASSERT_EQUAL(port_stats.opackets,
3821 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3822 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3823 "Port (%d) opackets value (%u) not as expected (%d)",
3824 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3825 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3826 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3828 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3830 TEST_ASSERT_EQUAL(port_stats.opackets,
3831 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3832 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3833 "Port (%d) opackets value (%u) not as expected (%d)",
3834 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3835 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3836 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3839 /* Verify that all mbufs who transmission failed have a ref value of one */
3840 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3841 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3842 "mbufs refcnts not as expected");
3844 free_mbufs(&pkts_burst[tx_count],
3845 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3847 /* Clean up and remove slaves from bonded device */
3848 return remove_slaves_and_stop_bonded_device();
3851 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3854 test_broadcast_rx_burst(void)
3856 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3858 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3859 struct rte_eth_stats port_stats;
3861 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3864 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3866 /* Initialize bonded device with 4 slaves in round robin mode */
3867 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 3, 1) != 0)
3871 /* Generate test bursts of packets to transmit */
3872 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3873 if (generate_test_burst(&gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0,
3874 0) != burst_size[i])
3878 /* Add rx data to slave 0 */
3879 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3880 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3881 &gen_pkt_burst[i][0], burst_size[i]);
3885 /* Call rx burst on bonded device */
3886 /* Send burst on bonded port */
3887 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3889 if (nb_rx != burst_size[0] + burst_size[1] + burst_size[2]) {
3890 printf("round-robin rx burst failed");
3894 /* Verify bonded device rx count */
3895 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3896 if (port_stats.ipackets != (uint64_t)(burst_size[0] + burst_size[1] +
3898 printf("Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
3899 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3900 burst_size[0] + burst_size[1] + burst_size[2]);
3905 /* Verify bonded slave devices rx counts */
3906 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3907 if (port_stats.ipackets != (uint64_t)burst_size[0]) {
3908 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3909 test_params->slave_port_ids[0],
3910 (unsigned int)port_stats.ipackets, burst_size[0]);
3914 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3915 if (port_stats.ipackets != (uint64_t)burst_size[1]) {
3916 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3917 test_params->slave_port_ids[1],
3918 (unsigned int)port_stats.ipackets, burst_size[1]);
3922 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3923 if (port_stats.ipackets != (uint64_t)burst_size[2]) {
3924 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3925 test_params->slave_port_ids[2],
3926 (unsigned int)port_stats.ipackets,
3931 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3932 if (port_stats.ipackets != 0) {
3933 printf("Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
3934 test_params->slave_port_ids[3],
3935 (unsigned int)port_stats.ipackets, 0);
3939 /* free mbufs allocate for rx testing */
3940 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3941 for (j = 0; j < MAX_PKT_BURST; j++) {
3942 if (gen_pkt_burst[i][j] != NULL) {
3943 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3944 gen_pkt_burst[i][j] = NULL;
3949 /* Clean up and remove slaves from bonded device */
3950 return remove_slaves_and_stop_bonded_device();
3954 test_broadcast_verify_promiscuous_enable_disable(void)
3956 int i, promiscuous_en;
3958 /* Initialize bonded device with 4 slaves in round robin mode */
3959 if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) != 0)
3962 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3964 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3965 if (promiscuous_en != 1) {
3966 printf("Port (%d) promiscuous mode not enabled\n",
3967 test_params->bonded_port_id);
3971 for (i = 0; i < test_params->bonded_slave_count; i++) {
3972 promiscuous_en = rte_eth_promiscuous_get(
3973 test_params->slave_port_ids[i]);
3974 if (promiscuous_en != 1) {
3975 printf("slave port (%d) promiscuous mode not enabled\n",
3976 test_params->slave_port_ids[i]);
3981 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3983 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
3984 if (promiscuous_en != 0) {
3985 printf("Port (%d) promiscuous mode not disabled\n",
3986 test_params->bonded_port_id);
3990 for (i = 0; i < test_params->bonded_slave_count; i++) {
3991 promiscuous_en = rte_eth_promiscuous_get(
3992 test_params->slave_port_ids[i]);
3993 if (promiscuous_en != 0) {
3994 printf("slave port (%d) promiscuous mode not disabled\n",
3995 test_params->slave_port_ids[i]);
4000 /* Clean up and remove slaves from bonded device */
4001 return remove_slaves_and_stop_bonded_device();
4005 test_broadcast_verify_mac_assignment(void)
4007 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4011 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4012 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
4014 /* Initialize bonded device with 4 slaves in round robin mode */
4015 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 4, 1) != 0)
4018 /* Verify that all MACs are the same as first slave added to bonded
4020 for (i = 0; i < test_params->bonded_slave_count; i++) {
4021 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4022 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
4023 sizeof(read_mac_addr))) {
4024 printf("slave port (%d) mac address not set to that of primary port\n",
4025 test_params->slave_port_ids[i]);
4030 /* change primary and verify that MAC addresses haven't changed */
4031 retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
4032 test_params->slave_port_ids[2]);
4034 printf("Failed to set bonded port (%d) primary port to (%d)\n",
4035 test_params->bonded_port_id, test_params->slave_port_ids[i]);
4039 for (i = 0; i < test_params->bonded_slave_count; i++) {
4040 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4041 if (memcmp(&expected_mac_addr_0, &read_mac_addr,
4042 sizeof(read_mac_addr))) {
4043 printf("slave port (%d) mac address has changed to that of primary"
4044 "port without stop/start toggle of bonded device\n",
4045 test_params->slave_port_ids[i]);
4050 /* stop / start bonded device and verify that primary MAC address is
4051 * propagated to bonded device and slaves */
4053 rte_eth_dev_stop(test_params->bonded_port_id);
4055 if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
4058 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4059 if (memcmp(&expected_mac_addr_1, &read_mac_addr, sizeof(read_mac_addr))) {
4060 printf("bonded port (%d) mac address not set to that of new primary"
4061 " port\n", test_params->slave_port_ids[i]);
4065 for (i = 0; i < test_params->bonded_slave_count; i++) {
4066 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4067 if (memcmp(&expected_mac_addr_1, &read_mac_addr,
4068 sizeof(read_mac_addr))) {
4069 printf("slave port (%d) mac address not set to that of new primary"
4070 "port\n", test_params->slave_port_ids[i]);
4075 /* Set explicit MAC address */
4076 if (rte_eth_bond_mac_address_set(test_params->bonded_port_id,
4077 (struct ether_addr *)bonded_mac) != 0)
4080 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4081 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
4082 printf("bonded port (%d) mac address not set to that of new primary port\n",
4083 test_params->slave_port_ids[i]);
4087 for (i = 0; i < test_params->bonded_slave_count; i++) {
4088 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
4089 if (memcmp(bonded_mac, &read_mac_addr, sizeof(read_mac_addr))) {
4090 printf("slave port (%d) mac address not set to that of new primary port\n",
4091 test_params->slave_port_ids[i]);
4096 /* Clean up and remove slaves from bonded device */
4097 return remove_slaves_and_stop_bonded_device();
4100 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
4102 test_broadcast_verify_slave_link_status_change_behaviour(void)
4104 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
4105 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4106 struct rte_eth_stats port_stats;
4108 uint8_t slaves[RTE_MAX_ETHPORTS];
4110 int i, j, burst_size, slave_count;
4112 memset(pkt_burst, 0, sizeof(pkt_burst));
4114 /* Initialize bonded device with 4 slaves in round robin mode */
4115 if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0,
4116 BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
4119 /* Verify Current Slaves Count /Active Slave Count is */
4120 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4122 if (slave_count != 4) {
4123 printf("Number of slaves (%d) is not as expected (%d).\n",
4128 slave_count = rte_eth_bond_active_slaves_get(
4129 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
4130 if (slave_count != 4) {
4131 printf("Number of active slaves (%d) is not as expected (%d).\n",
4136 /* Set 2 slaves link status to down */
4137 virtual_ethdev_simulate_link_status_interrupt(
4138 test_params->slave_port_ids[1], 0);
4139 virtual_ethdev_simulate_link_status_interrupt(
4140 test_params->slave_port_ids[3], 0);
4142 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4143 slaves, RTE_MAX_ETHPORTS);
4144 if (slave_count != 2) {
4145 printf("Number of active slaves (%d) is not as expected (%d).\n",
4150 for (i = 0; i < test_params->bonded_slave_count; i++)
4151 rte_eth_stats_reset(test_params->slave_port_ids[i]);
4153 /* Verify that pkts are not sent on slaves with link status down */
4156 if (generate_test_burst(&pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0) !=
4158 printf("generate_test_burst failed\n");
4162 if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
4163 burst_size) != burst_size) {
4164 printf("rte_eth_tx_burst failed\n");
4168 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4169 if (port_stats.opackets != (uint64_t)(burst_size * slave_count)) {
4170 printf("(%d) port_stats.opackets (%d) not as expected (%d)\n",
4171 test_params->bonded_port_id, (int)port_stats.opackets,
4172 burst_size * slave_count);
4176 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4177 if (port_stats.opackets != (uint64_t)burst_size) {
4178 printf("(%d) port_stats.opackets not as expected\n",
4179 test_params->slave_port_ids[0]);
4183 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4184 if (port_stats.opackets != 0) {
4185 printf("(%d) port_stats.opackets not as expected\n",
4186 test_params->slave_port_ids[1]);
4190 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4191 if (port_stats.opackets != (uint64_t)burst_size) {
4192 printf("(%d) port_stats.opackets not as expected\n",
4193 test_params->slave_port_ids[2]);
4197 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4198 if (port_stats.opackets != 0) {
4199 printf("(%d) port_stats.opackets not as expected\n",
4200 test_params->slave_port_ids[3]);
4204 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4205 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0) !=
4210 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4211 &pkt_burst[i][0], burst_size);
4214 /* Verify that pkts are not received on slaves with link status down */
4216 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4218 burst_size + burst_size) {
4219 printf("rte_eth_rx_burst\n");
4223 /* Verify bonded device rx count */
4224 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4225 if (port_stats.ipackets != (uint64_t)(burst_size + burst_size)) {
4226 printf("(%d) port_stats.ipackets not as expected\n",
4227 test_params->bonded_port_id);
4231 /* free mbufs allocate for rx testing */
4232 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4233 for (j = 0; j < MAX_PKT_BURST; j++) {
4234 if (pkt_burst[i][j] != NULL) {
4235 rte_pktmbuf_free(pkt_burst[i][j]);
4236 pkt_burst[i][j] = NULL;
4241 /* Clean up and remove slaves from bonded device */
4242 return remove_slaves_and_stop_bonded_device();
4247 test_reconfigure_bonded_device(void)
4249 test_params->nb_rx_q = 4;
4250 test_params->nb_tx_q = 4;
4252 if (configure_ethdev(test_params->bonded_port_id, 0, 0) != 0) {
4253 printf("failed to reconfigure bonded device");
4258 test_params->nb_rx_q = 2;
4259 test_params->nb_tx_q = 2;
4261 if (configure_ethdev(test_params->bonded_port_id, 0, 0) != 0) {
4262 printf("failed to reconfigure bonded device with less rx/tx queues");
4271 test_close_bonded_device(void)
4273 rte_eth_dev_close(test_params->bonded_port_id);
4278 testsuite_teardown(void)
4280 if (test_params->pkt_eth_hdr != NULL) {
4281 free(test_params->pkt_eth_hdr);
4282 test_params->pkt_eth_hdr = NULL;
4285 /* Clean up and remove slaves from bonded device */
4286 return remove_slaves_and_stop_bonded_device();
4290 static struct unit_test_suite link_bonding_test_suite = {
4291 .suite_name = "Link Bonding Unit Test Suite",
4292 .setup = test_setup,
4293 .teardown = testsuite_teardown,
4294 .unit_test_cases = {
4295 TEST_CASE(test_create_bonded_device),
4296 TEST_CASE(test_create_bonded_device_with_invalid_params),
4297 TEST_CASE(test_add_slave_to_bonded_device),
4298 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4299 TEST_CASE(test_remove_slave_from_bonded_device),
4300 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4301 TEST_CASE(test_get_slaves_from_bonded_device),
4302 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4303 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4304 TEST_CASE(test_start_bonded_device),
4305 TEST_CASE(test_stop_bonded_device),
4306 TEST_CASE(test_set_bonding_mode),
4307 TEST_CASE(test_set_primary_slave),
4308 TEST_CASE(test_set_explicit_bonded_mac),
4309 TEST_CASE(test_status_interrupt),
4310 TEST_CASE(test_adding_slave_after_bonded_device_started),
4311 TEST_CASE(test_roundrobin_tx_burst),
4312 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4313 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4314 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4315 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4316 TEST_CASE(test_roundrobin_verify_mac_assignment),
4317 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4318 TEST_CASE(test_activebackup_tx_burst),
4319 TEST_CASE(test_activebackup_rx_burst),
4320 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4321 TEST_CASE(test_activebackup_verify_mac_assignment),
4322 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4323 TEST_CASE(test_balance_xmit_policy_configuration),
4324 TEST_CASE(test_balance_l2_tx_burst),
4325 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4326 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4327 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4328 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4329 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4330 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4331 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4332 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4333 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4334 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4335 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4336 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4337 TEST_CASE(test_balance_rx_burst),
4338 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4339 TEST_CASE(test_balance_verify_mac_assignment),
4340 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4341 #ifdef RTE_MBUF_REFCNT
4342 TEST_CASE(test_broadcast_tx_burst),
4343 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4344 TEST_CASE(test_broadcast_rx_burst),
4345 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4346 TEST_CASE(test_broadcast_verify_mac_assignment),
4347 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4349 TEST_CASE(test_reconfigure_bonded_device),
4350 TEST_CASE(test_close_bonded_device),
4352 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
4358 test_link_bonding(void)
4360 return unit_test_suite_runner(&link_bonding_test_suite);
4363 static struct test_command link_bonding_cmd = {
4364 .command = "link_bonding_autotest",
4365 .callback = test_link_bonding,
4367 REGISTER_TEST_COMMAND(link_bonding_cmd);