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.
42 #include <sys/queue.h>
44 #include <rte_cycles.h>
45 #include <rte_byteorder.h>
46 #include <rte_common.h>
47 #include <rte_debug.h>
48 #include <rte_ethdev.h>
50 #include <rte_lcore.h>
51 #include <rte_memory.h>
52 #include <rte_string_fns.h>
53 #include <rte_eth_bond.h>
55 #include "virtual_pmd.h"
56 #include "packet_burst_generator.h"
60 #define TEST_MAX_NUMBER_OF_PORTS (16)
62 #define RX_RING_SIZE 128
63 #define RX_FREE_THRESH 32
68 #define TX_RING_SIZE 512
69 #define TX_FREE_THRESH 32
73 #define TX_RSBIT_THRESH 32
74 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
75 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
76 ETH_TXQ_FLAGS_NOXSUMTCP)
78 #define MBUF_PAYLOAD_SIZE (2048)
79 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
80 #define MBUF_CACHE_SIZE (250)
81 #define BURST_SIZE (32)
83 #define DEFAULT_MBUF_DATA_SIZE (2048)
84 #define RTE_TEST_RX_DESC_MAX (2048)
85 #define RTE_TEST_TX_DESC_MAX (2048)
86 #define MAX_PKT_BURST (512)
87 #define DEF_PKT_BURST (16)
89 #define BONDED_DEV_NAME ("unit_test_bonded_device")
91 #define INVALID_SOCKET_ID (-1)
92 #define INVALID_PORT_ID (-1)
93 #define INVALID_BONDING_MODE (-1)
96 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
97 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
99 struct link_bonding_unittest_params {
100 int8_t bonded_port_id;
101 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
102 uint8_t bonded_slave_count;
103 uint8_t bonding_mode;
108 struct rte_mempool *mbuf_pool;
110 struct ether_addr *default_slave_mac;
111 struct ether_addr *default_bonded_mac;
114 struct ether_hdr *pkt_eth_hdr;
115 struct ipv4_hdr *pkt_ipv4_hdr;
116 struct ipv6_hdr *pkt_ipv6_hdr;
117 struct udp_hdr *pkt_udp_hdr;
121 static struct ipv4_hdr pkt_ipv4_hdr;
122 static struct ipv6_hdr pkt_ipv6_hdr;
123 static struct udp_hdr pkt_udp_hdr;
125 static struct link_bonding_unittest_params default_params = {
126 .bonded_port_id = -1,
127 .slave_port_ids = { -1 },
128 .bonded_slave_count = 0,
129 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
136 .default_slave_mac = (struct ether_addr *)slave_mac,
137 .default_bonded_mac = (struct ether_addr *)bonded_mac,
140 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
141 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
142 .pkt_udp_hdr = &pkt_udp_hdr
146 static struct link_bonding_unittest_params *test_params = &default_params;
148 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
150 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
152 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
154 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
156 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
157 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
158 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
159 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
160 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
161 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
163 static uint16_t src_port = 1024;
164 static uint16_t dst_port_0 = 1024;
165 static uint16_t dst_port_1 = 2024;
167 static uint16_t vlan_id = 0x100;
169 struct rte_eth_rxmode rx_mode = {
170 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
172 .header_split = 0, /**< Header Split disabled. */
173 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
174 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
175 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
176 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
177 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
178 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
181 struct rte_fdir_conf fdir_conf = {
182 .mode = RTE_FDIR_MODE_NONE,
183 .pballoc = RTE_FDIR_PBALLOC_64K,
184 .status = RTE_FDIR_REPORT_STATUS,
185 .flexbytes_offset = 0x6,
189 static struct rte_eth_conf default_pmd_conf = {
191 .mq_mode = ETH_MQ_RX_NONE,
192 .max_rx_pkt_len = ETHER_MAX_LEN,
194 .header_split = 0, /**< Header Split disabled */
195 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
196 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
197 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
198 .hw_strip_crc = 0, /**< CRC stripped by hardware */
201 .mq_mode = ETH_MQ_TX_NONE,
206 static const struct rte_eth_rxconf rx_conf_default = {
208 .pthresh = RX_PTHRESH,
209 .hthresh = RX_HTHRESH,
210 .wthresh = RX_WTHRESH,
212 .rx_free_thresh = RX_FREE_THRESH,
216 static struct rte_eth_txconf tx_conf_default = {
218 .pthresh = TX_PTHRESH,
219 .hthresh = TX_HTHRESH,
220 .wthresh = TX_WTHRESH,
222 .tx_free_thresh = TX_FREE_THRESH,
223 .tx_rs_thresh = TX_RSBIT_THRESH,
224 .txq_flags = TX_Q_FLAGS
229 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
234 default_pmd_conf.intr_conf.lsc = 1;
236 default_pmd_conf.intr_conf.lsc = 0;
238 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
239 test_params->nb_tx_q, &default_pmd_conf),
240 "rte_eth_dev_configure for port %d failed", port_id);
242 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
243 TEST_ASSERT_SUCCESS(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) ,
246 "rte_eth_rx_queue_setup for port %d failed", port_id);
248 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
249 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
250 rte_eth_dev_socket_id(port_id), &tx_conf_default),
251 "rte_eth_tx_queue_setup for port %d failed", port_id);
254 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
255 "rte_eth_dev_start for port %d failed", port_id);
260 static int slaves_initialized;
262 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
263 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
269 int i, nb_mbuf_per_pool;
270 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
272 /* Allocate ethernet packet header with space for VLAN header */
273 if (test_params->pkt_eth_hdr == NULL) {
274 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
275 sizeof(struct vlan_hdr));
277 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
278 "Ethernet header struct allocation failed!");
281 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
282 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
283 if (test_params->mbuf_pool == NULL) {
284 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
285 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
286 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
288 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
289 "rte_mempool_create failed");
292 /* Create / Initialize virtual eth devs */
293 if (!slaves_initialized) {
294 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
295 char pmd_name[RTE_ETH_NAME_MAX_LEN];
297 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
299 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
301 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
302 mac_addr, rte_socket_id(), 1);
303 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
304 "Failed to create virtual virtual ethdev %s", pmd_name);
306 TEST_ASSERT_SUCCESS(configure_ethdev(
307 test_params->slave_port_ids[i], 1, 0),
308 "Failed to configure virtual ethdev %s", pmd_name);
310 slaves_initialized = 1;
317 test_create_bonded_device(void)
319 int current_slave_count;
321 uint8_t slaves[RTE_MAX_ETHPORTS];
323 /* Don't try to recreate bonded device if re-running test suite*/
324 if (test_params->bonded_port_id == -1) {
325 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
326 test_params->bonding_mode, rte_socket_id());
328 TEST_ASSERT(test_params->bonded_port_id >= 0,
329 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
331 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
332 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
335 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
336 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
337 test_params->bonded_port_id, test_params->bonding_mode);
339 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
340 slaves, RTE_MAX_ETHPORTS);
342 TEST_ASSERT_EQUAL(current_slave_count, 0,
343 "Number of slaves %d is great than expected %d.",
344 current_slave_count, 0);
346 current_slave_count = rte_eth_bond_active_slaves_get(
347 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
349 TEST_ASSERT_EQUAL(current_slave_count, 0,
350 "Number of active slaves %d is great than expected %d.",
351 current_slave_count, 0);
358 test_create_bonded_device_with_invalid_params(void)
362 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
365 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
367 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
369 test_params->bonding_mode = INVALID_BONDING_MODE;
371 /* Invalid bonding mode */
372 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
374 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
376 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
378 /* Invalid socket id */
379 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
381 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
387 test_add_slave_to_bonded_device(void)
389 int current_slave_count;
391 uint8_t slaves[RTE_MAX_ETHPORTS];
393 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
394 test_params->slave_port_ids[test_params->bonded_slave_count]),
395 "Failed to add slave (%d) to bonded port (%d).",
396 test_params->slave_port_ids[test_params->bonded_slave_count],
397 test_params->bonded_port_id);
399 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
400 slaves, RTE_MAX_ETHPORTS);
401 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
402 "Number of slaves (%d) is greater than expected (%d).",
403 current_slave_count, test_params->bonded_slave_count + 1);
405 current_slave_count = rte_eth_bond_active_slaves_get(
406 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
407 TEST_ASSERT_EQUAL(current_slave_count, 0,
408 "Number of active slaves (%d) is not as expected (%d).\n",
409 current_slave_count, 0);
411 test_params->bonded_slave_count++;
417 test_add_slave_to_invalid_bonded_device(void)
419 /* Invalid port ID */
420 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
421 test_params->slave_port_ids[test_params->bonded_slave_count]),
422 "Expected call to failed as invalid port specified.");
424 /* Non bonded device */
425 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
426 test_params->slave_port_ids[test_params->bonded_slave_count]),
427 "Expected call to failed as invalid port specified.");
434 test_remove_slave_from_bonded_device(void)
436 int current_slave_count;
437 struct ether_addr read_mac_addr, *mac_addr;
438 uint8_t slaves[RTE_MAX_ETHPORTS];
440 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
441 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
442 "Failed to remove slave %d from bonded port (%d).",
443 test_params->slave_port_ids[test_params->bonded_slave_count-1],
444 test_params->bonded_port_id);
447 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
448 slaves, RTE_MAX_ETHPORTS);
450 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
451 "Number of slaves (%d) is great than expected (%d).\n",
452 current_slave_count, test_params->bonded_slave_count - 1);
455 mac_addr = (struct ether_addr *)slave_mac;
456 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
457 test_params->bonded_slave_count-1;
460 test_params->slave_port_ids[test_params->bonded_slave_count-1],
462 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
463 "bonded port mac address not set to that of primary port\n");
466 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
468 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
471 test_params->bonded_slave_count--;
477 test_remove_slave_from_invalid_bonded_device(void)
479 /* Invalid port ID */
480 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
481 test_params->bonded_port_id + 5,
482 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
483 "Expected call to failed as invalid port specified.");
485 /* Non bonded device */
486 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
487 test_params->slave_port_ids[0],
488 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
489 "Expected call to failed as invalid port specified.");
494 static int bonded_id = 2;
497 test_add_already_bonded_slave_to_bonded_device(void)
499 int port_id, current_slave_count;
500 uint8_t slaves[RTE_MAX_ETHPORTS];
501 char pmd_name[RTE_ETH_NAME_MAX_LEN];
503 test_add_slave_to_bonded_device();
505 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
506 slaves, RTE_MAX_ETHPORTS);
507 TEST_ASSERT_EQUAL(current_slave_count, 1,
508 "Number of slaves (%d) is not that expected (%d).",
509 current_slave_count, 1);
511 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
513 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
515 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
517 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
518 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
520 "Added slave (%d) to bonded port (%d) unexpectedly.",
521 test_params->slave_port_ids[test_params->bonded_slave_count-1],
524 return test_remove_slave_from_bonded_device();
529 test_get_slaves_from_bonded_device(void)
531 int current_slave_count;
532 uint8_t slaves[RTE_MAX_ETHPORTS];
534 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
535 "Failed to add slave to bonded device");
537 /* Invalid port id */
538 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
540 TEST_ASSERT(current_slave_count < 0,
541 "Invalid port id unexpectedly succeeded");
543 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
544 slaves, RTE_MAX_ETHPORTS);
545 TEST_ASSERT(current_slave_count < 0,
546 "Invalid port id unexpectedly succeeded");
548 /* Invalid slaves pointer */
549 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
550 NULL, RTE_MAX_ETHPORTS);
551 TEST_ASSERT(current_slave_count < 0,
552 "Invalid slave array unexpectedly succeeded");
554 current_slave_count = rte_eth_bond_active_slaves_get(
555 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
556 TEST_ASSERT(current_slave_count < 0,
557 "Invalid slave array unexpectedly succeeded");
559 /* non bonded device*/
560 current_slave_count = rte_eth_bond_slaves_get(
561 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
562 TEST_ASSERT(current_slave_count < 0,
563 "Invalid port id unexpectedly succeeded");
565 current_slave_count = rte_eth_bond_active_slaves_get(
566 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
567 TEST_ASSERT(current_slave_count < 0,
568 "Invalid port id unexpectedly succeeded");
570 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
571 "Failed to remove slaves from bonded device");
578 test_add_remove_multiple_slaves_to_from_bonded_device(void)
582 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
583 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
584 "Failed to add slave to bonded device");
586 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
587 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
588 "Failed to remove slaves from bonded device");
594 enable_bonded_slaves(void)
598 for (i = 0; i < test_params->bonded_slave_count; i++) {
599 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
602 virtual_ethdev_simulate_link_status_interrupt(
603 test_params->slave_port_ids[i], 1);
608 test_start_bonded_device(void)
610 struct rte_eth_link link_status;
612 int current_slave_count, current_bonding_mode, primary_port;
613 uint8_t slaves[RTE_MAX_ETHPORTS];
615 /* Add slave to bonded device*/
616 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
617 "Failed to add slave to bonded device");
619 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
620 "Failed to start bonded pmd eth device %d.",
621 test_params->bonded_port_id);
623 /* Change link status of virtual pmd so it will be added to the active
624 * slave list of the bonded device*/
625 virtual_ethdev_simulate_link_status_interrupt(
626 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
628 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
629 slaves, RTE_MAX_ETHPORTS);
630 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
631 "Number of slaves (%d) is not expected value (%d).",
632 current_slave_count, test_params->bonded_slave_count);
634 current_slave_count = rte_eth_bond_active_slaves_get(
635 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
636 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
637 "Number of active slaves (%d) is not expected value (%d).",
638 current_slave_count, test_params->bonded_slave_count);
640 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
641 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
642 "Bonded device mode (%d) is not expected value (%d).\n",
643 current_bonding_mode, test_params->bonding_mode);
645 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
646 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
647 "Primary port (%d) is not expected value (%d).",
648 primary_port, test_params->slave_port_ids[0]);
650 rte_eth_link_get(test_params->bonded_port_id, &link_status);
651 TEST_ASSERT_EQUAL(link_status.link_status, 1,
652 "Bonded port (%d) status (%d) is not expected value (%d).\n",
653 test_params->bonded_port_id, link_status.link_status, 1);
659 test_stop_bonded_device(void)
661 int current_slave_count;
662 uint8_t slaves[RTE_MAX_ETHPORTS];
664 struct rte_eth_link link_status;
666 rte_eth_dev_stop(test_params->bonded_port_id);
668 rte_eth_link_get(test_params->bonded_port_id, &link_status);
669 TEST_ASSERT_EQUAL(link_status.link_status, 0,
670 "Bonded port (%d) status (%d) is not expected value (%d).",
671 test_params->bonded_port_id, link_status.link_status, 0);
673 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
674 slaves, RTE_MAX_ETHPORTS);
675 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
676 "Number of slaves (%d) is not expected value (%d).",
677 current_slave_count, test_params->bonded_slave_count);
679 current_slave_count = rte_eth_bond_active_slaves_get(
680 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
681 TEST_ASSERT_EQUAL(current_slave_count, 0,
682 "Number of active slaves (%d) is not expected value (%d).",
683 current_slave_count, 0);
689 remove_slaves_and_stop_bonded_device(void)
691 /* Clean up and remove slaves from bonded device */
692 while (test_params->bonded_slave_count > 0)
693 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
694 "test_remove_slave_from_bonded_device failed");
696 rte_eth_dev_stop(test_params->bonded_port_id);
697 rte_eth_stats_reset(test_params->bonded_port_id);
698 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
704 test_set_bonding_mode(void)
708 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
709 BONDING_MODE_ACTIVE_BACKUP,
710 BONDING_MODE_BALANCE,
711 #ifdef RTE_MBUF_REFCNT
712 BONDING_MODE_BROADCAST
716 /* Test supported link bonding modes */
717 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
718 /* Invalid port ID */
719 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
721 "Expected call to failed as invalid port (%d) specified.",
724 /* Non bonded device */
725 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
727 "Expected call to failed as invalid port (%d) specified.",
728 test_params->slave_port_ids[0]);
730 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
732 "Failed to set link bonding mode on port (%d) to (%d).",
733 test_params->bonded_port_id, bonding_modes[i]);
735 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
736 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
737 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
738 bonding_mode, test_params->bonded_port_id,
741 /* Invalid port ID */
742 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
743 TEST_ASSERT(bonding_mode < 0,
744 "Expected call to failed as invalid port (%d) specified.",
747 /* Non bonded device */
748 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
749 TEST_ASSERT(bonding_mode < 0,
750 "Expected call to failed as invalid port (%d) specified.",
751 test_params->slave_port_ids[0]);
754 return remove_slaves_and_stop_bonded_device();
758 test_set_primary_slave(void)
761 struct ether_addr read_mac_addr;
762 struct ether_addr *expected_mac_addr;
764 /* Add 4 slaves to bonded device */
765 for (i = test_params->bonded_slave_count; i < 4; i++)
766 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
767 "Failed to add slave to bonded device.");
769 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
770 BONDING_MODE_ROUND_ROBIN),
771 "Failed to set link bonding mode on port (%d) to (%d).",
772 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
774 /* Invalid port ID */
775 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
776 test_params->slave_port_ids[i]),
777 "Expected call to failed as invalid port specified.");
779 /* Non bonded device */
780 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
781 test_params->slave_port_ids[i]),
782 "Expected call to failed as invalid port specified.");
784 /* Set slave as primary
785 * Verify slave it is now primary slave
786 * Verify that MAC address of bonded device is that of primary slave
787 * Verify that MAC address of all bonded slaves are that of primary slave
789 for (i = 0; i < 4; i++) {
790 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
791 test_params->slave_port_ids[i]),
792 "Failed to set bonded port (%d) primary port to (%d)",
793 test_params->bonded_port_id, test_params->slave_port_ids[i]);
795 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
796 TEST_ASSERT(retval >= 0,
797 "Failed to read primary port from bonded port (%d)\n",
798 test_params->bonded_port_id);
800 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
801 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
802 test_params->bonded_port_id, retval,
803 test_params->slave_port_ids[i]);
805 /* stop/start bonded eth dev to apply new MAC */
806 rte_eth_dev_stop(test_params->bonded_port_id);
808 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
809 "Failed to start bonded port %d",
810 test_params->bonded_port_id);
812 expected_mac_addr = (struct ether_addr *)&slave_mac;
813 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
815 /* Check primary slave MAC */
816 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
817 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
818 sizeof(read_mac_addr)),
819 "bonded port mac address not set to that of primary port\n");
821 /* Check bonded MAC */
822 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
823 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
824 sizeof(read_mac_addr)),
825 "bonded port mac address not set to that of primary port\n");
827 /* Check other slaves MACs */
828 for (j = 0; j < 4; j++) {
830 rte_eth_macaddr_get(test_params->slave_port_ids[j],
832 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
833 sizeof(read_mac_addr)),
834 "slave port mac address not set to that of primary "
841 /* Test with none existent port */
842 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
843 "read primary port from expectedly");
845 /* Test with slave port */
846 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
847 "read primary port from expectedly\n");
849 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
850 "Failed to stop and remove slaves from bonded device");
853 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
854 "read primary port from expectedly\n");
860 test_set_explicit_bonded_mac(void)
863 struct ether_addr read_mac_addr;
864 struct ether_addr *mac_addr;
866 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
868 mac_addr = (struct ether_addr *)explicit_bonded_mac;
870 /* Invalid port ID */
871 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
872 "Expected call to failed as invalid port specified.");
874 /* Non bonded device */
875 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
876 test_params->slave_port_ids[0], mac_addr),
877 "Expected call to failed as invalid port specified.");
879 /* NULL MAC address */
880 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
881 test_params->bonded_port_id, NULL),
882 "Expected call to failed as NULL MAC specified");
884 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
885 test_params->bonded_port_id, mac_addr),
886 "Failed to set MAC address on bonded port (%d)",
887 test_params->bonded_port_id);
889 /* Add 4 slaves to bonded device */
890 for (i = test_params->bonded_slave_count; i < 4; i++) {
891 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
892 "Failed to add slave to bonded device.\n");
895 /* Check bonded MAC */
896 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
897 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
898 "bonded port mac address not set to that of primary port");
900 /* Check other slaves MACs */
901 for (i = 0; i < 4; i++) {
902 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
903 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
904 sizeof(read_mac_addr)),
905 "slave port mac address not set to that of primary port");
908 /* test resetting mac address on bonded device */
910 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
911 "Failed to reset MAC address on bonded port (%d)",
912 test_params->bonded_port_id);
915 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
916 "Reset MAC address on bonded port (%d) unexpectedly",
917 test_params->slave_port_ids[1]);
919 /* test resetting mac address on bonded device with no slaves */
920 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
921 "Failed to remove slaves and stop bonded device");
923 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
924 "Failed to reset MAC address on bonded port (%d)",
925 test_params->bonded_port_id);
930 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
933 test_set_bonded_port_initialization_mac_assignment(void)
935 int i, slave_count, bonded_port_id;
937 uint8_t slaves[RTE_MAX_ETHPORTS];
938 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
940 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
942 /* Initialize default values for MAC addresses */
943 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
944 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
947 * 1. a - Create / configure bonded / slave ethdevs
949 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
950 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
951 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
953 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
954 "Failed to configure bonded ethdev");
956 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
957 char pmd_name[RTE_ETH_NAME_MAX_LEN];
959 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
961 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
963 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
964 &slave_mac_addr, rte_socket_id(), 1);
966 TEST_ASSERT(slave_port_ids[i] >= 0,
967 "Failed to create slave ethdev %s", pmd_name);
969 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
970 "Failed to configure virtual ethdev %s",
976 * 2. Add slave ethdevs to bonded device
978 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
979 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
981 "Failed to add slave (%d) to bonded port (%d).",
982 slave_port_ids[i], bonded_port_id);
985 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
987 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
988 "Number of slaves (%d) is not as expected (%d)",
989 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
993 * 3. Set explicit MAC address on bonded ethdev
995 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
996 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
998 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
999 bonded_port_id, &bonded_mac_addr),
1000 "Failed to set MAC address on bonded port (%d)",
1004 /* 4. a - Start bonded ethdev
1005 * b - Enable slave devices
1006 * c - Verify bonded/slaves ethdev MAC addresses
1008 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1009 "Failed to start bonded pmd eth device %d.",
1012 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1013 virtual_ethdev_simulate_link_status_interrupt(
1014 slave_port_ids[i], 1);
1017 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1018 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1019 sizeof(read_mac_addr)),
1020 "bonded port mac address not as expected");
1022 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1023 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1024 sizeof(read_mac_addr)),
1025 "slave port 0 mac address not as expected");
1027 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1028 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1029 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1030 sizeof(read_mac_addr)),
1031 "slave port 1 mac address not as expected");
1033 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1034 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1035 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1036 sizeof(read_mac_addr)),
1037 "slave port 2 mac address not as expected");
1040 /* 7. a - Change primary port
1041 * b - Stop / Start bonded port
1042 * d - Verify slave ethdev MAC addresses
1044 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1046 "failed to set primary port on bonded device.");
1048 rte_eth_dev_stop(bonded_port_id);
1049 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1050 "Failed to start bonded pmd eth device %d.",
1053 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1054 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1055 sizeof(read_mac_addr)),
1056 "bonded port mac address not as expected");
1058 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1059 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1060 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1061 sizeof(read_mac_addr)),
1062 "slave port 0 mac address not as expected");
1064 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1065 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1066 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1067 sizeof(read_mac_addr)),
1068 "slave port 1 mac address not as expected");
1070 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1071 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1072 sizeof(read_mac_addr)),
1073 "slave port 2 mac address not as expected");
1075 /* 6. a - Stop bonded ethdev
1076 * b - remove slave ethdevs
1077 * c - Verify slave ethdevs MACs are restored
1079 rte_eth_dev_stop(bonded_port_id);
1081 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1082 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1084 "Failed to remove slave %d from bonded port (%d).",
1085 slave_port_ids[i], bonded_port_id);
1088 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1091 TEST_ASSERT_EQUAL(slave_count, 0,
1092 "Number of slaves (%d) is great than expected (%d).",
1095 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1096 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1097 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1098 sizeof(read_mac_addr)),
1099 "slave port 0 mac address not as expected");
1101 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1102 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1103 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1104 sizeof(read_mac_addr)),
1105 "slave port 1 mac address not as expected");
1107 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1108 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1109 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1110 sizeof(read_mac_addr)),
1111 "slave port 2 mac address not as expected");
1118 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1119 uint8_t number_of_slaves, uint8_t enable_slave)
1121 /* Configure bonded device */
1122 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1123 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1124 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1127 /* Add slaves to bonded device */
1128 while (number_of_slaves > test_params->bonded_slave_count)
1129 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1130 "Failed to add slave (%d to bonding port (%d).",
1131 test_params->bonded_slave_count - 1,
1132 test_params->bonded_port_id);
1134 /* Set link bonding mode */
1135 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1137 "Failed to set link bonding mode on port (%d) to (%d).",
1138 test_params->bonded_port_id, bonding_mode);
1140 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1141 "Failed to start bonded pmd eth device %d.",
1142 test_params->bonded_port_id);
1145 enable_bonded_slaves();
1151 test_adding_slave_after_bonded_device_started(void)
1155 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1156 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1157 "Failed to add slaves to bonded device");
1159 /* Enabled slave devices */
1160 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1161 virtual_ethdev_simulate_link_status_interrupt(
1162 test_params->slave_port_ids[i], 1);
1165 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1166 test_params->slave_port_ids[test_params->bonded_slave_count]),
1167 "Failed to add slave to bonded port.\n");
1169 rte_eth_stats_reset(
1170 test_params->slave_port_ids[test_params->bonded_slave_count]);
1172 test_params->bonded_slave_count++;
1174 return remove_slaves_and_stop_bonded_device();
1177 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1178 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1180 int test_lsc_interrupt_count;
1184 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1185 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1187 pthread_mutex_lock(&mutex);
1188 test_lsc_interrupt_count++;
1190 pthread_cond_signal(&cvar);
1191 pthread_mutex_unlock(&mutex);
1195 lsc_timeout(int wait_us)
1202 gettimeofday(&tp, NULL);
1204 /* Convert from timeval to timespec */
1205 ts.tv_sec = tp.tv_sec;
1206 ts.tv_nsec = tp.tv_usec * 1000;
1207 ts.tv_nsec += wait_us * 1000;
1209 pthread_mutex_lock(&mutex);
1210 if (test_lsc_interrupt_count < 1)
1211 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1213 pthread_mutex_unlock(&mutex);
1215 if (retval == 0 && test_lsc_interrupt_count < 1)
1222 test_status_interrupt(void)
1225 uint8_t slaves[RTE_MAX_ETHPORTS];
1227 /* initialized bonding device with T slaves */
1228 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1229 BONDING_MODE_ROUND_ROBIN, 1,
1230 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1231 "Failed to initialise bonded device");
1233 test_lsc_interrupt_count = 0;
1235 /* register link status change interrupt callback */
1236 rte_eth_dev_callback_register(test_params->bonded_port_id,
1237 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1238 &test_params->bonded_port_id);
1240 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1241 slaves, RTE_MAX_ETHPORTS);
1243 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1244 "Number of active slaves (%d) is not as expected (%d)",
1245 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1247 /* Bring all 4 slaves link status to down and test that we have received a
1249 virtual_ethdev_simulate_link_status_interrupt(
1250 test_params->slave_port_ids[0], 0);
1251 virtual_ethdev_simulate_link_status_interrupt(
1252 test_params->slave_port_ids[1], 0);
1253 virtual_ethdev_simulate_link_status_interrupt(
1254 test_params->slave_port_ids[2], 0);
1256 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1257 "Received a link status change interrupt unexpectedly");
1259 virtual_ethdev_simulate_link_status_interrupt(
1260 test_params->slave_port_ids[3], 0);
1262 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1263 "timed out waiting for interrupt");
1265 TEST_ASSERT(test_lsc_interrupt_count > 0,
1266 "Did not receive link status change interrupt");
1268 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1269 slaves, RTE_MAX_ETHPORTS);
1271 TEST_ASSERT_EQUAL(slave_count, 0,
1272 "Number of active slaves (%d) is not as expected (%d)",
1275 /* bring one slave port up so link status will change */
1276 test_lsc_interrupt_count = 0;
1278 virtual_ethdev_simulate_link_status_interrupt(
1279 test_params->slave_port_ids[0], 1);
1281 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1282 "timed out waiting for interrupt");
1284 /* test that we have received another lsc interrupt */
1285 TEST_ASSERT(test_lsc_interrupt_count > 0,
1286 "Did not receive link status change interrupt");
1288 /* Verify that calling the same slave lsc interrupt doesn't cause another
1289 * lsc interrupt from bonded device */
1290 test_lsc_interrupt_count = 0;
1292 virtual_ethdev_simulate_link_status_interrupt(
1293 test_params->slave_port_ids[0], 1);
1295 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1296 "received unexpected interrupt");
1298 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1299 "Did not receive link status change interrupt");
1302 /* unregister lsc callback before exiting */
1303 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1304 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1305 &test_params->bonded_port_id);
1307 /* Clean up and remove slaves from bonded device */
1308 return remove_slaves_and_stop_bonded_device();
1312 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1313 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1314 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1316 uint16_t pktlen, generated_burst_size;
1320 initialize_eth_header(test_params->pkt_eth_hdr,
1321 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1322 ipv4, vlan, vlan_id);
1324 initialize_eth_header(test_params->pkt_eth_hdr,
1325 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1326 ipv4, vlan, vlan_id);
1329 if (toggle_udp_port)
1330 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1333 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1338 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1339 dst_addr_1, pktlen);
1341 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1342 dst_addr_0, pktlen);
1344 ip_hdr = test_params->pkt_ipv4_hdr;
1347 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1348 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1351 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1352 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1355 ip_hdr = test_params->pkt_ipv6_hdr;
1358 /* Generate burst of packets to transmit */
1359 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1360 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1361 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1363 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1364 "Failed to generate packet burst");
1366 return generated_burst_size;
1369 /** Round Robin Mode Tests */
1372 test_roundrobin_tx_burst(void)
1375 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1376 struct rte_eth_stats port_stats;
1378 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1379 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1380 "Failed to intialise bonded device");
1382 burst_size = 20 * test_params->bonded_slave_count;
1384 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1385 "Burst size specified is greater than supported.");
1387 /* Generate test bursts of packets to transmit */
1388 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1389 burst_size, "failed to generate test burst");
1391 /* Send burst on bonded port */
1392 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1393 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1396 /* Verify bonded port tx stats */
1397 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1398 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1399 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1400 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1403 /* Verify slave ports tx stats */
1404 for (i = 0; i < test_params->bonded_slave_count; i++) {
1405 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1406 TEST_ASSERT_EQUAL(port_stats.opackets,
1407 (uint64_t)burst_size / test_params->bonded_slave_count,
1408 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1409 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1410 burst_size / test_params->bonded_slave_count);
1413 /* Put all slaves down and try and transmit */
1414 for (i = 0; i < test_params->bonded_slave_count; i++) {
1415 virtual_ethdev_simulate_link_status_interrupt(
1416 test_params->slave_port_ids[i], 0);
1419 /* Send burst on bonded port */
1420 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1421 pkt_burst, burst_size), 0,
1422 "tx burst return unexpected value");
1424 /* Clean up and remove slaves from bonded device */
1425 return remove_slaves_and_stop_bonded_device();
1428 #ifdef RTE_MBUF_REFCNT
1430 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1434 for (i = 0; i < nb_mbufs; i++) {
1435 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1436 TEST_ASSERT_EQUAL(refcnt, val,
1437 "mbuf ref count (%d)is not the expected value (%d)",
1446 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1450 for (i = 0; i < nb_mbufs; i++)
1451 rte_pktmbuf_free(mbufs[i]);
1454 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1455 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1456 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1457 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1460 test_roundrobin_tx_burst_slave_tx_fail(void)
1462 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1463 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1465 struct rte_eth_stats port_stats;
1467 int i, first_fail_idx, tx_count;
1469 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1470 BONDING_MODE_ROUND_ROBIN, 0,
1471 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1472 "Failed to intialise bonded device");
1474 /* Generate test bursts of packets to transmit */
1475 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1476 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1477 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1478 "Failed to generate test packet burst");
1480 /* Copy references to packets which we expect not to be transmitted */
1481 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1482 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1483 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1484 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1486 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1487 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1488 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1491 /* Set virtual slave to only fail transmission of
1492 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1493 virtual_ethdev_tx_burst_fn_set_success(
1494 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1497 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1498 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1499 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1501 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1502 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1504 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1505 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1506 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1507 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1508 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1510 /* Verify that failed packet are expected failed packets */
1511 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1512 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1513 "expected mbuf (%d) pointer %p not expected pointer %p",
1514 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1517 /* Verify bonded port tx stats */
1518 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1520 TEST_ASSERT_EQUAL(port_stats.opackets,
1521 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1522 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1523 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1524 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1525 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1526 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1528 /* Verify slave ports tx stats */
1529 for (i = 0; i < test_params->bonded_slave_count; i++) {
1530 int slave_expected_tx_count;
1532 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1534 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1535 test_params->bonded_slave_count;
1537 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1538 slave_expected_tx_count = slave_expected_tx_count -
1539 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1541 TEST_ASSERT_EQUAL(port_stats.opackets,
1542 (uint64_t)slave_expected_tx_count,
1543 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1544 test_params->slave_port_ids[i],
1545 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1548 #ifdef RTE_MBUF_REFCNT
1549 /* Verify that all mbufs have a ref value of zero */
1550 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1551 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1552 "mbufs refcnts not as expected");
1554 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1556 /* Clean up and remove slaves from bonded device */
1557 return remove_slaves_and_stop_bonded_device();
1561 test_roundrobin_rx_burst_on_single_slave(void)
1563 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1564 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1566 struct rte_eth_stats port_stats;
1568 int i, j, burst_size = 25;
1570 /* Initialize bonded device with 4 slaves in round robin mode */
1571 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1572 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1573 "Failed to initialize bonded device with slaves");
1575 /* Generate test bursts of packets to transmit */
1576 TEST_ASSERT_EQUAL(generate_test_burst(
1577 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1578 "burst generation failed");
1580 for (i = 0; i < test_params->bonded_slave_count; i++) {
1581 /* Add rx data to slave */
1582 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1583 &gen_pkt_burst[0], burst_size);
1585 /* Call rx burst on bonded device */
1586 /* Send burst on bonded port */
1587 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1588 test_params->bonded_port_id, 0, rx_pkt_burst,
1589 MAX_PKT_BURST), burst_size,
1590 "round-robin rx burst failed");
1592 /* Verify bonded device rx count */
1593 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1594 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1595 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1596 test_params->bonded_port_id,
1597 (unsigned int)port_stats.ipackets, burst_size);
1601 /* Verify bonded slave devices rx count */
1602 /* Verify slave ports tx stats */
1603 for (j = 0; j < test_params->bonded_slave_count; j++) {
1604 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1607 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1608 "Slave Port (%d) ipackets value (%u) not as expected"
1609 " (%d)", test_params->slave_port_ids[i],
1610 (unsigned int)port_stats.ipackets, burst_size);
1612 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1613 "Slave Port (%d) ipackets value (%u) not as expected"
1614 " (%d)", test_params->slave_port_ids[i],
1615 (unsigned int)port_stats.ipackets, 0);
1618 /* Reset bonded slaves stats */
1619 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1621 /* reset bonded device stats */
1622 rte_eth_stats_reset(test_params->bonded_port_id);
1626 for (i = 0; i < MAX_PKT_BURST; i++) {
1627 if (gen_pkt_burst[i] != NULL)
1628 rte_pktmbuf_free(gen_pkt_burst[i]);
1630 if (rx_pkt_burst[i] != NULL)
1631 rte_pktmbuf_free(rx_pkt_burst[i]);
1635 /* Clean up and remove slaves from bonded device */
1636 return remove_slaves_and_stop_bonded_device();
1639 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1642 test_roundrobin_rx_burst_on_multiple_slaves(void)
1644 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1646 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1647 struct rte_eth_stats port_stats;
1649 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1652 /* Initialize bonded device with 4 slaves in round robin mode */
1653 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1654 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1655 "Failed to initialize bonded device with slaves");
1657 /* Generate test bursts of packets to transmit */
1658 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1659 TEST_ASSERT_EQUAL(generate_test_burst(
1660 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1661 burst_size[i], "burst generation failed");
1664 /* Add rx data to slaves */
1665 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1666 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1667 &gen_pkt_burst[i][0], burst_size[i]);
1670 /* Call rx burst on bonded device */
1671 /* Send burst on bonded port */
1672 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1674 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1675 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1676 burst_size[0] + burst_size[1] + burst_size[2]);
1678 /* Verify bonded device rx count */
1679 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1680 TEST_ASSERT_EQUAL(port_stats.ipackets,
1681 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1682 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1683 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1684 burst_size[0] + burst_size[1] + burst_size[2]);
1686 /* Verify bonded slave devices rx counts */
1687 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1688 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1689 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1690 test_params->slave_port_ids[0],
1691 (unsigned int)port_stats.ipackets, burst_size[0]);
1693 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1694 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1695 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1696 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1699 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1700 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1701 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1702 test_params->slave_port_ids[2],
1703 (unsigned int)port_stats.ipackets, burst_size[2]);
1705 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1706 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1707 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1708 test_params->slave_port_ids[3],
1709 (unsigned int)port_stats.ipackets, 0);
1712 for (i = 0; i < MAX_PKT_BURST; i++) {
1713 if (rx_pkt_burst[i] != NULL)
1714 rte_pktmbuf_free(rx_pkt_burst[i]);
1717 /* Clean up and remove slaves from bonded device */
1718 return remove_slaves_and_stop_bonded_device();
1722 test_roundrobin_verify_mac_assignment(void)
1724 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1728 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1729 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1731 /* Initialize bonded device with 4 slaves in round robin mode */
1732 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1733 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1734 "Failed to initialize bonded device with slaves");
1736 /* Verify that all MACs are the same as first slave added to bonded dev */
1737 for (i = 0; i < test_params->bonded_slave_count; i++) {
1738 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1739 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1740 sizeof(read_mac_addr)),
1741 "slave port (%d) mac address not set to that of primary port",
1742 test_params->slave_port_ids[i]);
1745 /* change primary and verify that MAC addresses haven't changed */
1746 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1747 test_params->slave_port_ids[2]),
1748 "Failed to set bonded port (%d) primary port to (%d)",
1749 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1751 for (i = 0; i < test_params->bonded_slave_count; i++) {
1752 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1753 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1754 sizeof(read_mac_addr)),
1755 "slave port (%d) mac address has changed to that of primary"
1756 " port without stop/start toggle of bonded device",
1757 test_params->slave_port_ids[i]);
1760 /* stop / start bonded device and verify that primary MAC address is
1761 * propagate to bonded device and slaves */
1762 rte_eth_dev_stop(test_params->bonded_port_id);
1764 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1765 "Failed to start bonded device");
1767 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1768 TEST_ASSERT_SUCCESS(
1769 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1770 "bonded port (%d) mac address not set to that of new primary port",
1771 test_params->slave_port_ids[i]);
1773 for (i = 0; i < test_params->bonded_slave_count; i++) {
1774 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1775 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1776 sizeof(read_mac_addr)),
1777 "slave port (%d) mac address not set to that of new primary"
1778 " port", test_params->slave_port_ids[i]);
1781 /* Set explicit MAC address */
1782 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1783 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1784 "Failed to set MAC");
1786 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1787 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1788 sizeof(read_mac_addr)),
1789 "bonded port (%d) mac address not set to that of new primary port",
1790 test_params->slave_port_ids[i]);
1792 for (i = 0; i < test_params->bonded_slave_count; i++) {
1793 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1794 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1795 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1796 " that of new primary port\n", test_params->slave_port_ids[i]);
1799 /* Clean up and remove slaves from bonded device */
1800 return remove_slaves_and_stop_bonded_device();
1804 test_roundrobin_verify_promiscuous_enable_disable(void)
1806 int i, promiscuous_en;
1808 /* Initialize bonded device with 4 slaves in round robin mode */
1809 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1810 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1811 "Failed to initialize bonded device with slaves");
1813 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1815 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1816 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1817 "Port (%d) promiscuous mode not enabled",
1818 test_params->bonded_port_id);
1820 for (i = 0; i < test_params->bonded_slave_count; i++) {
1821 promiscuous_en = rte_eth_promiscuous_get(
1822 test_params->slave_port_ids[i]);
1823 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1824 "slave port (%d) promiscuous mode not enabled",
1825 test_params->slave_port_ids[i]);
1828 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1830 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1831 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1832 "Port (%d) promiscuous mode not disabled\n",
1833 test_params->bonded_port_id);
1835 for (i = 0; i < test_params->bonded_slave_count; i++) {
1836 promiscuous_en = rte_eth_promiscuous_get(
1837 test_params->slave_port_ids[i]);
1838 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1839 "Port (%d) promiscuous mode not disabled\n",
1840 test_params->slave_port_ids[i]);
1843 /* Clean up and remove slaves from bonded device */
1844 return remove_slaves_and_stop_bonded_device();
1847 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1848 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1851 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1853 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1854 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1855 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1857 struct rte_eth_stats port_stats;
1858 uint8_t slaves[RTE_MAX_ETHPORTS];
1860 int i, burst_size, slave_count;
1862 /* NULL all pointers in array to simplify cleanup */
1863 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1865 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1866 * in round robin mode */
1867 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1868 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1869 "Failed to initialize bonded device with slaves");
1871 /* Verify Current Slaves Count /Active Slave Count is */
1872 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1874 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1875 "Number of slaves (%d) is not as expected (%d).",
1876 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1878 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1879 slaves, RTE_MAX_ETHPORTS);
1880 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1881 "Number of active slaves (%d) is not as expected (%d).",
1882 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1884 /* Set 2 slaves eth_devs link status to down */
1885 virtual_ethdev_simulate_link_status_interrupt(
1886 test_params->slave_port_ids[1], 0);
1887 virtual_ethdev_simulate_link_status_interrupt(
1888 test_params->slave_port_ids[3], 0);
1890 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1891 slaves, RTE_MAX_ETHPORTS);
1892 TEST_ASSERT_EQUAL(slave_count,
1893 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1894 "Number of active slaves (%d) is not as expected (%d).\n",
1895 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1899 /* Verify that pkts are not sent on slaves with link status down:
1901 * 1. Generate test burst of traffic
1902 * 2. Transmit burst on bonded eth_dev
1903 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1904 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1907 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1908 burst_size, "generate_test_burst failed");
1910 rte_eth_stats_reset(test_params->bonded_port_id);
1914 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1915 burst_size), burst_size, "rte_eth_tx_burst failed");
1917 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1918 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1919 "Port (%d) opackets stats (%d) not expected (%d) value",
1920 test_params->bonded_port_id, (int)port_stats.opackets,
1923 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1924 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1925 "Port (%d) opackets stats (%d) not expected (%d) value",
1926 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1928 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1929 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1930 "Port (%d) opackets stats (%d) not expected (%d) value",
1931 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1933 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1934 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1935 "Port (%d) opackets stats (%d) not expected (%d) value",
1936 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1938 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1939 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1940 "Port (%d) opackets stats (%d) not expected (%d) value",
1941 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1943 /* Verify that pkts are not sent on slaves with link status down:
1945 * 1. Generate test bursts of traffic
1946 * 2. Add bursts on to virtual eth_devs
1947 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1948 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1949 * 4. Verify stats for bonded eth_dev
1950 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1952 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1953 TEST_ASSERT_EQUAL(generate_test_burst(
1954 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1955 burst_size, "failed to generate packet burst");
1957 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1958 &gen_pkt_burst[i][0], burst_size);
1961 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1962 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1963 burst_size + burst_size,
1964 "rte_eth_rx_burst failed");
1966 /* Verify bonded device rx count */
1967 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1968 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1969 "(%d) port_stats.ipackets not as expected\n",
1970 test_params->bonded_port_id);
1973 for (i = 0; i < MAX_PKT_BURST; i++) {
1974 if (rx_pkt_burst[i] != NULL)
1975 rte_pktmbuf_free(rx_pkt_burst[i]);
1977 if (gen_pkt_burst[1][i] != NULL)
1978 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1980 if (gen_pkt_burst[3][i] != NULL)
1981 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1984 /* Clean up and remove slaves from bonded device */
1985 return remove_slaves_and_stop_bonded_device();
1988 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1990 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1993 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1996 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1998 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1999 char slave_name[RTE_ETH_NAME_MAX_LEN];
2003 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2004 /* Generate slave name / MAC address */
2005 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2006 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2008 /* Create slave devices with no ISR Support */
2009 if (polling_test_slaves[i] == -1) {
2010 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2011 rte_socket_id(), 0);
2012 TEST_ASSERT(polling_test_slaves[i] >= 0,
2013 "Failed to create virtual virtual ethdev %s\n", slave_name);
2015 /* Configure slave */
2016 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2017 "Failed to configure virtual ethdev %s(%d)", slave_name,
2018 polling_test_slaves[i]);
2021 /* Add slave to bonded device */
2022 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2023 polling_test_slaves[i]),
2024 "Failed to add slave %s(%d) to bonded device %d",
2025 slave_name, polling_test_slaves[i],
2026 test_params->bonded_port_id);
2029 /* Initialize bonded device */
2030 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2031 "Failed to configure bonded device %d",
2032 test_params->bonded_port_id);
2035 /* Register link status change interrupt callback */
2036 rte_eth_dev_callback_register(test_params->bonded_port_id,
2037 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2038 &test_params->bonded_port_id);
2040 /* link status change callback for first slave link up */
2041 test_lsc_interrupt_count = 0;
2043 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2045 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2048 /* no link status change callback for second slave link up */
2049 test_lsc_interrupt_count = 0;
2051 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2053 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2055 /* link status change callback for both slave links down */
2056 test_lsc_interrupt_count = 0;
2058 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2059 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2061 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2063 /* Un-Register link status change interrupt callback */
2064 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2065 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2066 &test_params->bonded_port_id);
2069 /* Clean up and remove slaves from bonded device */
2070 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2072 TEST_ASSERT_SUCCESS(
2073 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2074 polling_test_slaves[i]),
2075 "Failed to remove slave %d from bonded port (%d)",
2076 polling_test_slaves[i], test_params->bonded_port_id);
2079 return remove_slaves_and_stop_bonded_device();
2083 /** Active Backup Mode Tests */
2086 test_activebackup_tx_burst(void)
2088 int i, pktlen, primary_port, burst_size;
2089 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2090 struct rte_eth_stats port_stats;
2092 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2093 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2094 "Failed to initialize bonded device with slaves");
2096 initialize_eth_header(test_params->pkt_eth_hdr,
2097 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 1, 0, 0);
2098 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2100 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2101 dst_addr_0, pktlen);
2103 burst_size = 20 * test_params->bonded_slave_count;
2105 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2106 "Burst size specified is greater than supported.");
2108 /* Generate a burst of packets to transmit */
2109 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2110 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2111 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2112 burst_size, "failed to generate burst correctly");
2114 /* Send burst on bonded port */
2115 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2116 burst_size), burst_size, "tx burst failed");
2118 /* Verify bonded port tx stats */
2119 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2120 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2121 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2122 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2125 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2127 /* Verify slave ports tx stats */
2128 for (i = 0; i < test_params->bonded_slave_count; i++) {
2129 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2130 if (test_params->slave_port_ids[i] == primary_port) {
2131 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2132 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2133 test_params->bonded_port_id,
2134 (unsigned int)port_stats.opackets,
2135 burst_size / test_params->bonded_slave_count);
2137 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2138 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2139 test_params->bonded_port_id,
2140 (unsigned int)port_stats.opackets, 0);
2144 /* Put all slaves down and try and transmit */
2145 for (i = 0; i < test_params->bonded_slave_count; i++) {
2146 virtual_ethdev_simulate_link_status_interrupt(
2147 test_params->slave_port_ids[i], 0);
2150 /* Send burst on bonded port */
2151 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2152 pkts_burst, burst_size), 0, "Sending empty burst failed");
2154 /* Clean up and remove slaves from bonded device */
2155 return remove_slaves_and_stop_bonded_device();
2158 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2161 test_activebackup_rx_burst(void)
2163 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2164 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2166 struct rte_eth_stats port_stats;
2170 int i, j, burst_size = 17;
2172 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2173 BONDING_MODE_ACTIVE_BACKUP, 0,
2174 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2175 "Failed to initialize bonded device with slaves");
2177 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2178 TEST_ASSERT(primary_port >= 0,
2179 "failed to get primary slave for bonded port (%d)",
2180 test_params->bonded_port_id);
2182 for (i = 0; i < test_params->bonded_slave_count; i++) {
2183 /* Generate test bursts of packets to transmit */
2184 TEST_ASSERT_EQUAL(generate_test_burst(
2185 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2186 burst_size, "burst generation failed");
2188 /* Add rx data to slave */
2189 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2190 &gen_pkt_burst[0], burst_size);
2192 /* Call rx burst on bonded device */
2193 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2194 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2195 "rte_eth_rx_burst failed");
2197 if (test_params->slave_port_ids[i] == primary_port) {
2198 /* Verify bonded device rx count */
2199 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2200 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2201 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2202 test_params->bonded_port_id,
2203 (unsigned int)port_stats.ipackets, burst_size);
2205 /* Verify bonded slave devices rx count */
2206 for (j = 0; j < test_params->bonded_slave_count; j++) {
2207 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2209 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2210 "Slave Port (%d) ipackets value (%u) not as "
2211 "expected (%d)", test_params->slave_port_ids[i],
2212 (unsigned int)port_stats.ipackets, burst_size);
2214 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2215 "Slave Port (%d) ipackets value (%u) not as "
2216 "expected (%d)\n", test_params->slave_port_ids[i],
2217 (unsigned int)port_stats.ipackets, 0);
2221 for (j = 0; j < test_params->bonded_slave_count; j++) {
2222 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2223 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2224 "Slave Port (%d) ipackets value (%u) not as expected "
2225 "(%d)", test_params->slave_port_ids[i],
2226 (unsigned int)port_stats.ipackets, 0);
2231 for (i = 0; i < MAX_PKT_BURST; i++) {
2232 if (rx_pkt_burst[i] != NULL) {
2233 rte_pktmbuf_free(rx_pkt_burst[i]);
2234 rx_pkt_burst[i] = NULL;
2238 /* reset bonded device stats */
2239 rte_eth_stats_reset(test_params->bonded_port_id);
2242 /* Clean up and remove slaves from bonded device */
2243 return remove_slaves_and_stop_bonded_device();
2247 test_activebackup_verify_promiscuous_enable_disable(void)
2249 int i, primary_port, promiscuous_en;
2251 /* Initialize bonded device with 4 slaves in round robin mode */
2252 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2253 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2254 "Failed to initialize bonded device with slaves");
2256 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2257 TEST_ASSERT(primary_port >= 0,
2258 "failed to get primary slave for bonded port (%d)",
2259 test_params->bonded_port_id);
2261 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2263 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2264 "Port (%d) promiscuous mode not enabled",
2265 test_params->bonded_port_id);
2267 for (i = 0; i < test_params->bonded_slave_count; i++) {
2268 promiscuous_en = rte_eth_promiscuous_get(
2269 test_params->slave_port_ids[i]);
2270 if (primary_port == test_params->slave_port_ids[i]) {
2271 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2272 "slave port (%d) promiscuous mode not enabled",
2273 test_params->slave_port_ids[i]);
2275 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2276 "slave port (%d) promiscuous mode enabled",
2277 test_params->slave_port_ids[i]);
2282 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2284 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2285 "Port (%d) promiscuous mode not disabled\n",
2286 test_params->bonded_port_id);
2288 for (i = 0; i < test_params->bonded_slave_count; i++) {
2289 promiscuous_en = rte_eth_promiscuous_get(
2290 test_params->slave_port_ids[i]);
2291 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2292 "slave port (%d) promiscuous mode not disabled\n",
2293 test_params->slave_port_ids[i]);
2296 /* Clean up and remove slaves from bonded device */
2297 return remove_slaves_and_stop_bonded_device();
2301 test_activebackup_verify_mac_assignment(void)
2303 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2305 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2306 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2308 /* Initialize bonded device with 2 slaves in active backup mode */
2309 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2310 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2311 "Failed to initialize bonded device with slaves");
2313 /* Verify that bonded MACs is that of first slave and that the other slave
2314 * MAC hasn't been changed */
2315 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2317 sizeof(read_mac_addr)),
2318 "bonded port (%d) mac address not set to that of primary port",
2319 test_params->bonded_port_id);
2321 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2323 sizeof(read_mac_addr)),
2324 "slave port (%d) mac address not set to that of primary port",
2325 test_params->slave_port_ids[0]);
2327 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2328 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2329 sizeof(read_mac_addr)),
2330 "slave port (%d) mac address not as expected",
2331 test_params->slave_port_ids[1]);
2333 /* change primary and verify that MAC addresses haven't changed */
2334 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2335 test_params->slave_port_ids[1]), 0,
2336 "Failed to set bonded port (%d) primary port to (%d)",
2337 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2339 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2340 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2341 sizeof(read_mac_addr)),
2342 "bonded port (%d) mac address not set to that of primary port",
2343 test_params->bonded_port_id);
2345 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2347 sizeof(read_mac_addr)),
2348 "slave port (%d) mac address not set to that of primary port",
2349 test_params->slave_port_ids[0]);
2351 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2352 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2353 sizeof(read_mac_addr)),
2354 "slave port (%d) mac address not as expected",
2355 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 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2363 "Failed to start device");
2365 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2367 sizeof(read_mac_addr)),
2368 "bonded port (%d) mac address not set to that of primary port",
2369 test_params->bonded_port_id);
2371 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2372 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2373 sizeof(read_mac_addr)),
2374 "slave port (%d) mac address not as expected",
2375 test_params->slave_port_ids[0]);
2377 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2378 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2379 sizeof(read_mac_addr)),
2380 "slave port (%d) mac address not set to that of primary port",
2381 test_params->slave_port_ids[1]);
2383 /* Set explicit MAC address */
2384 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2385 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2386 "failed to set MAC address");
2388 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2389 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2390 sizeof(read_mac_addr)),
2391 "bonded port (%d) mac address not set to that of bonded port",
2392 test_params->bonded_port_id);
2394 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2395 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2396 sizeof(read_mac_addr)),
2397 "slave port (%d) mac address not as expected",
2398 test_params->slave_port_ids[0]);
2400 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2401 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2402 sizeof(read_mac_addr)),
2403 "slave port (%d) mac address not set to that of bonded port",
2404 test_params->slave_port_ids[1]);
2406 /* Clean up and remove slaves from bonded device */
2407 return remove_slaves_and_stop_bonded_device();
2411 test_activebackup_verify_slave_link_status_change_failover(void)
2413 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2414 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2415 struct rte_eth_stats port_stats;
2417 uint8_t slaves[RTE_MAX_ETHPORTS];
2419 int i, j, burst_size, slave_count, primary_port;
2423 memset(pkt_burst, 0, sizeof(pkt_burst));
2425 /* Generate packet burst for testing */
2426 TEST_ASSERT_EQUAL(generate_test_burst(
2427 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2428 "generate_test_burst failed");
2430 /* Initialize bonded device with 4 slaves in round robin mode */
2431 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2432 BONDING_MODE_ACTIVE_BACKUP, 0,
2433 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2434 "Failed to initialize bonded device with slaves");
2436 /* Verify Current Slaves Count /Active Slave Count is */
2437 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2439 TEST_ASSERT_EQUAL(slave_count, 4,
2440 "Number of slaves (%d) is not as expected (%d).",
2443 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2444 slaves, RTE_MAX_ETHPORTS);
2445 TEST_ASSERT_EQUAL(slave_count, 4,
2446 "Number of active slaves (%d) is not as expected (%d).",
2449 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2450 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2451 "Primary port not as expected");
2453 /* Bring 2 slaves down and verify active slave count */
2454 virtual_ethdev_simulate_link_status_interrupt(
2455 test_params->slave_port_ids[1], 0);
2456 virtual_ethdev_simulate_link_status_interrupt(
2457 test_params->slave_port_ids[3], 0);
2459 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2460 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2461 "Number of active slaves (%d) is not as expected (%d).",
2464 virtual_ethdev_simulate_link_status_interrupt(
2465 test_params->slave_port_ids[1], 1);
2466 virtual_ethdev_simulate_link_status_interrupt(
2467 test_params->slave_port_ids[3], 1);
2470 /* Bring primary port down, verify that active slave count is 3 and primary
2472 virtual_ethdev_simulate_link_status_interrupt(
2473 test_params->slave_port_ids[0], 0);
2475 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2476 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2478 "Number of active slaves (%d) is not as expected (%d).",
2481 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2482 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2483 "Primary port not as expected");
2485 /* Verify that pkts are sent on new primary slave */
2487 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2488 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2489 burst_size), burst_size, "rte_eth_tx_burst failed");
2491 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2492 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2493 "(%d) port_stats.opackets not as expected",
2494 test_params->slave_port_ids[2]);
2496 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2497 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2498 "(%d) port_stats.opackets not as expected\n",
2499 test_params->slave_port_ids[0]);
2501 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2502 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2503 "(%d) port_stats.opackets not as expected\n",
2504 test_params->slave_port_ids[1]);
2506 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2507 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2508 "(%d) port_stats.opackets not as expected\n",
2509 test_params->slave_port_ids[3]);
2511 /* Generate packet burst for testing */
2513 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2514 TEST_ASSERT_EQUAL(generate_test_burst(
2515 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2516 "generate_test_burst failed");
2518 virtual_ethdev_add_mbufs_to_rx_queue(
2519 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2522 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2523 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2524 burst_size, "rte_eth_rx_burst\n");
2526 /* Verify bonded device rx count */
2527 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2528 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2529 "(%d) port_stats.ipackets not as expected",
2530 test_params->bonded_port_id);
2532 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2533 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2534 "(%d) port_stats.opackets not as expected",
2535 test_params->slave_port_ids[2]);
2537 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2538 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2539 "(%d) port_stats.opackets not as expected",
2540 test_params->slave_port_ids[0]);
2542 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2543 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2544 "(%d) port_stats.opackets not as expected",
2545 test_params->slave_port_ids[1]);
2547 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2548 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2549 "(%d) port_stats.opackets not as expected",
2550 test_params->slave_port_ids[3]);
2553 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2554 for (j = 0; j < MAX_PKT_BURST; j++) {
2555 if (pkt_burst[i][j] != NULL) {
2556 rte_pktmbuf_free(pkt_burst[i][j]);
2557 pkt_burst[i][j] = NULL;
2562 /* Clean up and remove slaves from bonded device */
2563 return remove_slaves_and_stop_bonded_device();
2566 /** Balance Mode Tests */
2569 test_balance_xmit_policy_configuration(void)
2571 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2572 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2573 "Failed to initialize_bonded_device_with_slaves.");
2575 /* Invalid port id */
2576 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2577 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2578 "Expected call to failed as invalid port specified.");
2580 /* Set xmit policy on non bonded device */
2581 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2582 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2583 "Expected call to failed as invalid port specified.");
2586 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2587 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2588 "Failed to set balance xmit policy.");
2590 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2591 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2594 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2595 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2596 "Failed to set balance xmit policy.");
2598 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2599 BALANCE_XMIT_POLICY_LAYER23,
2600 "balance xmit policy not as expected.");
2603 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2604 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2605 "Failed to set balance xmit policy.");
2607 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2608 BALANCE_XMIT_POLICY_LAYER34,
2609 "balance xmit policy not as expected.");
2611 /* Invalid port id */
2612 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2613 "Expected call to failed as invalid port specified.");
2615 /* Clean up and remove slaves from bonded device */
2616 return remove_slaves_and_stop_bonded_device();
2619 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2622 test_balance_l2_tx_burst(void)
2624 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2625 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2629 struct rte_eth_stats port_stats;
2631 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2632 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2633 "Failed to initialize_bonded_device_with_slaves.");
2635 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2636 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2637 "Failed to set balance xmit policy.");
2639 initialize_eth_header(test_params->pkt_eth_hdr,
2640 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 1, 0, 0);
2641 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2643 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2644 dst_addr_0, pktlen);
2646 /* Generate a burst 1 of packets to transmit */
2647 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2648 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2649 test_params->pkt_udp_hdr, burst_size[0],
2650 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2651 "failed to generate packet burst");
2653 initialize_eth_header(test_params->pkt_eth_hdr,
2654 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 1, 0, 0);
2656 /* Generate a burst 2 of packets to transmit */
2657 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2658 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2659 test_params->pkt_udp_hdr, burst_size[1],
2660 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2661 "failed to generate packet burst");
2663 /* Send burst 1 on bonded port */
2664 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2665 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2666 &pkts_burst[i][0], burst_size[i]),
2667 burst_size[i], "Failed to transmit packet burst");
2670 /* Verify bonded port tx stats */
2671 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2672 TEST_ASSERT_EQUAL(port_stats.opackets,
2673 (uint64_t)(burst_size[0] + burst_size[1]),
2674 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2675 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2676 burst_size[0] + burst_size[1]);
2679 /* Verify slave ports tx stats */
2680 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2681 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2682 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2683 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2686 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2687 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2688 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2689 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2692 /* Put all slaves down and try and transmit */
2693 for (i = 0; i < test_params->bonded_slave_count; i++) {
2695 virtual_ethdev_simulate_link_status_interrupt(
2696 test_params->slave_port_ids[i], 0);
2699 /* Send burst on bonded port */
2700 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2701 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2702 0, "Expected zero packet");
2704 /* Clean up and remove slaves from bonded device */
2705 return remove_slaves_and_stop_bonded_device();
2709 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2710 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2712 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2714 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2715 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2717 struct rte_eth_stats port_stats;
2719 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2720 BONDING_MODE_BALANCE, 0, 2, 1),
2721 "Failed to initialize_bonded_device_with_slaves.");
2723 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2724 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2725 "Failed to set balance xmit policy.");
2730 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2731 "Burst size specified is greater than supported.");
2733 /* Generate test bursts of packets to transmit */
2734 TEST_ASSERT_EQUAL(generate_test_burst(
2735 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2736 burst_size_1, "failed to generate packet burst");
2738 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2739 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2740 "failed to generate packet burst");
2742 /* Send burst 1 on bonded port */
2743 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2745 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2747 /* Send burst 2 on bonded port */
2748 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2750 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2752 /* Verify bonded port tx stats */
2753 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2754 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2755 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2756 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2759 /* Verify slave ports tx stats */
2760 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2761 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2762 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2763 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2766 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2767 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2768 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2769 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2772 /* Put all slaves down and try and transmit */
2773 for (i = 0; i < test_params->bonded_slave_count; i++) {
2775 virtual_ethdev_simulate_link_status_interrupt(
2776 test_params->slave_port_ids[i], 0);
2779 /* Send burst on bonded port */
2780 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2781 test_params->bonded_port_id, 0, pkts_burst_1,
2782 burst_size_1), 0, "Expected zero packet");
2785 /* Clean up and remove slaves from bonded device */
2786 return remove_slaves_and_stop_bonded_device();
2790 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2792 return balance_l23_tx_burst(0, 1, 1, 0);
2796 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2798 return balance_l23_tx_burst(1, 1, 0, 1);
2802 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2804 return balance_l23_tx_burst(0, 0, 0, 1);
2808 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2810 return balance_l23_tx_burst(1, 0, 0, 1);
2814 test_balance_l23_tx_burst_toggle_mac_addr(void)
2816 return balance_l23_tx_burst(0, 0, 1, 0);
2820 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2821 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2822 uint8_t toggle_udp_port)
2824 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2826 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2827 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2829 struct rte_eth_stats port_stats;
2831 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2832 BONDING_MODE_BALANCE, 0, 2, 1),
2833 "Failed to initialize_bonded_device_with_slaves.");
2835 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2836 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2837 "Failed to set balance xmit policy.");
2842 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2843 "Burst size specified is greater than supported.");
2845 /* Generate test bursts of packets to transmit */
2846 TEST_ASSERT_EQUAL(generate_test_burst(
2847 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2848 burst_size_1, "failed to generate burst");
2850 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2851 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2852 toggle_udp_port), burst_size_2, "failed to generate burst");
2854 /* Send burst 1 on bonded port */
2855 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2857 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2859 /* Send burst 2 on bonded port */
2860 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2862 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2865 /* Verify bonded port tx stats */
2866 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2867 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2868 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2869 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2872 /* Verify slave ports tx stats */
2873 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2874 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2875 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2876 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2879 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2880 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2881 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2882 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2885 /* Put all slaves down and try and transmit */
2886 for (i = 0; i < test_params->bonded_slave_count; i++) {
2888 virtual_ethdev_simulate_link_status_interrupt(
2889 test_params->slave_port_ids[i], 0);
2892 /* Send burst on bonded port */
2893 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2894 test_params->bonded_port_id, 0, pkts_burst_1,
2895 burst_size_1), 0, "Expected zero packet");
2897 /* Clean up and remove slaves from bonded device */
2898 return remove_slaves_and_stop_bonded_device();
2902 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2904 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2908 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2910 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2914 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2916 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2920 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2922 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2926 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2928 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2932 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2934 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2937 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2938 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2939 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2940 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2941 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2944 test_balance_tx_burst_slave_tx_fail(void)
2946 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2947 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2949 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2951 struct rte_eth_stats port_stats;
2953 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2955 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2956 BONDING_MODE_BALANCE, 0,
2957 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2958 "Failed to intialise bonded device");
2960 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2961 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2962 "Failed to set balance xmit policy.");
2965 /* Generate test bursts for transmission */
2966 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2967 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2968 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2969 "Failed to generate test packet burst 1");
2971 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2972 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2974 /* copy mbuf referneces for expected transmission failures */
2975 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2976 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2978 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2979 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2980 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2981 "Failed to generate test packet burst 2");
2984 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2985 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2986 virtual_ethdev_tx_burst_fn_set_success(
2987 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2990 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2991 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2992 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2995 /* Transmit burst 1 */
2996 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2997 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2999 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3000 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3001 "Transmitted (%d) packets, expected to transmit (%d) packets",
3002 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3003 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3005 /* Verify that failed packet are expected failed packets */
3006 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3007 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3008 "expected mbuf (%d) pointer %p not expected pointer %p",
3009 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3012 /* Transmit burst 2 */
3013 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3014 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3016 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3017 "Transmitted (%d) packets, expected to transmit (%d) packets",
3018 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3021 /* Verify bonded port tx stats */
3022 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3024 TEST_ASSERT_EQUAL(port_stats.opackets,
3025 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3026 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3027 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3028 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3029 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3030 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3031 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3032 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3034 /* Verify slave ports tx stats */
3036 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3038 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3039 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3040 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3041 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3042 test_params->slave_port_ids[0],
3043 (unsigned int)port_stats.opackets,
3044 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3045 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3050 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3052 TEST_ASSERT_EQUAL(port_stats.opackets,
3053 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3054 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3055 test_params->slave_port_ids[1],
3056 (unsigned int)port_stats.opackets,
3057 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3059 #ifdef RTE_MBUF_REFCNT
3060 /* Verify that all mbufs have a ref value of zero */
3061 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3062 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3063 "mbufs refcnts not as expected");
3066 free_mbufs(&pkts_burst_1[tx_count_1],
3067 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3069 /* Clean up and remove slaves from bonded device */
3070 return remove_slaves_and_stop_bonded_device();
3073 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3076 test_balance_rx_burst(void)
3078 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3080 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3081 struct rte_eth_stats port_stats;
3083 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3086 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3088 /* Initialize bonded device with 4 slaves in round robin mode */
3089 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3090 BONDING_MODE_BALANCE, 0, 3, 1),
3091 "Failed to intialise bonded device");
3093 /* Generate test bursts of packets to transmit */
3094 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3095 TEST_ASSERT_EQUAL(generate_test_burst(
3096 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3097 0, 0), burst_size[i],
3098 "failed to generate packet burst");
3101 /* Add rx data to slaves */
3102 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3103 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3104 &gen_pkt_burst[i][0], burst_size[i]);
3107 /* Call rx burst on bonded device */
3108 /* Send burst on bonded port */
3109 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3110 rx_pkt_burst, MAX_PKT_BURST),
3111 burst_size[0] + burst_size[1] + burst_size[2],
3112 "balance rx burst failed\n");
3114 /* Verify bonded device rx count */
3115 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3116 TEST_ASSERT_EQUAL(port_stats.ipackets,
3117 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3118 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3119 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3120 burst_size[0] + burst_size[1] + burst_size[2]);
3123 /* Verify bonded slave devices rx counts */
3124 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3125 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3126 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3127 test_params->slave_port_ids[0],
3128 (unsigned int)port_stats.ipackets, burst_size[0]);
3130 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3131 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3132 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3133 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3136 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3137 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3138 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3139 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3142 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3143 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3144 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3145 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3149 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3150 for (j = 0; j < MAX_PKT_BURST; j++) {
3151 if (gen_pkt_burst[i][j] != NULL) {
3152 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3153 gen_pkt_burst[i][j] = NULL;
3158 /* Clean up and remove slaves from bonded device */
3159 return remove_slaves_and_stop_bonded_device();
3163 test_balance_verify_promiscuous_enable_disable(void)
3167 /* Initialize bonded device with 4 slaves in round robin mode */
3168 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3169 BONDING_MODE_BALANCE, 0, 4, 1),
3170 "Failed to intialise bonded device");
3172 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3174 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3175 "Port (%d) promiscuous mode not enabled",
3176 test_params->bonded_port_id);
3178 for (i = 0; i < test_params->bonded_slave_count; i++) {
3179 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3180 test_params->slave_port_ids[i]), 1,
3181 "Port (%d) promiscuous mode not enabled",
3182 test_params->slave_port_ids[i]);
3185 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3187 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3188 "Port (%d) promiscuous mode not disabled",
3189 test_params->bonded_port_id);
3191 for (i = 0; i < test_params->bonded_slave_count; i++) {
3192 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3193 test_params->slave_port_ids[i]), 0,
3194 "Port (%d) promiscuous mode not disabled",
3195 test_params->slave_port_ids[i]);
3198 /* Clean up and remove slaves from bonded device */
3199 return remove_slaves_and_stop_bonded_device();
3203 test_balance_verify_mac_assignment(void)
3205 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3207 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3208 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3210 /* Initialize bonded device with 2 slaves in active backup mode */
3211 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3212 BONDING_MODE_BALANCE, 0, 2, 1),
3213 "Failed to intialise bonded device");
3215 /* Verify that bonded MACs is that of first slave and that the other slave
3216 * MAC hasn't been changed */
3217 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3218 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3219 sizeof(read_mac_addr)),
3220 "bonded port (%d) mac address not set to that of primary port",
3221 test_params->bonded_port_id);
3223 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3224 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3225 sizeof(read_mac_addr)),
3226 "slave port (%d) mac address not set to that of primary port",
3227 test_params->slave_port_ids[0]);
3229 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3230 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3231 sizeof(read_mac_addr)),
3232 "slave port (%d) mac address not set to that of primary port",
3233 test_params->slave_port_ids[1]);
3235 /* change primary and verify that MAC addresses haven't changed */
3236 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3237 test_params->slave_port_ids[1]),
3238 "Failed to set bonded port (%d) primary port to (%d)\n",
3239 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3241 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3242 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3243 sizeof(read_mac_addr)),
3244 "bonded port (%d) mac address not set to that of primary port",
3245 test_params->bonded_port_id);
3247 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3248 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3249 sizeof(read_mac_addr)),
3250 "slave port (%d) mac address not set to that of primary port",
3251 test_params->slave_port_ids[0]);
3253 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3254 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3255 sizeof(read_mac_addr)),
3256 "slave port (%d) mac address not set to that of primary port",
3257 test_params->slave_port_ids[1]);
3259 /* stop / start bonded device and verify that primary MAC address is
3260 * propagated to bonded device and slaves */
3262 rte_eth_dev_stop(test_params->bonded_port_id);
3264 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3265 "Failed to start bonded device");
3267 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3268 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3269 sizeof(read_mac_addr)),
3270 "bonded port (%d) mac address not set to that of primary port",
3271 test_params->bonded_port_id);
3273 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3274 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3275 sizeof(read_mac_addr)),
3276 "slave port (%d) mac address not set to that of primary port",
3277 test_params->slave_port_ids[0]);
3279 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3280 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3281 sizeof(read_mac_addr)),
3282 "slave port (%d) mac address not set to that of primary port",
3283 test_params->slave_port_ids[1]);
3285 /* Set explicit MAC address */
3286 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3287 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3288 "failed to set MAC");
3290 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3291 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3292 sizeof(read_mac_addr)),
3293 "bonded port (%d) mac address not set to that of bonded port",
3294 test_params->bonded_port_id);
3296 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3297 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3298 sizeof(read_mac_addr)),
3299 "slave port (%d) mac address not as expected\n",
3300 test_params->slave_port_ids[0]);
3302 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3303 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3304 sizeof(read_mac_addr)),
3305 "slave port (%d) mac address not set to that of bonded port",
3306 test_params->slave_port_ids[1]);
3308 /* Clean up and remove slaves from bonded device */
3309 return remove_slaves_and_stop_bonded_device();
3312 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3315 test_balance_verify_slave_link_status_change_behaviour(void)
3317 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3318 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3319 struct rte_eth_stats port_stats;
3321 uint8_t slaves[RTE_MAX_ETHPORTS];
3323 int i, j, burst_size, slave_count;
3325 memset(pkt_burst, 0, sizeof(pkt_burst));
3327 /* Initialize bonded device with 4 slaves in round robin mode */
3328 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3329 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3330 "Failed to intialise bonded device");
3332 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3333 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3334 "Failed to set balance xmit policy.");
3337 /* Verify Current Slaves Count /Active Slave Count is */
3338 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3340 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3341 "Number of slaves (%d) is not as expected (%d).",
3342 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3344 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3345 slaves, RTE_MAX_ETHPORTS);
3346 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3347 "Number of active slaves (%d) is not as expected (%d).",
3348 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3350 /* Set 2 slaves link status to down */
3351 virtual_ethdev_simulate_link_status_interrupt(
3352 test_params->slave_port_ids[1], 0);
3353 virtual_ethdev_simulate_link_status_interrupt(
3354 test_params->slave_port_ids[3], 0);
3356 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3357 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3358 "Number of active slaves (%d) is not as expected (%d).",
3361 /* Send to sets of packet burst and verify that they are balanced across
3365 TEST_ASSERT_EQUAL(generate_test_burst(
3366 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3367 "generate_test_burst failed");
3369 TEST_ASSERT_EQUAL(generate_test_burst(
3370 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3371 "generate_test_burst failed");
3373 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3374 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3375 burst_size, "rte_eth_tx_burst failed");
3377 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3378 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3379 burst_size, "rte_eth_tx_burst failed");
3382 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3383 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3384 "(%d) port_stats.opackets (%d) not as expected (%d).",
3385 test_params->bonded_port_id, (int)port_stats.opackets,
3386 burst_size + burst_size);
3388 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3389 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3390 "(%d) port_stats.opackets (%d) not as expected (%d).",
3391 test_params->slave_port_ids[0], (int)port_stats.opackets,
3394 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3395 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3396 "(%d) port_stats.opackets (%d) not as expected (%d).",
3397 test_params->slave_port_ids[2], (int)port_stats.opackets,
3400 /* verify that all packets get send on primary slave when no other slaves
3402 virtual_ethdev_simulate_link_status_interrupt(
3403 test_params->slave_port_ids[2], 0);
3405 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3406 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3407 "Number of active slaves (%d) is not as expected (%d).",
3410 TEST_ASSERT_EQUAL(generate_test_burst(
3411 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3412 "generate_test_burst failed");
3414 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3415 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3416 burst_size, "rte_eth_tx_burst failed");
3418 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3419 TEST_ASSERT_EQUAL(port_stats.opackets,
3420 (uint64_t)(burst_size + burst_size + burst_size),
3421 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3422 test_params->bonded_port_id, (int)port_stats.opackets,
3423 burst_size + burst_size + burst_size);
3425 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3426 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3427 "(%d) port_stats.opackets (%d) not as expected (%d).",
3428 test_params->slave_port_ids[0], (int)port_stats.opackets,
3429 burst_size + burst_size);
3431 virtual_ethdev_simulate_link_status_interrupt(
3432 test_params->slave_port_ids[0], 0);
3433 virtual_ethdev_simulate_link_status_interrupt(
3434 test_params->slave_port_ids[1], 1);
3435 virtual_ethdev_simulate_link_status_interrupt(
3436 test_params->slave_port_ids[2], 1);
3437 virtual_ethdev_simulate_link_status_interrupt(
3438 test_params->slave_port_ids[3], 1);
3440 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3441 TEST_ASSERT_EQUAL(generate_test_burst(
3442 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3443 "Failed to generate packet burst");
3445 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3446 &pkt_burst[i][0], burst_size);
3449 /* Verify that pkts are not received on slaves with link status down */
3451 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3454 /* Verify bonded device rx count */
3455 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3456 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3457 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3458 test_params->bonded_port_id, (int)port_stats.ipackets,
3461 /* free mbufs allocate for rx testing */
3462 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3463 for (j = 0; j < MAX_PKT_BURST; j++) {
3464 if (pkt_burst[i][j] != NULL) {
3465 rte_pktmbuf_free(pkt_burst[i][j]);
3466 pkt_burst[i][j] = NULL;
3471 /* Clean up and remove slaves from bonded device */
3472 return remove_slaves_and_stop_bonded_device();
3475 #ifdef RTE_MBUF_REFCNT
3476 /** Broadcast Mode Tests */
3479 test_broadcast_tx_burst(void)
3481 int i, pktlen, burst_size;
3482 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3484 struct rte_eth_stats port_stats;
3486 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3487 BONDING_MODE_BROADCAST, 0, 2, 1),
3488 "Failed to intialise bonded device");
3490 initialize_eth_header(test_params->pkt_eth_hdr,
3491 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 1, 0, 0);
3493 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3495 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3496 dst_addr_0, pktlen);
3498 burst_size = 20 * test_params->bonded_slave_count;
3500 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3501 "Burst size specified is greater than supported.");
3503 /* Generate a burst of packets to transmit */
3504 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3505 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3506 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3507 1), burst_size, "Failed to generate packet burst");
3509 /* Send burst on bonded port */
3510 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3511 pkts_burst, burst_size), burst_size,
3512 "Bonded Port (%d) rx burst failed, packets transmitted value "
3513 "not as expected (%d)",
3514 test_params->bonded_port_id, burst_size);
3516 /* Verify bonded port tx stats */
3517 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3518 TEST_ASSERT_EQUAL(port_stats.opackets,
3519 (uint64_t)burst_size * test_params->bonded_slave_count,
3520 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3521 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3524 /* Verify slave ports tx stats */
3525 for (i = 0; i < test_params->bonded_slave_count; i++) {
3526 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3527 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3528 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3529 test_params->bonded_port_id,
3530 (unsigned int)port_stats.opackets, burst_size);
3533 /* Put all slaves down and try and transmit */
3534 for (i = 0; i < test_params->bonded_slave_count; i++) {
3536 virtual_ethdev_simulate_link_status_interrupt(
3537 test_params->slave_port_ids[i], 0);
3540 /* Send burst on bonded port */
3541 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3542 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3543 "transmitted an unexpected number of packets");
3545 /* Clean up and remove slaves from bonded device */
3546 return remove_slaves_and_stop_bonded_device();
3550 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3551 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3552 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3553 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3556 test_broadcast_tx_burst_slave_tx_fail(void)
3558 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3559 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3561 struct rte_eth_stats port_stats;
3565 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3566 BONDING_MODE_BROADCAST, 0,
3567 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3568 "Failed to intialise bonded device");
3570 /* Generate test bursts for transmission */
3571 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3572 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3573 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3574 "Failed to generate test packet burst");
3576 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3577 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3578 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3581 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3582 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3583 virtual_ethdev_tx_burst_fn_set_success(
3584 test_params->slave_port_ids[0],
3586 virtual_ethdev_tx_burst_fn_set_success(
3587 test_params->slave_port_ids[1],
3589 virtual_ethdev_tx_burst_fn_set_success(
3590 test_params->slave_port_ids[2],
3593 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3594 test_params->slave_port_ids[0],
3595 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3597 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3598 test_params->slave_port_ids[1],
3599 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3601 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3602 test_params->slave_port_ids[2],
3603 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3605 /* Transmit burst */
3606 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3607 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3609 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3610 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3611 "Transmitted (%d) packets, expected to transmit (%d) packets",
3612 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3613 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3615 /* Verify that failed packet are expected failed packets */
3616 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3617 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3618 "expected mbuf (%d) pointer %p not expected pointer %p",
3619 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3622 /* Verify slave ports tx stats */
3624 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3626 TEST_ASSERT_EQUAL(port_stats.opackets,
3627 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3628 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3629 "Port (%d) opackets value (%u) not as expected (%d)",
3630 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3631 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3632 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3635 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3637 TEST_ASSERT_EQUAL(port_stats.opackets,
3638 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3639 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3640 "Port (%d) opackets value (%u) not as expected (%d)",
3641 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3642 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3643 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3645 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3647 TEST_ASSERT_EQUAL(port_stats.opackets,
3648 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3649 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3650 "Port (%d) opackets value (%u) not as expected (%d)",
3651 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3652 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3653 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3656 /* Verify that all mbufs who transmission failed have a ref value of one */
3657 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3658 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3659 "mbufs refcnts not as expected");
3661 free_mbufs(&pkts_burst[tx_count],
3662 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3664 /* Clean up and remove slaves from bonded device */
3665 return remove_slaves_and_stop_bonded_device();
3668 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3671 test_broadcast_rx_burst(void)
3673 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3675 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3676 struct rte_eth_stats port_stats;
3678 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3681 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3683 /* Initialize bonded device with 4 slaves in round robin mode */
3684 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3685 BONDING_MODE_BROADCAST, 0, 3, 1),
3686 "Failed to intialise bonded device");
3688 /* Generate test bursts of packets to transmit */
3689 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3690 TEST_ASSERT_EQUAL(generate_test_burst(
3691 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3692 burst_size[i], "failed to generate packet burst");
3695 /* Add rx data to slave 0 */
3696 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3697 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3698 &gen_pkt_burst[i][0], burst_size[i]);
3702 /* Call rx burst on bonded device */
3703 /* Send burst on bonded port */
3704 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3705 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3706 burst_size[0] + burst_size[1] + burst_size[2],
3709 /* Verify bonded device rx count */
3710 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3711 TEST_ASSERT_EQUAL(port_stats.ipackets,
3712 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3713 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3714 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3715 burst_size[0] + burst_size[1] + burst_size[2]);
3718 /* Verify bonded slave devices rx counts */
3719 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3720 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3721 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3722 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3725 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3726 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3727 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3728 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3731 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3732 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3733 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3734 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3737 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3738 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3739 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3740 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3743 /* free mbufs allocate for rx testing */
3744 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3745 for (j = 0; j < MAX_PKT_BURST; j++) {
3746 if (gen_pkt_burst[i][j] != NULL) {
3747 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3748 gen_pkt_burst[i][j] = NULL;
3753 /* Clean up and remove slaves from bonded device */
3754 return remove_slaves_and_stop_bonded_device();
3758 test_broadcast_verify_promiscuous_enable_disable(void)
3762 /* Initialize bonded device with 4 slaves in round robin mode */
3763 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3764 BONDING_MODE_BROADCAST, 0, 4, 1),
3765 "Failed to intialise bonded device");
3767 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3770 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3771 "Port (%d) promiscuous mode not enabled",
3772 test_params->bonded_port_id);
3774 for (i = 0; i < test_params->bonded_slave_count; i++) {
3775 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3776 test_params->slave_port_ids[i]), 1,
3777 "Port (%d) promiscuous mode not enabled",
3778 test_params->slave_port_ids[i]);
3781 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3783 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3784 "Port (%d) promiscuous mode not disabled",
3785 test_params->bonded_port_id);
3787 for (i = 0; i < test_params->bonded_slave_count; i++) {
3788 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3789 test_params->slave_port_ids[i]), 0,
3790 "Port (%d) promiscuous mode not disabled",
3791 test_params->slave_port_ids[i]);
3794 /* Clean up and remove slaves from bonded device */
3795 return remove_slaves_and_stop_bonded_device();
3799 test_broadcast_verify_mac_assignment(void)
3801 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3805 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3806 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3808 /* Initialize bonded device with 4 slaves in round robin mode */
3809 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3810 BONDING_MODE_BROADCAST, 0, 4, 1),
3811 "Failed to intialise bonded device");
3813 /* Verify that all MACs are the same as first slave added to bonded
3815 for (i = 0; i < test_params->bonded_slave_count; i++) {
3816 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3817 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3818 sizeof(read_mac_addr)),
3819 "slave port (%d) mac address not set to that of primary port",
3820 test_params->slave_port_ids[i]);
3823 /* change primary and verify that MAC addresses haven't changed */
3824 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3825 test_params->slave_port_ids[2]),
3826 "Failed to set bonded port (%d) primary port to (%d)",
3827 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3829 for (i = 0; i < test_params->bonded_slave_count; i++) {
3830 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3831 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3832 sizeof(read_mac_addr)),
3833 "slave port (%d) mac address has changed to that of primary "
3834 "port without stop/start toggle of bonded device",
3835 test_params->slave_port_ids[i]);
3838 /* stop / start bonded device and verify that primary MAC address is
3839 * propagated to bonded device and slaves */
3841 rte_eth_dev_stop(test_params->bonded_port_id);
3843 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3844 "Failed to start bonded device");
3846 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3847 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3848 sizeof(read_mac_addr)),
3849 "bonded port (%d) mac address not set to that of new primary port",
3850 test_params->slave_port_ids[i]);
3852 for (i = 0; i < test_params->bonded_slave_count; i++) {
3853 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3854 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3855 sizeof(read_mac_addr)),
3856 "slave port (%d) mac address not set to that of new primary "
3857 "port", test_params->slave_port_ids[i]);
3860 /* Set explicit MAC address */
3861 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3862 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3863 "Failed to set MAC address");
3865 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3866 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3867 sizeof(read_mac_addr)),
3868 "bonded port (%d) mac address not set to that of new primary port",
3869 test_params->slave_port_ids[i]);
3872 for (i = 0; i < test_params->bonded_slave_count; i++) {
3873 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3874 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3875 sizeof(read_mac_addr)),
3876 "slave port (%d) mac address not set to that of new primary "
3877 "port", test_params->slave_port_ids[i]);
3880 /* Clean up and remove slaves from bonded device */
3881 return remove_slaves_and_stop_bonded_device();
3884 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3886 test_broadcast_verify_slave_link_status_change_behaviour(void)
3888 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3889 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3890 struct rte_eth_stats port_stats;
3892 uint8_t slaves[RTE_MAX_ETHPORTS];
3894 int i, j, burst_size, slave_count;
3896 memset(pkt_burst, 0, sizeof(pkt_burst));
3898 /* Initialize bonded device with 4 slaves in round robin mode */
3899 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3900 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3901 1), "Failed to intialise bonded device");
3903 /* Verify Current Slaves Count /Active Slave Count is */
3904 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3906 TEST_ASSERT_EQUAL(slave_count, 4,
3907 "Number of slaves (%d) is not as expected (%d).",
3910 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3911 slaves, RTE_MAX_ETHPORTS);
3912 TEST_ASSERT_EQUAL(slave_count, 4,
3913 "Number of active slaves (%d) is not as expected (%d).",
3916 /* Set 2 slaves link status to down */
3917 virtual_ethdev_simulate_link_status_interrupt(
3918 test_params->slave_port_ids[1], 0);
3919 virtual_ethdev_simulate_link_status_interrupt(
3920 test_params->slave_port_ids[3], 0);
3922 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3923 slaves, RTE_MAX_ETHPORTS);
3924 TEST_ASSERT_EQUAL(slave_count, 2,
3925 "Number of active slaves (%d) is not as expected (%d).",
3928 for (i = 0; i < test_params->bonded_slave_count; i++)
3929 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3931 /* Verify that pkts are not sent on slaves with link status down */
3934 TEST_ASSERT_EQUAL(generate_test_burst(
3935 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3936 "generate_test_burst failed");
3938 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3939 &pkt_burst[0][0], burst_size), burst_size,
3940 "rte_eth_tx_burst failed\n");
3942 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3943 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3944 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3945 test_params->bonded_port_id, (int)port_stats.opackets,
3946 burst_size * slave_count);
3948 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3949 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3950 "(%d) port_stats.opackets not as expected",
3951 test_params->slave_port_ids[0]);
3953 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3954 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3955 "(%d) port_stats.opackets not as expected",
3956 test_params->slave_port_ids[1]);
3958 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3959 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3960 "(%d) port_stats.opackets not as expected",
3961 test_params->slave_port_ids[2]);
3964 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3965 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3966 "(%d) port_stats.opackets not as expected",
3967 test_params->slave_port_ids[3]);
3970 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3971 TEST_ASSERT_EQUAL(generate_test_burst(
3972 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3973 burst_size, "failed to generate packet burst");
3975 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3976 &pkt_burst[i][0], burst_size);
3979 /* Verify that pkts are not received on slaves with link status down */
3980 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3981 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3982 burst_size + burst_size, "rte_eth_rx_burst failed");
3985 /* Verify bonded device rx count */
3986 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3987 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3988 "(%d) port_stats.ipackets not as expected\n",
3989 test_params->bonded_port_id);
3991 /* free mbufs allocate for rx testing */
3992 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3993 for (j = 0; j < MAX_PKT_BURST; j++) {
3994 if (pkt_burst[i][j] != NULL) {
3995 rte_pktmbuf_free(pkt_burst[i][j]);
3996 pkt_burst[i][j] = NULL;
4001 /* Clean up and remove slaves from bonded device */
4002 return remove_slaves_and_stop_bonded_device();
4007 test_reconfigure_bonded_device(void)
4009 test_params->nb_rx_q = 4;
4010 test_params->nb_tx_q = 4;
4012 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4013 "failed to reconfigure bonded device");
4015 test_params->nb_rx_q = 2;
4016 test_params->nb_tx_q = 2;
4018 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4019 "failed to reconfigure bonded device with less rx/tx queues");
4026 test_close_bonded_device(void)
4028 rte_eth_dev_close(test_params->bonded_port_id);
4033 testsuite_teardown(void)
4035 if (test_params->pkt_eth_hdr != NULL) {
4036 free(test_params->pkt_eth_hdr);
4037 test_params->pkt_eth_hdr = NULL;
4040 /* Clean up and remove slaves from bonded device */
4041 return remove_slaves_and_stop_bonded_device();
4045 test_tlb_tx_burst(void)
4047 int i, burst_size, nb_tx;
4048 uint64_t nb_tx2 = 0;
4049 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4050 struct rte_eth_stats port_stats[32];
4051 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4053 uint64_t floor_obytes = 0, ceiling_obytes = 0;
4055 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4056 (BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 1, 3, 1),
4057 "Failed to initialise bonded device");
4059 burst_size = 20 * test_params->bonded_slave_count;
4061 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4062 "Burst size specified is greater than supported.\n");
4065 /* Generate 400000 test bursts in 2s of packets to transmit */
4066 for (i = 0; i < 400000; i++) {
4067 /*test two types of mac src own(bonding) and others */
4069 initialize_eth_header(test_params->pkt_eth_hdr,
4070 (struct ether_addr *)src_mac,
4071 (struct ether_addr *)dst_mac_0, 1, 0, 0);
4073 initialize_eth_header(test_params->pkt_eth_hdr,
4074 (struct ether_addr *)test_params->default_slave_mac,
4075 (struct ether_addr *)dst_mac_0, 1, 0, 0);
4077 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4079 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4080 dst_addr_0, pktlen);
4081 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4082 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4083 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4084 /* Send burst on bonded port */
4085 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4089 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4090 "number of packet not equal burst size");
4096 /* Verify bonded port tx stats */
4097 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4099 all_bond_opackets = port_stats[0].opackets;
4100 all_bond_obytes = port_stats[0].obytes;
4102 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4103 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4104 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4108 /* Verify slave ports tx stats */
4109 for (i = 0; i < test_params->bonded_slave_count; i++) {
4110 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4111 sum_ports_opackets += port_stats[i].opackets;
4114 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4115 "Total packets sent by slaves is not equal to packets sent by bond interface");
4116 /* distribution of packets on each slave within +/- 10% of the expected value. */
4117 for (i = 0; i < test_params->bonded_slave_count; i++) {
4119 floor_obytes = (all_bond_obytes*90)/(test_params->bonded_slave_count*100);
4120 ceiling_obytes = (all_bond_obytes*110)/(test_params->bonded_slave_count*100);
4121 TEST_ASSERT(port_stats[i].obytes >= floor_obytes &&
4122 port_stats[i].obytes <= ceiling_obytes,
4123 "Distribution is not even");
4125 /* Put all slaves down and try and transmit */
4126 for (i = 0; i < test_params->bonded_slave_count; i++) {
4127 virtual_ethdev_simulate_link_status_interrupt(
4128 test_params->slave_port_ids[i], 0);
4131 /* Send burst on bonded port */
4132 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4134 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4136 /* Clean ugit checkout masterp and remove slaves from bonded device */
4137 return remove_slaves_and_stop_bonded_device();
4140 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4143 test_tlb_rx_burst(void)
4145 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4146 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4148 struct rte_eth_stats port_stats;
4152 uint16_t i, j, nb_rx, burst_size = 17;
4154 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4155 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4156 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING,
4157 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4158 "Failed to initialize bonded device");
4161 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4162 TEST_ASSERT(primary_port >= 0,
4163 "failed to get primary slave for bonded port (%d)",
4164 test_params->bonded_port_id);
4166 for (i = 0; i < test_params->bonded_slave_count; i++) {
4167 /* Generate test bursts of packets to transmit */
4168 TEST_ASSERT_EQUAL(generate_test_burst(
4169 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4170 "burst generation failed");
4172 /* Add rx data to slave */
4173 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4174 &gen_pkt_burst[0], burst_size);
4176 /* Call rx burst on bonded device */
4177 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4178 &rx_pkt_burst[0], MAX_PKT_BURST);
4180 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4182 if (test_params->slave_port_ids[i] == primary_port) {
4183 /* Verify bonded device rx count */
4184 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4185 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4186 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4187 test_params->bonded_port_id,
4188 (unsigned int)port_stats.ipackets, burst_size);
4190 /* Verify bonded slave devices rx count */
4191 for (j = 0; j < test_params->bonded_slave_count; j++) {
4192 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4194 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4195 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4196 test_params->slave_port_ids[i],
4197 (unsigned int)port_stats.ipackets, burst_size);
4199 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4200 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4201 test_params->slave_port_ids[i],
4202 (unsigned int)port_stats.ipackets, 0);
4206 for (j = 0; j < test_params->bonded_slave_count; j++) {
4207 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4208 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4209 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4210 test_params->slave_port_ids[i],
4211 (unsigned int)port_stats.ipackets, 0);
4216 for (i = 0; i < burst_size; i++)
4217 rte_pktmbuf_free(rx_pkt_burst[i]);
4219 /* reset bonded device stats */
4220 rte_eth_stats_reset(test_params->bonded_port_id);
4223 /* Clean up and remove slaves from bonded device */
4224 return remove_slaves_and_stop_bonded_device();
4228 test_tlb_verify_promiscuous_enable_disable(void)
4230 int i, primary_port, promiscuous_en;
4232 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4233 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4234 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0, 4, 1),
4235 "Failed to initialize bonded device");
4237 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4238 TEST_ASSERT(primary_port >= 0,
4239 "failed to get primary slave for bonded port (%d)",
4240 test_params->bonded_port_id);
4242 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4244 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4245 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4246 "Port (%d) promiscuous mode not enabled\n",
4247 test_params->bonded_port_id);
4248 for (i = 0; i < test_params->bonded_slave_count; i++) {
4249 promiscuous_en = rte_eth_promiscuous_get(
4250 test_params->slave_port_ids[i]);
4251 if (primary_port == test_params->slave_port_ids[i]) {
4252 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4253 "Port (%d) promiscuous mode not enabled\n",
4254 test_params->bonded_port_id);
4256 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4257 "Port (%d) promiscuous mode enabled\n",
4258 test_params->bonded_port_id);
4263 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4265 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4266 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4267 "Port (%d) promiscuous mode not disabled\n",
4268 test_params->bonded_port_id);
4270 for (i = 0; i < test_params->bonded_slave_count; i++) {
4271 promiscuous_en = rte_eth_promiscuous_get(
4272 test_params->slave_port_ids[i]);
4273 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4274 "slave port (%d) promiscuous mode not disabled\n",
4275 test_params->slave_port_ids[i]);
4278 /* Clean up and remove slaves from bonded device */
4279 return remove_slaves_and_stop_bonded_device();
4283 test_tlb_verify_mac_assignment(void)
4285 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4287 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4288 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4290 /* Initialize bonded device with 2 slaves in active backup mode */
4291 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4292 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0, 2, 1),
4293 "Failed to initialize bonded device");
4295 /* Verify that bonded MACs is that of first slave and that the other slave
4296 * MAC hasn't been changed */
4297 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4298 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4299 sizeof(read_mac_addr)),
4300 "bonded port (%d) mac address not set to that of primary port",
4301 test_params->bonded_port_id);
4303 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4304 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4305 sizeof(read_mac_addr)),
4306 "slave port (%d) mac address not set to that of primary port",
4307 test_params->slave_port_ids[0]);
4309 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4311 sizeof(read_mac_addr)),
4312 "slave port (%d) mac address not as expected",
4313 test_params->slave_port_ids[1]);
4315 /* change primary and verify that MAC addresses haven't changed */
4316 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4317 test_params->slave_port_ids[1]), 0,
4318 "Failed to set bonded port (%d) primary port to (%d)",
4319 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4321 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4323 sizeof(read_mac_addr)),
4324 "bonded port (%d) mac address not set to that of primary port",
4325 test_params->bonded_port_id);
4327 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4328 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4329 sizeof(read_mac_addr)),
4330 "slave port (%d) mac address not set to that of primary port",
4331 test_params->slave_port_ids[0]);
4333 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4335 sizeof(read_mac_addr)),
4336 "slave port (%d) mac address not as expected",
4337 test_params->slave_port_ids[1]);
4339 /* stop / start bonded device and verify that primary MAC address is
4340 * propagated to bonded device and slaves */
4342 rte_eth_dev_stop(test_params->bonded_port_id);
4344 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4345 "Failed to start device");
4347 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4348 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4349 sizeof(read_mac_addr)),
4350 "bonded port (%d) mac address not set to that of primary port",
4351 test_params->bonded_port_id);
4353 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4354 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4355 sizeof(read_mac_addr)),
4356 "slave port (%d) mac address not as expected",
4357 test_params->slave_port_ids[0]);
4359 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4361 sizeof(read_mac_addr)),
4362 "slave port (%d) mac address not set to that of primary port",
4363 test_params->slave_port_ids[1]);
4366 /* Set explicit MAC address */
4367 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4368 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4369 "failed to set MAC addres");
4371 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4372 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4373 sizeof(read_mac_addr)),
4374 "bonded port (%d) mac address not set to that of bonded port",
4375 test_params->bonded_port_id);
4377 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4378 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4379 sizeof(read_mac_addr)),
4380 "slave port (%d) mac address not as expected",
4381 test_params->slave_port_ids[0]);
4383 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4384 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4385 sizeof(read_mac_addr)),
4386 "slave port (%d) mac address not set to that of bonded port",
4387 test_params->slave_port_ids[1]);
4389 /* Clean up and remove slaves from bonded device */
4390 return remove_slaves_and_stop_bonded_device();
4394 test_tlb_verify_slave_link_status_change_failover(void)
4396 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4397 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4398 struct rte_eth_stats port_stats;
4400 uint8_t slaves[RTE_MAX_ETHPORTS];
4402 int i, j, burst_size, slave_count, primary_port;
4406 memset(pkt_burst, 0, sizeof(pkt_burst));
4410 /* Initialize bonded device with 4 slaves in round robin mode */
4411 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4412 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0,
4413 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4414 "Failed to initialize bonded device with slaves");
4416 /* Verify Current Slaves Count /Active Slave Count is */
4417 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4419 TEST_ASSERT_EQUAL(slave_count, 4,
4420 "Number of slaves (%d) is not as expected (%d).\n",
4423 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4424 slaves, RTE_MAX_ETHPORTS);
4425 TEST_ASSERT_EQUAL(slave_count, (int)4,
4426 "Number of slaves (%d) is not as expected (%d).\n",
4429 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4430 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4431 "Primary port not as expected");
4433 /* Bring 2 slaves down and verify active slave count */
4434 virtual_ethdev_simulate_link_status_interrupt(
4435 test_params->slave_port_ids[1], 0);
4436 virtual_ethdev_simulate_link_status_interrupt(
4437 test_params->slave_port_ids[3], 0);
4439 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4440 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4441 "Number of active slaves (%d) is not as expected (%d).",
4444 virtual_ethdev_simulate_link_status_interrupt(
4445 test_params->slave_port_ids[1], 1);
4446 virtual_ethdev_simulate_link_status_interrupt(
4447 test_params->slave_port_ids[3], 1);
4450 /* Bring primary port down, verify that active slave count is 3 and primary
4452 virtual_ethdev_simulate_link_status_interrupt(
4453 test_params->slave_port_ids[0], 0);
4455 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4456 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4457 "Number of active slaves (%d) is not as expected (%d).",
4460 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4461 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4462 "Primary port not as expected");
4463 rte_delay_us(500000);
4464 /* Verify that pkts are sent on new primary slave */
4465 for (i = 0; i < 4; i++) {
4466 TEST_ASSERT_EQUAL(generate_test_burst(
4467 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4468 "generate_test_burst failed\n");
4469 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4470 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4471 "rte_eth_tx_burst failed\n");
4472 rte_delay_us(11000);
4475 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4476 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4477 "(%d) port_stats.opackets not as expected\n",
4478 test_params->slave_port_ids[2]);
4480 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4481 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4482 "(%d) port_stats.opackets not as expected\n",
4483 test_params->slave_port_ids[0]);
4485 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4486 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4487 "(%d) port_stats.opackets not as expected\n",
4488 test_params->slave_port_ids[1]);
4490 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4491 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4492 "(%d) port_stats.opackets not as expected\n",
4493 test_params->slave_port_ids[3]);
4496 /* Generate packet burst for testing */
4498 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4499 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4503 virtual_ethdev_add_mbufs_to_rx_queue(
4504 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4507 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4508 MAX_PKT_BURST) != burst_size) {
4509 printf("rte_eth_rx_burst\n");
4514 /* Verify bonded device rx count */
4515 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4516 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4517 "(%d) port_stats.ipackets not as expected\n",
4518 test_params->bonded_port_id);
4522 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4523 for (j = 0; j < MAX_PKT_BURST; j++) {
4524 if (pkt_burst[i][j] != NULL) {
4525 rte_pktmbuf_free(pkt_burst[i][j]);
4526 pkt_burst[i][j] = NULL;
4532 /* Clean up and remove slaves from bonded device */
4533 return remove_slaves_and_stop_bonded_device();
4537 static struct unit_test_suite link_bonding_test_suite = {
4538 .suite_name = "Link Bonding Unit Test Suite",
4539 .setup = test_setup,
4540 .teardown = testsuite_teardown,
4541 .unit_test_cases = {
4542 TEST_CASE(test_create_bonded_device),
4543 TEST_CASE(test_create_bonded_device_with_invalid_params),
4544 TEST_CASE(test_add_slave_to_bonded_device),
4545 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4546 TEST_CASE(test_remove_slave_from_bonded_device),
4547 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4548 TEST_CASE(test_get_slaves_from_bonded_device),
4549 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4550 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4551 TEST_CASE(test_start_bonded_device),
4552 TEST_CASE(test_stop_bonded_device),
4553 TEST_CASE(test_set_bonding_mode),
4554 TEST_CASE(test_set_primary_slave),
4555 TEST_CASE(test_set_explicit_bonded_mac),
4556 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4557 TEST_CASE(test_status_interrupt),
4558 TEST_CASE(test_adding_slave_after_bonded_device_started),
4559 TEST_CASE(test_roundrobin_tx_burst),
4560 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4561 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4562 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4563 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4564 TEST_CASE(test_roundrobin_verify_mac_assignment),
4565 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4566 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4567 TEST_CASE(test_activebackup_tx_burst),
4568 TEST_CASE(test_activebackup_rx_burst),
4569 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4570 TEST_CASE(test_activebackup_verify_mac_assignment),
4571 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4572 TEST_CASE(test_balance_xmit_policy_configuration),
4573 TEST_CASE(test_balance_l2_tx_burst),
4574 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4575 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4576 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4577 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4578 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4579 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4580 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4581 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4582 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4583 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4584 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4585 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4586 TEST_CASE(test_balance_rx_burst),
4587 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4588 TEST_CASE(test_balance_verify_mac_assignment),
4589 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4590 TEST_CASE(test_tlb_tx_burst),
4591 TEST_CASE(test_tlb_rx_burst),
4592 TEST_CASE(test_tlb_verify_mac_assignment),
4593 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4594 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4595 #ifdef RTE_MBUF_REFCNT
4596 TEST_CASE(test_broadcast_tx_burst),
4597 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4598 TEST_CASE(test_broadcast_rx_burst),
4599 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4600 TEST_CASE(test_broadcast_verify_mac_assignment),
4601 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4603 TEST_CASE(test_reconfigure_bonded_device),
4604 TEST_CASE(test_close_bonded_device),
4606 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
4612 test_link_bonding(void)
4614 return unit_test_suite_runner(&link_bonding_test_suite);
4617 static struct test_command link_bonding_cmd = {
4618 .command = "link_bonding_autotest",
4619 .callback = test_link_bonding,
4621 REGISTER_TEST_COMMAND(link_bonding_cmd);