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->slave_port_ids[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] =
814 test_params->slave_port_ids[i];
816 /* Check primary slave MAC */
817 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
818 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
819 sizeof(read_mac_addr)),
820 "bonded port mac address not set to that of primary port\n");
822 /* Check bonded MAC */
823 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
824 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
825 sizeof(read_mac_addr)),
826 "bonded port mac address not set to that of primary port\n");
828 /* Check other slaves MACs */
829 for (j = 0; j < 4; j++) {
831 rte_eth_macaddr_get(test_params->slave_port_ids[j],
833 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
834 sizeof(read_mac_addr)),
835 "slave port mac address not set to that of primary "
842 /* Test with none existent port */
843 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
844 "read primary port from expectedly");
846 /* Test with slave port */
847 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
848 "read primary port from expectedly\n");
850 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
851 "Failed to stop and remove slaves from bonded device");
854 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
855 "read primary port from expectedly\n");
861 test_set_explicit_bonded_mac(void)
864 struct ether_addr read_mac_addr;
865 struct ether_addr *mac_addr;
867 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
869 mac_addr = (struct ether_addr *)explicit_bonded_mac;
871 /* Invalid port ID */
872 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
873 "Expected call to failed as invalid port specified.");
875 /* Non bonded device */
876 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
877 test_params->slave_port_ids[0], mac_addr),
878 "Expected call to failed as invalid port specified.");
880 /* NULL MAC address */
881 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
882 test_params->bonded_port_id, NULL),
883 "Expected call to failed as NULL MAC specified");
885 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
886 test_params->bonded_port_id, mac_addr),
887 "Failed to set MAC address on bonded port (%d)",
888 test_params->bonded_port_id);
890 /* Add 4 slaves to bonded device */
891 for (i = test_params->bonded_slave_count; i < 4; i++) {
892 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
893 "Failed to add slave to bonded device.\n");
896 /* Check bonded MAC */
897 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
898 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
899 "bonded port mac address not set to that of primary port");
901 /* Check other slaves MACs */
902 for (i = 0; i < 4; i++) {
903 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
904 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
905 sizeof(read_mac_addr)),
906 "slave port mac address not set to that of primary port");
909 /* test resetting mac address on bonded device */
911 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
912 "Failed to reset MAC address on bonded port (%d)",
913 test_params->bonded_port_id);
916 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
917 "Reset MAC address on bonded port (%d) unexpectedly",
918 test_params->slave_port_ids[1]);
920 /* test resetting mac address on bonded device with no slaves */
921 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
922 "Failed to remove slaves and stop bonded device");
924 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
925 "Failed to reset MAC address on bonded port (%d)",
926 test_params->bonded_port_id);
933 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
934 uint8_t number_of_slaves, uint8_t enable_slave)
936 /* Configure bonded device */
937 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
938 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
939 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
942 /* Add slaves to bonded device */
943 while (number_of_slaves > test_params->bonded_slave_count)
944 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
945 "Failed to add slave (%d to bonding port (%d).",
946 test_params->bonded_slave_count - 1,
947 test_params->bonded_port_id);
949 /* Set link bonding mode */
950 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
952 "Failed to set link bonding mode on port (%d) to (%d).",
953 test_params->bonded_port_id, bonding_mode);
955 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
956 "Failed to start bonded pmd eth device %d.",
957 test_params->bonded_port_id);
960 enable_bonded_slaves();
966 test_adding_slave_after_bonded_device_started(void)
970 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
971 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
972 "Failed to add slaves to bonded device");
974 /* Enabled slave devices */
975 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
976 virtual_ethdev_simulate_link_status_interrupt(
977 test_params->slave_port_ids[i], 1);
980 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
981 test_params->slave_port_ids[test_params->bonded_slave_count]),
982 "Failed to add slave to bonded port.\n");
985 test_params->slave_port_ids[test_params->bonded_slave_count]);
987 test_params->bonded_slave_count++;
989 return remove_slaves_and_stop_bonded_device();
992 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
993 #define TEST_LSC_WAIT_TIMEOUT_MS 500
995 int test_lsc_interrupt_count;
999 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1000 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1002 pthread_mutex_lock(&mutex);
1003 test_lsc_interrupt_count++;
1005 pthread_cond_signal(&cvar);
1006 pthread_mutex_unlock(&mutex);
1010 lsc_timeout(int wait_us)
1017 gettimeofday(&tp, NULL);
1019 /* Convert from timeval to timespec */
1020 ts.tv_sec = tp.tv_sec;
1021 ts.tv_nsec = tp.tv_usec * 1000;
1022 ts.tv_nsec += wait_us * 1000;
1024 pthread_mutex_lock(&mutex);
1025 if (test_lsc_interrupt_count < 1)
1026 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1028 pthread_mutex_unlock(&mutex);
1030 if (retval == 0 && test_lsc_interrupt_count < 1)
1037 test_status_interrupt(void)
1040 uint8_t slaves[RTE_MAX_ETHPORTS];
1042 /* initialized bonding device with T slaves */
1043 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1044 BONDING_MODE_ROUND_ROBIN, 1,
1045 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1046 "Failed to initialise bonded device");
1048 test_lsc_interrupt_count = 0;
1050 /* register link status change interrupt callback */
1051 rte_eth_dev_callback_register(test_params->bonded_port_id,
1052 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1053 &test_params->bonded_port_id);
1055 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1056 slaves, RTE_MAX_ETHPORTS);
1058 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1059 "Number of active slaves (%d) is not as expected (%d)",
1060 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1062 /* Bring all 4 slaves link status to down and test that we have received a
1064 virtual_ethdev_simulate_link_status_interrupt(
1065 test_params->slave_port_ids[0], 0);
1066 virtual_ethdev_simulate_link_status_interrupt(
1067 test_params->slave_port_ids[1], 0);
1068 virtual_ethdev_simulate_link_status_interrupt(
1069 test_params->slave_port_ids[2], 0);
1071 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1072 "Received a link status change interrupt unexpectedly");
1074 virtual_ethdev_simulate_link_status_interrupt(
1075 test_params->slave_port_ids[3], 0);
1077 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1078 "timed out waiting for interrupt");
1080 TEST_ASSERT(test_lsc_interrupt_count > 0,
1081 "Did not receive link status change interrupt");
1083 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1084 slaves, RTE_MAX_ETHPORTS);
1086 TEST_ASSERT_EQUAL(slave_count, 0,
1087 "Number of active slaves (%d) is not as expected (%d)",
1090 /* bring one slave port up so link status will change */
1091 test_lsc_interrupt_count = 0;
1093 virtual_ethdev_simulate_link_status_interrupt(
1094 test_params->slave_port_ids[0], 1);
1096 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1097 "timed out waiting for interrupt");
1099 /* test that we have received another lsc interrupt */
1100 TEST_ASSERT(test_lsc_interrupt_count > 0,
1101 "Did not receive link status change interrupt");
1103 /* Verify that calling the same slave lsc interrupt doesn't cause another
1104 * lsc interrupt from bonded device */
1105 test_lsc_interrupt_count = 0;
1107 virtual_ethdev_simulate_link_status_interrupt(
1108 test_params->slave_port_ids[0], 1);
1110 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1111 "received unexpected interrupt");
1113 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1114 "Did not receive link status change interrupt");
1117 /* unregister lsc callback before exiting */
1118 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1119 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1120 &test_params->bonded_port_id);
1122 /* Clean up and remove slaves from bonded device */
1123 return remove_slaves_and_stop_bonded_device();
1127 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1128 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1129 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1131 uint16_t pktlen, generated_burst_size;
1135 initialize_eth_header(test_params->pkt_eth_hdr,
1136 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1139 initialize_eth_header(test_params->pkt_eth_hdr,
1140 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1144 if (toggle_udp_port)
1145 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1148 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1153 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1154 dst_addr_1, pktlen);
1156 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1157 dst_addr_0, pktlen);
1159 ip_hdr = test_params->pkt_ipv4_hdr;
1162 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1163 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1166 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1167 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1170 ip_hdr = test_params->pkt_ipv6_hdr;
1173 /* Generate burst of packets to transmit */
1174 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1175 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1176 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1178 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1179 "Failed to generate packet burst");
1181 return generated_burst_size;
1184 /** Round Robin Mode Tests */
1187 test_roundrobin_tx_burst(void)
1190 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1191 struct rte_eth_stats port_stats;
1193 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1194 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1195 "Failed to intialise bonded device");
1197 burst_size = 20 * test_params->bonded_slave_count;
1199 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1200 "Burst size specified is greater than supported.");
1202 /* Generate test bursts of packets to transmit */
1203 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1204 burst_size, "failed to generate test burst");
1206 /* Send burst on bonded port */
1207 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1208 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1211 /* Verify bonded port tx stats */
1212 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1213 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1214 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1215 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1218 /* Verify slave ports tx stats */
1219 for (i = 0; i < test_params->bonded_slave_count; i++) {
1220 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1221 TEST_ASSERT_EQUAL(port_stats.opackets,
1222 (uint64_t)burst_size / test_params->bonded_slave_count,
1223 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1224 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1225 burst_size / test_params->bonded_slave_count);
1228 /* Put all slaves down and try and transmit */
1229 for (i = 0; i < test_params->bonded_slave_count; i++) {
1230 virtual_ethdev_simulate_link_status_interrupt(
1231 test_params->slave_port_ids[i], 0);
1234 /* Send burst on bonded port */
1235 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1236 pkt_burst, burst_size), 0,
1237 "tx burst return unexpected value");
1239 /* Clean up and remove slaves from bonded device */
1240 return remove_slaves_and_stop_bonded_device();
1243 #ifdef RTE_MBUF_REFCNT
1245 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1249 for (i = 0; i < nb_mbufs; i++) {
1250 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1251 TEST_ASSERT_EQUAL(refcnt, val,
1252 "mbuf ref count (%d)is not the expected value (%d)",
1261 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1265 for (i = 0; i < nb_mbufs; i++)
1266 rte_pktmbuf_free(mbufs[i]);
1269 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1270 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1271 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1272 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1275 test_roundrobin_tx_burst_slave_tx_fail(void)
1277 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1278 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1280 struct rte_eth_stats port_stats;
1282 int i, first_fail_idx, tx_count;
1284 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1285 BONDING_MODE_ROUND_ROBIN, 0,
1286 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1287 "Failed to intialise bonded device");
1289 /* Generate test bursts of packets to transmit */
1290 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1291 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1292 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1293 "Failed to generate test packet burst");
1295 /* Copy references to packets which we expect not to be transmitted */
1296 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1297 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1298 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1299 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1301 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1302 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1303 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1306 /* Set virtual slave to only fail transmission of
1307 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1308 virtual_ethdev_tx_burst_fn_set_success(
1309 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1312 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1313 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1314 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1316 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1317 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1319 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1320 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1321 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1322 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1323 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1325 /* Verify that failed packet are expected failed packets */
1326 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1327 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1328 "expected mbuf (%d) pointer %p not expected pointer %p",
1329 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1332 /* Verify bonded port tx stats */
1333 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1335 TEST_ASSERT_EQUAL(port_stats.opackets,
1336 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1337 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1338 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1339 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1340 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1341 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1343 /* Verify slave ports tx stats */
1344 for (i = 0; i < test_params->bonded_slave_count; i++) {
1345 int slave_expected_tx_count;
1347 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1349 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1350 test_params->bonded_slave_count;
1352 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1353 slave_expected_tx_count = slave_expected_tx_count -
1354 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1356 TEST_ASSERT_EQUAL(port_stats.opackets,
1357 (uint64_t)slave_expected_tx_count,
1358 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1359 test_params->slave_port_ids[i],
1360 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1363 #ifdef RTE_MBUF_REFCNT
1364 /* Verify that all mbufs have a ref value of zero */
1365 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1366 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1367 "mbufs refcnts not as expected");
1369 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1371 /* Clean up and remove slaves from bonded device */
1372 return remove_slaves_and_stop_bonded_device();
1376 test_roundrobin_rx_burst_on_single_slave(void)
1378 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1379 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1381 struct rte_eth_stats port_stats;
1383 int i, j, burst_size = 25;
1385 /* Initialize bonded device with 4 slaves in round robin mode */
1386 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1387 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1388 "Failed to initialize bonded device with slaves");
1390 /* Generate test bursts of packets to transmit */
1391 TEST_ASSERT_EQUAL(generate_test_burst(
1392 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1393 "burst generation failed");
1395 for (i = 0; i < test_params->bonded_slave_count; i++) {
1396 /* Add rx data to slave */
1397 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1398 &gen_pkt_burst[0], burst_size);
1400 /* Call rx burst on bonded device */
1401 /* Send burst on bonded port */
1402 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1403 test_params->bonded_port_id, 0, rx_pkt_burst,
1404 MAX_PKT_BURST), burst_size,
1405 "round-robin rx burst failed");
1407 /* Verify bonded device rx count */
1408 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1409 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1410 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1411 test_params->bonded_port_id,
1412 (unsigned int)port_stats.ipackets, burst_size);
1416 /* Verify bonded slave devices rx count */
1417 /* Verify slave ports tx stats */
1418 for (j = 0; j < test_params->bonded_slave_count; j++) {
1419 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1422 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1423 "Slave Port (%d) ipackets value (%u) not as expected"
1424 " (%d)", test_params->slave_port_ids[i],
1425 (unsigned int)port_stats.ipackets, burst_size);
1427 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1428 "Slave Port (%d) ipackets value (%u) not as expected"
1429 " (%d)", test_params->slave_port_ids[i],
1430 (unsigned int)port_stats.ipackets, 0);
1433 /* Reset bonded slaves stats */
1434 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1436 /* reset bonded device stats */
1437 rte_eth_stats_reset(test_params->bonded_port_id);
1441 for (i = 0; i < MAX_PKT_BURST; i++) {
1442 if (gen_pkt_burst[i] != NULL)
1443 rte_pktmbuf_free(gen_pkt_burst[i]);
1445 if (rx_pkt_burst[i] != NULL)
1446 rte_pktmbuf_free(rx_pkt_burst[i]);
1450 /* Clean up and remove slaves from bonded device */
1451 return remove_slaves_and_stop_bonded_device();
1454 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1457 test_roundrobin_rx_burst_on_multiple_slaves(void)
1459 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1461 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1462 struct rte_eth_stats port_stats;
1464 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1467 /* Initialize bonded device with 4 slaves in round robin mode */
1468 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1469 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1470 "Failed to initialize bonded device with slaves");
1472 /* Generate test bursts of packets to transmit */
1473 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1474 TEST_ASSERT_EQUAL(generate_test_burst(
1475 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1476 burst_size[i], "burst generation failed");
1479 /* Add rx data to slaves */
1480 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1481 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1482 &gen_pkt_burst[i][0], burst_size[i]);
1485 /* Call rx burst on bonded device */
1486 /* Send burst on bonded port */
1487 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1489 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1490 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1491 burst_size[0] + burst_size[1] + burst_size[2]);
1493 /* Verify bonded device rx count */
1494 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1495 TEST_ASSERT_EQUAL(port_stats.ipackets,
1496 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1497 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1498 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1499 burst_size[0] + burst_size[1] + burst_size[2]);
1501 /* Verify bonded slave devices rx counts */
1502 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1503 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1504 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1505 test_params->slave_port_ids[0],
1506 (unsigned int)port_stats.ipackets, burst_size[0]);
1508 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1509 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1510 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1511 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1514 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1515 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1516 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1517 test_params->slave_port_ids[2],
1518 (unsigned int)port_stats.ipackets, burst_size[2]);
1520 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1521 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1522 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1523 test_params->slave_port_ids[3],
1524 (unsigned int)port_stats.ipackets, 0);
1527 for (i = 0; i < MAX_PKT_BURST; i++) {
1528 if (rx_pkt_burst[i] != NULL)
1529 rte_pktmbuf_free(rx_pkt_burst[i]);
1532 /* Clean up and remove slaves from bonded device */
1533 return remove_slaves_and_stop_bonded_device();
1537 test_roundrobin_verify_mac_assignment(void)
1539 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1543 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1544 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1546 /* Initialize bonded device with 4 slaves in round robin mode */
1547 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1548 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1549 "Failed to initialize bonded device with slaves");
1551 /* Verify that all MACs are the same as first slave added to bonded dev */
1552 for (i = 0; i < test_params->bonded_slave_count; i++) {
1553 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1554 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1555 sizeof(read_mac_addr)),
1556 "slave port (%d) mac address not set to that of primary port",
1557 test_params->slave_port_ids[i]);
1560 /* change primary and verify that MAC addresses haven't changed */
1561 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1562 test_params->slave_port_ids[2]),
1563 "Failed to set bonded port (%d) primary port to (%d)",
1564 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1566 for (i = 0; i < test_params->bonded_slave_count; i++) {
1567 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1568 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1569 sizeof(read_mac_addr)),
1570 "slave port (%d) mac address has changed to that of primary"
1571 " port without stop/start toggle of bonded device",
1572 test_params->slave_port_ids[i]);
1575 /* stop / start bonded device and verify that primary MAC address is
1576 * propagate to bonded device and slaves */
1577 rte_eth_dev_stop(test_params->bonded_port_id);
1579 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1580 "Failed to start bonded device");
1582 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1583 TEST_ASSERT_SUCCESS(
1584 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1585 "bonded port (%d) mac address not set to that of new primary port",
1586 test_params->slave_port_ids[i]);
1588 for (i = 0; i < test_params->bonded_slave_count; i++) {
1589 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1590 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1591 sizeof(read_mac_addr)),
1592 "slave port (%d) mac address not set to that of new primary"
1593 " port", test_params->slave_port_ids[i]);
1596 /* Set explicit MAC address */
1597 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1598 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1599 "Failed to set MAC");
1601 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1602 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1603 sizeof(read_mac_addr)),
1604 "bonded port (%d) mac address not set to that of new primary port",
1605 test_params->slave_port_ids[i]);
1607 for (i = 0; i < test_params->bonded_slave_count; i++) {
1608 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1609 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1610 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1611 " that of new primary port\n", test_params->slave_port_ids[i]);
1614 /* Clean up and remove slaves from bonded device */
1615 return remove_slaves_and_stop_bonded_device();
1619 test_roundrobin_verify_promiscuous_enable_disable(void)
1621 int i, promiscuous_en;
1623 /* Initialize bonded device with 4 slaves in round robin mode */
1624 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1625 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1626 "Failed to initialize bonded device with slaves");
1628 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1630 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1631 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1632 "Port (%d) promiscuous mode not enabled",
1633 test_params->bonded_port_id);
1635 for (i = 0; i < test_params->bonded_slave_count; i++) {
1636 promiscuous_en = rte_eth_promiscuous_get(
1637 test_params->slave_port_ids[i]);
1638 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1639 "slave port (%d) promiscuous mode not enabled",
1640 test_params->slave_port_ids[i]);
1643 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1645 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1646 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1647 "Port (%d) promiscuous mode not disabled\n",
1648 test_params->bonded_port_id);
1650 for (i = 0; i < test_params->bonded_slave_count; i++) {
1651 promiscuous_en = rte_eth_promiscuous_get(
1652 test_params->slave_port_ids[i]);
1653 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1654 "Port (%d) promiscuous mode not disabled\n",
1655 test_params->slave_port_ids[i]);
1658 /* Clean up and remove slaves from bonded device */
1659 return remove_slaves_and_stop_bonded_device();
1662 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1663 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1666 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1668 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1669 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1670 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1672 struct rte_eth_stats port_stats;
1673 uint8_t slaves[RTE_MAX_ETHPORTS];
1675 int i, burst_size, slave_count;
1677 /* NULL all pointers in array to simplify cleanup */
1678 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1680 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1681 * in round robin mode */
1682 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1683 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1684 "Failed to initialize bonded device with slaves");
1686 /* Verify Current Slaves Count /Active Slave Count is */
1687 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1689 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1690 "Number of slaves (%d) is not as expected (%d).",
1691 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1693 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1694 slaves, RTE_MAX_ETHPORTS);
1695 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1696 "Number of active slaves (%d) is not as expected (%d).",
1697 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1699 /* Set 2 slaves eth_devs link status to down */
1700 virtual_ethdev_simulate_link_status_interrupt(
1701 test_params->slave_port_ids[1], 0);
1702 virtual_ethdev_simulate_link_status_interrupt(
1703 test_params->slave_port_ids[3], 0);
1705 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1706 slaves, RTE_MAX_ETHPORTS);
1707 TEST_ASSERT_EQUAL(slave_count,
1708 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1709 "Number of active slaves (%d) is not as expected (%d).\n",
1710 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1714 /* Verify that pkts are not sent on slaves with link status down:
1716 * 1. Generate test burst of traffic
1717 * 2. Transmit burst on bonded eth_dev
1718 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1719 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1722 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1723 burst_size, "generate_test_burst failed");
1725 rte_eth_stats_reset(test_params->bonded_port_id);
1729 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1730 burst_size), burst_size, "rte_eth_tx_burst failed");
1732 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1733 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1734 "Port (%d) opackets stats (%d) not expected (%d) value",
1735 test_params->bonded_port_id, (int)port_stats.opackets,
1738 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1739 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1740 "Port (%d) opackets stats (%d) not expected (%d) value",
1741 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1743 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1744 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1745 "Port (%d) opackets stats (%d) not expected (%d) value",
1746 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1748 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1749 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1750 "Port (%d) opackets stats (%d) not expected (%d) value",
1751 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1753 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1754 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1755 "Port (%d) opackets stats (%d) not expected (%d) value",
1756 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1758 /* Verify that pkts are not sent on slaves with link status down:
1760 * 1. Generate test bursts of traffic
1761 * 2. Add bursts on to virtual eth_devs
1762 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1763 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1764 * 4. Verify stats for bonded eth_dev
1765 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1767 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1768 TEST_ASSERT_EQUAL(generate_test_burst(
1769 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1770 burst_size, "failed to generate packet burst");
1772 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1773 &gen_pkt_burst[i][0], burst_size);
1776 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1777 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1778 burst_size + burst_size,
1779 "rte_eth_rx_burst failed");
1781 /* Verify bonded device rx count */
1782 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1783 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1784 "(%d) port_stats.ipackets not as expected\n",
1785 test_params->bonded_port_id);
1788 for (i = 0; i < MAX_PKT_BURST; i++) {
1789 if (rx_pkt_burst[i] != NULL)
1790 rte_pktmbuf_free(rx_pkt_burst[i]);
1792 if (gen_pkt_burst[1][i] != NULL)
1793 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1795 if (gen_pkt_burst[3][i] != NULL)
1796 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1799 /* Clean up and remove slaves from bonded device */
1800 return remove_slaves_and_stop_bonded_device();
1803 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1805 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1808 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1811 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1813 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1814 char slave_name[RTE_ETH_NAME_MAX_LEN];
1818 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1819 /* Generate slave name / MAC address */
1820 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1821 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
1823 /* Create slave devices with no ISR Support */
1824 if (polling_test_slaves[i] == -1) {
1825 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
1826 rte_socket_id(), 0);
1827 TEST_ASSERT(polling_test_slaves[i] >= 0,
1828 "Failed to create virtual virtual ethdev %s\n", slave_name);
1830 /* Configure slave */
1831 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
1832 "Failed to configure virtual ethdev %s(%d)", slave_name,
1833 polling_test_slaves[i]);
1836 /* Add slave to bonded device */
1837 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1838 polling_test_slaves[i]),
1839 "Failed to add slave %s(%d) to bonded device %d",
1840 slave_name, polling_test_slaves[i],
1841 test_params->bonded_port_id);
1844 /* Initialize bonded device */
1845 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
1846 "Failed to configure bonded device %d",
1847 test_params->bonded_port_id);
1850 /* Register link status change interrupt callback */
1851 rte_eth_dev_callback_register(test_params->bonded_port_id,
1852 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1853 &test_params->bonded_port_id);
1855 /* link status change callback for first slave link up */
1856 test_lsc_interrupt_count = 0;
1858 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
1860 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
1863 /* no link status change callback for second slave link up */
1864 test_lsc_interrupt_count = 0;
1866 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
1868 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
1870 /* link status change callback for both slave links down */
1871 test_lsc_interrupt_count = 0;
1873 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
1874 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
1876 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
1878 /* Un-Register link status change interrupt callback */
1879 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1880 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1881 &test_params->bonded_port_id);
1884 /* Clean up and remove slaves from bonded device */
1885 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1887 TEST_ASSERT_SUCCESS(
1888 rte_eth_bond_slave_remove(test_params->bonded_port_id,
1889 polling_test_slaves[i]),
1890 "Failed to remove slave %d from bonded port (%d)",
1891 polling_test_slaves[i], test_params->bonded_port_id);
1894 return remove_slaves_and_stop_bonded_device();
1898 /** Active Backup Mode Tests */
1901 test_activebackup_tx_burst(void)
1903 int i, pktlen, primary_port, burst_size;
1904 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1905 struct rte_eth_stats port_stats;
1907 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1908 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
1909 "Failed to initialize bonded device with slaves");
1911 initialize_eth_header(test_params->pkt_eth_hdr,
1912 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
1913 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1915 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1916 dst_addr_0, pktlen);
1918 burst_size = 20 * test_params->bonded_slave_count;
1920 TEST_ASSERT(burst_size < MAX_PKT_BURST,
1921 "Burst size specified is greater than supported.");
1923 /* Generate a burst of packets to transmit */
1924 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
1925 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
1926 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
1927 burst_size, "failed to generate burst correctly");
1929 /* Send burst on bonded port */
1930 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1931 burst_size), burst_size, "tx burst failed");
1933 /* Verify bonded port tx stats */
1934 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1935 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1936 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1937 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1940 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1942 /* Verify slave ports tx stats */
1943 for (i = 0; i < test_params->bonded_slave_count; i++) {
1944 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1945 if (test_params->slave_port_ids[i] == primary_port) {
1946 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1947 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1948 test_params->bonded_port_id,
1949 (unsigned int)port_stats.opackets,
1950 burst_size / test_params->bonded_slave_count);
1952 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
1953 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1954 test_params->bonded_port_id,
1955 (unsigned int)port_stats.opackets, 0);
1959 /* Put all slaves down and try and transmit */
1960 for (i = 0; i < test_params->bonded_slave_count; i++) {
1961 virtual_ethdev_simulate_link_status_interrupt(
1962 test_params->slave_port_ids[i], 0);
1965 /* Send burst on bonded port */
1966 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1967 pkts_burst, burst_size), 0, "Sending empty burst failed");
1969 /* Clean up and remove slaves from bonded device */
1970 return remove_slaves_and_stop_bonded_device();
1973 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
1976 test_activebackup_rx_burst(void)
1978 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1979 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1981 struct rte_eth_stats port_stats;
1985 int i, j, burst_size = 17;
1987 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1988 BONDING_MODE_ACTIVE_BACKUP, 0,
1989 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
1990 "Failed to initialize bonded device with slaves");
1992 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1993 TEST_ASSERT(primary_port >= 0,
1994 "failed to get primary slave for bonded port (%d)",
1995 test_params->bonded_port_id);
1997 for (i = 0; i < test_params->bonded_slave_count; i++) {
1998 /* Generate test bursts of packets to transmit */
1999 TEST_ASSERT_EQUAL(generate_test_burst(
2000 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2001 burst_size, "burst generation failed");
2003 /* Add rx data to slave */
2004 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2005 &gen_pkt_burst[0], burst_size);
2007 /* Call rx burst on bonded device */
2008 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2009 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2010 "rte_eth_rx_burst failed");
2012 if (test_params->slave_port_ids[i] == primary_port) {
2013 /* Verify bonded device rx count */
2014 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2015 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2016 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2017 test_params->bonded_port_id,
2018 (unsigned int)port_stats.ipackets, burst_size);
2020 /* Verify bonded slave devices rx count */
2021 for (j = 0; j < test_params->bonded_slave_count; j++) {
2022 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2024 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2025 "Slave Port (%d) ipackets value (%u) not as "
2026 "expected (%d)", test_params->slave_port_ids[i],
2027 (unsigned int)port_stats.ipackets, burst_size);
2029 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2030 "Slave Port (%d) ipackets value (%u) not as "
2031 "expected (%d)\n", test_params->slave_port_ids[i],
2032 (unsigned int)port_stats.ipackets, 0);
2036 for (j = 0; j < test_params->bonded_slave_count; j++) {
2037 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2038 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2039 "Slave Port (%d) ipackets value (%u) not as expected "
2040 "(%d)", test_params->slave_port_ids[i],
2041 (unsigned int)port_stats.ipackets, 0);
2046 for (i = 0; i < MAX_PKT_BURST; i++) {
2047 if (rx_pkt_burst[i] != NULL) {
2048 rte_pktmbuf_free(rx_pkt_burst[i]);
2049 rx_pkt_burst[i] = NULL;
2053 /* reset bonded device stats */
2054 rte_eth_stats_reset(test_params->bonded_port_id);
2057 /* Clean up and remove slaves from bonded device */
2058 return remove_slaves_and_stop_bonded_device();
2062 test_activebackup_verify_promiscuous_enable_disable(void)
2064 int i, primary_port, promiscuous_en;
2066 /* Initialize bonded device with 4 slaves in round robin mode */
2067 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2068 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2069 "Failed to initialize bonded device with slaves");
2071 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2072 TEST_ASSERT(primary_port >= 0,
2073 "failed to get primary slave for bonded port (%d)",
2074 test_params->bonded_port_id);
2076 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2078 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2079 "Port (%d) promiscuous mode not enabled",
2080 test_params->bonded_port_id);
2082 for (i = 0; i < test_params->bonded_slave_count; i++) {
2083 promiscuous_en = rte_eth_promiscuous_get(
2084 test_params->slave_port_ids[i]);
2085 if (primary_port == test_params->slave_port_ids[i]) {
2086 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2087 "slave port (%d) promiscuous mode not enabled",
2088 test_params->slave_port_ids[i]);
2090 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2091 "slave port (%d) promiscuous mode enabled",
2092 test_params->slave_port_ids[i]);
2097 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2099 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2100 "Port (%d) promiscuous mode not disabled\n",
2101 test_params->bonded_port_id);
2103 for (i = 0; i < test_params->bonded_slave_count; i++) {
2104 promiscuous_en = rte_eth_promiscuous_get(
2105 test_params->slave_port_ids[i]);
2106 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2107 "slave port (%d) promiscuous mode not disabled\n",
2108 test_params->slave_port_ids[i]);
2111 /* Clean up and remove slaves from bonded device */
2112 return remove_slaves_and_stop_bonded_device();
2116 test_activebackup_verify_mac_assignment(void)
2118 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2120 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2121 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2123 /* Initialize bonded device with 2 slaves in active backup mode */
2124 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2125 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2126 "Failed to initialize bonded device with slaves");
2128 /* Verify that bonded MACs is that of first slave and that the other slave
2129 * MAC hasn't been changed */
2130 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2131 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2132 sizeof(read_mac_addr)),
2133 "bonded port (%d) mac address not set to that of primary port",
2134 test_params->bonded_port_id);
2136 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2137 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2138 sizeof(read_mac_addr)),
2139 "slave port (%d) mac address not set to that of primary port",
2140 test_params->slave_port_ids[0]);
2142 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2143 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2144 sizeof(read_mac_addr)),
2145 "slave port (%d) mac address not as expected",
2146 test_params->slave_port_ids[1]);
2148 /* change primary and verify that MAC addresses haven't changed */
2149 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2150 test_params->slave_port_ids[1]), 0,
2151 "Failed to set bonded port (%d) primary port to (%d)",
2152 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2154 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2155 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2156 sizeof(read_mac_addr)),
2157 "bonded port (%d) mac address not set to that of primary port",
2158 test_params->bonded_port_id);
2160 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2161 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2162 sizeof(read_mac_addr)),
2163 "slave port (%d) mac address not set to that of primary port",
2164 test_params->slave_port_ids[0]);
2166 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2167 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2168 sizeof(read_mac_addr)),
2169 "slave port (%d) mac address not as expected",
2170 test_params->slave_port_ids[1]);
2172 /* stop / start bonded device and verify that primary MAC address is
2173 * propagated to bonded device and slaves */
2175 rte_eth_dev_stop(test_params->bonded_port_id);
2177 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2178 "Failed to start device");
2180 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2181 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2182 sizeof(read_mac_addr)),
2183 "bonded port (%d) mac address not set to that of primary port",
2184 test_params->bonded_port_id);
2186 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2187 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2188 sizeof(read_mac_addr)),
2189 "slave port (%d) mac address not as expected",
2190 test_params->slave_port_ids[0]);
2192 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2193 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2194 sizeof(read_mac_addr)),
2195 "slave port (%d) mac address not set to that of primary port",
2196 test_params->slave_port_ids[1]);
2198 /* Set explicit MAC address */
2199 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2200 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2201 "failed to set MAC address");
2203 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2204 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2205 sizeof(read_mac_addr)),
2206 "bonded port (%d) mac address not set to that of bonded port",
2207 test_params->bonded_port_id);
2209 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2210 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2211 sizeof(read_mac_addr)),
2212 "slave port (%d) mac address not as expected",
2213 test_params->slave_port_ids[0]);
2215 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2216 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2217 sizeof(read_mac_addr)),
2218 "slave port (%d) mac address not set to that of bonded port",
2219 test_params->slave_port_ids[1]);
2221 /* Clean up and remove slaves from bonded device */
2222 return remove_slaves_and_stop_bonded_device();
2226 test_activebackup_verify_slave_link_status_change_failover(void)
2228 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2229 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2230 struct rte_eth_stats port_stats;
2232 uint8_t slaves[RTE_MAX_ETHPORTS];
2234 int i, j, burst_size, slave_count, primary_port;
2238 memset(pkt_burst, 0, sizeof(pkt_burst));
2240 /* Generate packet burst for testing */
2241 TEST_ASSERT_EQUAL(generate_test_burst(
2242 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2243 "generate_test_burst failed");
2245 /* Initialize bonded device with 4 slaves in round robin mode */
2246 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2247 BONDING_MODE_ACTIVE_BACKUP, 0,
2248 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2249 "Failed to initialize bonded device with slaves");
2251 /* Verify Current Slaves Count /Active Slave Count is */
2252 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2254 TEST_ASSERT_EQUAL(slave_count, 4,
2255 "Number of slaves (%d) is not as expected (%d).",
2258 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2259 slaves, RTE_MAX_ETHPORTS);
2260 TEST_ASSERT_EQUAL(slave_count, 4,
2261 "Number of active slaves (%d) is not as expected (%d).",
2264 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2265 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2266 "Primary port not as expected");
2268 /* Bring 2 slaves down and verify active slave count */
2269 virtual_ethdev_simulate_link_status_interrupt(
2270 test_params->slave_port_ids[1], 0);
2271 virtual_ethdev_simulate_link_status_interrupt(
2272 test_params->slave_port_ids[3], 0);
2274 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2275 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2276 "Number of active slaves (%d) is not as expected (%d).",
2279 virtual_ethdev_simulate_link_status_interrupt(
2280 test_params->slave_port_ids[1], 1);
2281 virtual_ethdev_simulate_link_status_interrupt(
2282 test_params->slave_port_ids[3], 1);
2285 /* Bring primary port down, verify that active slave count is 3 and primary
2287 virtual_ethdev_simulate_link_status_interrupt(
2288 test_params->slave_port_ids[0], 0);
2290 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2291 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2293 "Number of active slaves (%d) is not as expected (%d).",
2296 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2297 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2298 "Primary port not as expected");
2300 /* Verify that pkts are sent on new primary slave */
2302 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2303 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2304 burst_size), burst_size, "rte_eth_tx_burst failed");
2306 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2307 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2308 "(%d) port_stats.opackets not as expected",
2309 test_params->slave_port_ids[2]);
2311 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2312 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2313 "(%d) port_stats.opackets not as expected\n",
2314 test_params->slave_port_ids[0]);
2316 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2317 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2318 "(%d) port_stats.opackets not as expected\n",
2319 test_params->slave_port_ids[1]);
2321 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2322 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2323 "(%d) port_stats.opackets not as expected\n",
2324 test_params->slave_port_ids[3]);
2326 /* Generate packet burst for testing */
2328 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2329 TEST_ASSERT_EQUAL(generate_test_burst(
2330 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2331 "generate_test_burst failed");
2333 virtual_ethdev_add_mbufs_to_rx_queue(
2334 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2337 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2338 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2339 burst_size, "rte_eth_rx_burst\n");
2341 /* Verify bonded device rx count */
2342 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2343 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2344 "(%d) port_stats.ipackets not as expected",
2345 test_params->bonded_port_id);
2347 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2348 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2349 "(%d) port_stats.opackets not as expected",
2350 test_params->slave_port_ids[2]);
2352 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2353 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2354 "(%d) port_stats.opackets not as expected",
2355 test_params->slave_port_ids[0]);
2357 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2358 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2359 "(%d) port_stats.opackets not as expected",
2360 test_params->slave_port_ids[1]);
2362 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2363 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2364 "(%d) port_stats.opackets not as expected",
2365 test_params->slave_port_ids[3]);
2368 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2369 for (j = 0; j < MAX_PKT_BURST; j++) {
2370 if (pkt_burst[i][j] != NULL) {
2371 rte_pktmbuf_free(pkt_burst[i][j]);
2372 pkt_burst[i][j] = NULL;
2377 /* Clean up and remove slaves from bonded device */
2378 return remove_slaves_and_stop_bonded_device();
2381 /** Balance Mode Tests */
2384 test_balance_xmit_policy_configuration(void)
2386 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2387 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2388 "Failed to initialize_bonded_device_with_slaves.");
2390 /* Invalid port id */
2391 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2392 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2393 "Expected call to failed as invalid port specified.");
2395 /* Set xmit policy on non bonded device */
2396 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2397 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2398 "Expected call to failed as invalid port specified.");
2401 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2402 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2403 "Failed to set balance xmit policy.");
2405 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2406 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2409 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2410 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2411 "Failed to set balance xmit policy.");
2413 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2414 BALANCE_XMIT_POLICY_LAYER23,
2415 "balance xmit policy not as expected.");
2418 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2419 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2420 "Failed to set balance xmit policy.");
2422 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2423 BALANCE_XMIT_POLICY_LAYER34,
2424 "balance xmit policy not as expected.");
2426 /* Invalid port id */
2427 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2428 "Expected call to failed as invalid port specified.");
2430 /* Clean up and remove slaves from bonded device */
2431 return remove_slaves_and_stop_bonded_device();
2434 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2437 test_balance_l2_tx_burst(void)
2439 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2440 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2444 struct rte_eth_stats port_stats;
2446 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2447 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2448 "Failed to initialize_bonded_device_with_slaves.");
2450 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2451 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2452 "Failed to set balance xmit policy.");
2454 initialize_eth_header(test_params->pkt_eth_hdr,
2455 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2456 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2458 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2459 dst_addr_0, pktlen);
2461 /* Generate a burst 1 of packets to transmit */
2462 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2463 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2464 test_params->pkt_udp_hdr, burst_size[0],
2465 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2466 "failed to generate packet burst");
2468 initialize_eth_header(test_params->pkt_eth_hdr,
2469 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2471 /* Generate a burst 2 of packets to transmit */
2472 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2473 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2474 test_params->pkt_udp_hdr, burst_size[1],
2475 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2476 "failed to generate packet burst");
2478 /* Send burst 1 on bonded port */
2479 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2480 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2481 &pkts_burst[i][0], burst_size[i]),
2482 burst_size[i], "Failed to transmit packet burst");
2485 /* Verify bonded port tx stats */
2486 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2487 TEST_ASSERT_EQUAL(port_stats.opackets,
2488 (uint64_t)(burst_size[0] + burst_size[1]),
2489 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2490 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2491 burst_size[0] + burst_size[1]);
2494 /* Verify slave ports tx stats */
2495 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2496 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2497 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2498 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2501 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2502 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2503 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2504 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2507 /* Put all slaves down and try and transmit */
2508 for (i = 0; i < test_params->bonded_slave_count; i++) {
2510 virtual_ethdev_simulate_link_status_interrupt(
2511 test_params->slave_port_ids[i], 0);
2514 /* Send burst on bonded port */
2515 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2516 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2517 0, "Expected zero packet");
2519 /* Clean up and remove slaves from bonded device */
2520 return remove_slaves_and_stop_bonded_device();
2524 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2525 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2527 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2529 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2530 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2532 struct rte_eth_stats port_stats;
2534 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2535 BONDING_MODE_BALANCE, 0, 2, 1),
2536 "Failed to initialize_bonded_device_with_slaves.");
2538 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2539 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2540 "Failed to set balance xmit policy.");
2545 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2546 "Burst size specified is greater than supported.");
2548 /* Generate test bursts of packets to transmit */
2549 TEST_ASSERT_EQUAL(generate_test_burst(
2550 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2551 burst_size_1, "failed to generate packet burst");
2553 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2554 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2555 "failed to generate packet burst");
2557 /* Send burst 1 on bonded port */
2558 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2560 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2562 /* Send burst 2 on bonded port */
2563 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2565 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2567 /* Verify bonded port tx stats */
2568 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2569 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2570 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2571 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2574 /* Verify slave ports tx stats */
2575 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2576 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2577 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2578 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2581 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2582 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2583 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2584 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2587 /* Put all slaves down and try and transmit */
2588 for (i = 0; i < test_params->bonded_slave_count; i++) {
2590 virtual_ethdev_simulate_link_status_interrupt(
2591 test_params->slave_port_ids[i], 0);
2594 /* Send burst on bonded port */
2595 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2596 test_params->bonded_port_id, 0, pkts_burst_1,
2597 burst_size_1), 0, "Expected zero packet");
2600 /* Clean up and remove slaves from bonded device */
2601 return remove_slaves_and_stop_bonded_device();
2605 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2607 return balance_l23_tx_burst(0, 1, 1, 0);
2611 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2613 return balance_l23_tx_burst(1, 1, 0, 1);
2617 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2619 return balance_l23_tx_burst(0, 0, 0, 1);
2623 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2625 return balance_l23_tx_burst(1, 0, 0, 1);
2629 test_balance_l23_tx_burst_toggle_mac_addr(void)
2631 return balance_l23_tx_burst(0, 0, 1, 0);
2635 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2636 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2637 uint8_t toggle_udp_port)
2639 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2641 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2642 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2644 struct rte_eth_stats port_stats;
2646 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2647 BONDING_MODE_BALANCE, 0, 2, 1),
2648 "Failed to initialize_bonded_device_with_slaves.");
2650 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2651 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2652 "Failed to set balance xmit policy.");
2657 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2658 "Burst size specified is greater than supported.");
2660 /* Generate test bursts of packets to transmit */
2661 TEST_ASSERT_EQUAL(generate_test_burst(
2662 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2663 burst_size_1, "failed to generate burst");
2665 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2666 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2667 toggle_udp_port), burst_size_2, "failed to generate burst");
2669 /* Send burst 1 on bonded port */
2670 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2672 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2674 /* Send burst 2 on bonded port */
2675 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2677 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2680 /* Verify bonded port tx stats */
2681 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2682 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2683 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2684 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2687 /* Verify slave ports tx stats */
2688 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2689 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2690 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2691 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2694 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2695 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2696 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2697 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2700 /* Put all slaves down and try and transmit */
2701 for (i = 0; i < test_params->bonded_slave_count; i++) {
2703 virtual_ethdev_simulate_link_status_interrupt(
2704 test_params->slave_port_ids[i], 0);
2707 /* Send burst on bonded port */
2708 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2709 test_params->bonded_port_id, 0, pkts_burst_1,
2710 burst_size_1), 0, "Expected zero packet");
2712 /* Clean up and remove slaves from bonded device */
2713 return remove_slaves_and_stop_bonded_device();
2717 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2719 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2723 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2725 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2729 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2731 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2735 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2737 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2741 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2743 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2747 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2749 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2752 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2753 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2754 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2755 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2756 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2759 test_balance_tx_burst_slave_tx_fail(void)
2761 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2762 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2764 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2766 struct rte_eth_stats port_stats;
2768 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2770 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2771 BONDING_MODE_BALANCE, 0,
2772 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2773 "Failed to intialise bonded device");
2775 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2776 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2777 "Failed to set balance xmit policy.");
2780 /* Generate test bursts for transmission */
2781 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2782 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2783 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2784 "Failed to generate test packet burst 1");
2786 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2787 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2789 /* copy mbuf referneces for expected transmission failures */
2790 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2791 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2793 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2794 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2795 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2796 "Failed to generate test packet burst 2");
2799 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2800 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2801 virtual_ethdev_tx_burst_fn_set_success(
2802 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2805 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2806 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2807 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2810 /* Transmit burst 1 */
2811 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2812 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2814 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2815 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2816 "Transmitted (%d) packets, expected to transmit (%d) packets",
2817 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2818 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2820 /* Verify that failed packet are expected failed packets */
2821 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
2822 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
2823 "expected mbuf (%d) pointer %p not expected pointer %p",
2824 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
2827 /* Transmit burst 2 */
2828 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2829 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2831 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2832 "Transmitted (%d) packets, expected to transmit (%d) packets",
2833 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2836 /* Verify bonded port tx stats */
2837 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2839 TEST_ASSERT_EQUAL(port_stats.opackets,
2840 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2841 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2842 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
2843 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2844 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2845 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2846 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2847 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2849 /* Verify slave ports tx stats */
2851 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2853 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
2854 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2855 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2856 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2857 test_params->slave_port_ids[0],
2858 (unsigned int)port_stats.opackets,
2859 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2860 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2865 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2867 TEST_ASSERT_EQUAL(port_stats.opackets,
2868 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2869 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2870 test_params->slave_port_ids[1],
2871 (unsigned int)port_stats.opackets,
2872 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2874 #ifdef RTE_MBUF_REFCNT
2875 /* Verify that all mbufs have a ref value of zero */
2876 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
2877 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
2878 "mbufs refcnts not as expected");
2881 free_mbufs(&pkts_burst_1[tx_count_1],
2882 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2884 /* Clean up and remove slaves from bonded device */
2885 return remove_slaves_and_stop_bonded_device();
2888 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
2891 test_balance_rx_burst(void)
2893 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2895 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2896 struct rte_eth_stats port_stats;
2898 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
2901 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
2903 /* Initialize bonded device with 4 slaves in round robin mode */
2904 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2905 BONDING_MODE_BALANCE, 0, 3, 1),
2906 "Failed to intialise bonded device");
2908 /* Generate test bursts of packets to transmit */
2909 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2910 TEST_ASSERT_EQUAL(generate_test_burst(
2911 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
2912 0, 0), burst_size[i],
2913 "failed to generate packet burst");
2916 /* Add rx data to slaves */
2917 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2918 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2919 &gen_pkt_burst[i][0], burst_size[i]);
2922 /* Call rx burst on bonded device */
2923 /* Send burst on bonded port */
2924 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2925 rx_pkt_burst, MAX_PKT_BURST),
2926 burst_size[0] + burst_size[1] + burst_size[2],
2927 "balance rx burst failed\n");
2929 /* Verify bonded device rx count */
2930 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2931 TEST_ASSERT_EQUAL(port_stats.ipackets,
2932 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
2933 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2934 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
2935 burst_size[0] + burst_size[1] + burst_size[2]);
2938 /* Verify bonded slave devices rx counts */
2939 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2940 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
2941 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2942 test_params->slave_port_ids[0],
2943 (unsigned int)port_stats.ipackets, burst_size[0]);
2945 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2946 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
2947 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2948 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
2951 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2952 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
2953 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2954 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
2957 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2958 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2959 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2960 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
2964 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2965 for (j = 0; j < MAX_PKT_BURST; j++) {
2966 if (gen_pkt_burst[i][j] != NULL) {
2967 rte_pktmbuf_free(gen_pkt_burst[i][j]);
2968 gen_pkt_burst[i][j] = NULL;
2973 /* Clean up and remove slaves from bonded device */
2974 return remove_slaves_and_stop_bonded_device();
2978 test_balance_verify_promiscuous_enable_disable(void)
2982 /* Initialize bonded device with 4 slaves in round robin mode */
2983 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2984 BONDING_MODE_BALANCE, 0, 4, 1),
2985 "Failed to intialise bonded device");
2987 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2989 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2990 "Port (%d) promiscuous mode not enabled",
2991 test_params->bonded_port_id);
2993 for (i = 0; i < test_params->bonded_slave_count; i++) {
2994 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
2995 test_params->slave_port_ids[i]), 1,
2996 "Port (%d) promiscuous mode not enabled",
2997 test_params->slave_port_ids[i]);
3000 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3002 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3003 "Port (%d) promiscuous mode not disabled",
3004 test_params->bonded_port_id);
3006 for (i = 0; i < test_params->bonded_slave_count; i++) {
3007 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3008 test_params->slave_port_ids[i]), 0,
3009 "Port (%d) promiscuous mode not disabled",
3010 test_params->slave_port_ids[i]);
3013 /* Clean up and remove slaves from bonded device */
3014 return remove_slaves_and_stop_bonded_device();
3018 test_balance_verify_mac_assignment(void)
3020 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3022 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3023 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3025 /* Initialize bonded device with 2 slaves in active backup mode */
3026 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3027 BONDING_MODE_BALANCE, 0, 2, 1),
3028 "Failed to intialise bonded device");
3030 /* Verify that bonded MACs is that of first slave and that the other slave
3031 * MAC hasn't been changed */
3032 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3033 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3034 sizeof(read_mac_addr)),
3035 "bonded port (%d) mac address not set to that of primary port",
3036 test_params->bonded_port_id);
3038 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3039 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3040 sizeof(read_mac_addr)),
3041 "slave port (%d) mac address not set to that of primary port",
3042 test_params->slave_port_ids[0]);
3044 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3045 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3046 sizeof(read_mac_addr)),
3047 "slave port (%d) mac address not set to that of primary port",
3048 test_params->slave_port_ids[1]);
3050 /* change primary and verify that MAC addresses haven't changed */
3051 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3052 test_params->slave_port_ids[1]),
3053 "Failed to set bonded port (%d) primary port to (%d)\n",
3054 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3056 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3057 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3058 sizeof(read_mac_addr)),
3059 "bonded port (%d) mac address not set to that of primary port",
3060 test_params->bonded_port_id);
3062 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3063 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3064 sizeof(read_mac_addr)),
3065 "slave port (%d) mac address not set to that of primary port",
3066 test_params->slave_port_ids[0]);
3068 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3069 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3070 sizeof(read_mac_addr)),
3071 "slave port (%d) mac address not set to that of primary port",
3072 test_params->slave_port_ids[1]);
3074 /* stop / start bonded device and verify that primary MAC address is
3075 * propagated to bonded device and slaves */
3077 rte_eth_dev_stop(test_params->bonded_port_id);
3079 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3080 "Failed to start bonded device");
3082 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3083 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3084 sizeof(read_mac_addr)),
3085 "bonded port (%d) mac address not set to that of primary port",
3086 test_params->bonded_port_id);
3088 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3089 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3090 sizeof(read_mac_addr)),
3091 "slave port (%d) mac address not set to that of primary port",
3092 test_params->slave_port_ids[0]);
3094 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3095 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3096 sizeof(read_mac_addr)),
3097 "slave port (%d) mac address not set to that of primary port",
3098 test_params->slave_port_ids[1]);
3100 /* Set explicit MAC address */
3101 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3102 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3103 "failed to set MAC");
3105 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3106 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3107 sizeof(read_mac_addr)),
3108 "bonded port (%d) mac address not set to that of bonded port",
3109 test_params->bonded_port_id);
3111 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3112 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3113 sizeof(read_mac_addr)),
3114 "slave port (%d) mac address not as expected\n",
3115 test_params->slave_port_ids[0]);
3117 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3118 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3119 sizeof(read_mac_addr)),
3120 "slave port (%d) mac address not set to that of bonded port",
3121 test_params->slave_port_ids[1]);
3123 /* Clean up and remove slaves from bonded device */
3124 return remove_slaves_and_stop_bonded_device();
3127 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3130 test_balance_verify_slave_link_status_change_behaviour(void)
3132 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3133 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3134 struct rte_eth_stats port_stats;
3136 uint8_t slaves[RTE_MAX_ETHPORTS];
3138 int i, j, burst_size, slave_count;
3140 memset(pkt_burst, 0, sizeof(pkt_burst));
3142 /* Initialize bonded device with 4 slaves in round robin mode */
3143 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3144 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3145 "Failed to intialise bonded device");
3147 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3148 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3149 "Failed to set balance xmit policy.");
3152 /* Verify Current Slaves Count /Active Slave Count is */
3153 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3155 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3156 "Number of slaves (%d) is not as expected (%d).",
3157 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3159 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3160 slaves, RTE_MAX_ETHPORTS);
3161 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3162 "Number of active slaves (%d) is not as expected (%d).",
3163 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3165 /* Set 2 slaves link status to down */
3166 virtual_ethdev_simulate_link_status_interrupt(
3167 test_params->slave_port_ids[1], 0);
3168 virtual_ethdev_simulate_link_status_interrupt(
3169 test_params->slave_port_ids[3], 0);
3171 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3172 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3173 "Number of active slaves (%d) is not as expected (%d).",
3176 /* Send to sets of packet burst and verify that they are balanced across
3180 TEST_ASSERT_EQUAL(generate_test_burst(
3181 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3182 "generate_test_burst failed");
3184 TEST_ASSERT_EQUAL(generate_test_burst(
3185 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3186 "generate_test_burst failed");
3188 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3189 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3190 burst_size, "rte_eth_tx_burst failed");
3192 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3193 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3194 burst_size, "rte_eth_tx_burst failed");
3197 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3198 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3199 "(%d) port_stats.opackets (%d) not as expected (%d).",
3200 test_params->bonded_port_id, (int)port_stats.opackets,
3201 burst_size + burst_size);
3203 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3204 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3205 "(%d) port_stats.opackets (%d) not as expected (%d).",
3206 test_params->slave_port_ids[0], (int)port_stats.opackets,
3209 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3210 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3211 "(%d) port_stats.opackets (%d) not as expected (%d).",
3212 test_params->slave_port_ids[2], (int)port_stats.opackets,
3215 /* verify that all packets get send on primary slave when no other slaves
3217 virtual_ethdev_simulate_link_status_interrupt(
3218 test_params->slave_port_ids[2], 0);
3220 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3221 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3222 "Number of active slaves (%d) is not as expected (%d).",
3225 TEST_ASSERT_EQUAL(generate_test_burst(
3226 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3227 "generate_test_burst failed");
3229 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3230 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3231 burst_size, "rte_eth_tx_burst failed");
3233 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3234 TEST_ASSERT_EQUAL(port_stats.opackets,
3235 (uint64_t)(burst_size + burst_size + burst_size),
3236 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3237 test_params->bonded_port_id, (int)port_stats.opackets,
3238 burst_size + burst_size + burst_size);
3240 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3241 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3242 "(%d) port_stats.opackets (%d) not as expected (%d).",
3243 test_params->slave_port_ids[0], (int)port_stats.opackets,
3244 burst_size + burst_size);
3246 virtual_ethdev_simulate_link_status_interrupt(
3247 test_params->slave_port_ids[0], 0);
3248 virtual_ethdev_simulate_link_status_interrupt(
3249 test_params->slave_port_ids[1], 1);
3250 virtual_ethdev_simulate_link_status_interrupt(
3251 test_params->slave_port_ids[2], 1);
3252 virtual_ethdev_simulate_link_status_interrupt(
3253 test_params->slave_port_ids[3], 1);
3255 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3256 TEST_ASSERT_EQUAL(generate_test_burst(
3257 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3258 "Failed to generate packet burst");
3260 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3261 &pkt_burst[i][0], burst_size);
3264 /* Verify that pkts are not received on slaves with link status down */
3266 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3269 /* Verify bonded device rx count */
3270 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3271 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3272 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3273 test_params->bonded_port_id, (int)port_stats.ipackets,
3276 /* free mbufs allocate for rx testing */
3277 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3278 for (j = 0; j < MAX_PKT_BURST; j++) {
3279 if (pkt_burst[i][j] != NULL) {
3280 rte_pktmbuf_free(pkt_burst[i][j]);
3281 pkt_burst[i][j] = NULL;
3286 /* Clean up and remove slaves from bonded device */
3287 return remove_slaves_and_stop_bonded_device();
3290 #ifdef RTE_MBUF_REFCNT
3291 /** Broadcast Mode Tests */
3294 test_broadcast_tx_burst(void)
3296 int i, pktlen, burst_size;
3297 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3299 struct rte_eth_stats port_stats;
3301 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3302 BONDING_MODE_BROADCAST, 0, 2, 1),
3303 "Failed to intialise bonded device");
3305 initialize_eth_header(test_params->pkt_eth_hdr,
3306 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3308 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3310 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3311 dst_addr_0, pktlen);
3313 burst_size = 20 * test_params->bonded_slave_count;
3315 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3316 "Burst size specified is greater than supported.");
3318 /* Generate a burst of packets to transmit */
3319 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3320 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3321 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3322 1), burst_size, "Failed to generate packet burst");
3324 /* Send burst on bonded port */
3325 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3326 pkts_burst, burst_size), burst_size,
3327 "Bonded Port (%d) rx burst failed, packets transmitted value "
3328 "not as expected (%d)",
3329 test_params->bonded_port_id, burst_size);
3331 /* Verify bonded port tx stats */
3332 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3333 TEST_ASSERT_EQUAL(port_stats.opackets,
3334 (uint64_t)burst_size * test_params->bonded_slave_count,
3335 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3336 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3339 /* Verify slave ports tx stats */
3340 for (i = 0; i < test_params->bonded_slave_count; i++) {
3341 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3342 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3343 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3344 test_params->bonded_port_id,
3345 (unsigned int)port_stats.opackets, burst_size);
3348 /* Put all slaves down and try and transmit */
3349 for (i = 0; i < test_params->bonded_slave_count; i++) {
3351 virtual_ethdev_simulate_link_status_interrupt(
3352 test_params->slave_port_ids[i], 0);
3355 /* Send burst on bonded port */
3356 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3357 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3358 "transmitted an unexpected number of packets");
3360 /* Clean up and remove slaves from bonded device */
3361 return remove_slaves_and_stop_bonded_device();
3365 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3366 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3367 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3368 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3371 test_broadcast_tx_burst_slave_tx_fail(void)
3373 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3374 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3376 struct rte_eth_stats port_stats;
3380 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3381 BONDING_MODE_BROADCAST, 0,
3382 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3383 "Failed to intialise bonded device");
3385 /* Generate test bursts for transmission */
3386 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3387 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3388 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3389 "Failed to generate test packet burst");
3391 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3392 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3393 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3396 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3397 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3398 virtual_ethdev_tx_burst_fn_set_success(
3399 test_params->slave_port_ids[0],
3401 virtual_ethdev_tx_burst_fn_set_success(
3402 test_params->slave_port_ids[1],
3404 virtual_ethdev_tx_burst_fn_set_success(
3405 test_params->slave_port_ids[2],
3408 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3409 test_params->slave_port_ids[0],
3410 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3412 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3413 test_params->slave_port_ids[1],
3414 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3416 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3417 test_params->slave_port_ids[2],
3418 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3420 /* Transmit burst */
3421 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3422 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3424 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3425 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3426 "Transmitted (%d) packets, expected to transmit (%d) packets",
3427 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3428 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3430 /* Verify that failed packet are expected failed packets */
3431 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3432 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3433 "expected mbuf (%d) pointer %p not expected pointer %p",
3434 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3437 /* Verify slave ports tx stats */
3439 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3441 TEST_ASSERT_EQUAL(port_stats.opackets,
3442 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3443 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3444 "Port (%d) opackets value (%u) not as expected (%d)",
3445 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3446 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3447 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3450 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3452 TEST_ASSERT_EQUAL(port_stats.opackets,
3453 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3454 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3455 "Port (%d) opackets value (%u) not as expected (%d)",
3456 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3457 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3458 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3460 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3462 TEST_ASSERT_EQUAL(port_stats.opackets,
3463 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3464 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3465 "Port (%d) opackets value (%u) not as expected (%d)",
3466 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3467 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3468 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3471 /* Verify that all mbufs who transmission failed have a ref value of one */
3472 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3473 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3474 "mbufs refcnts not as expected");
3476 free_mbufs(&pkts_burst[tx_count],
3477 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3479 /* Clean up and remove slaves from bonded device */
3480 return remove_slaves_and_stop_bonded_device();
3483 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3486 test_broadcast_rx_burst(void)
3488 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3490 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3491 struct rte_eth_stats port_stats;
3493 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3496 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3498 /* Initialize bonded device with 4 slaves in round robin mode */
3499 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3500 BONDING_MODE_BROADCAST, 0, 3, 1),
3501 "Failed to intialise bonded device");
3503 /* Generate test bursts of packets to transmit */
3504 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3505 TEST_ASSERT_EQUAL(generate_test_burst(
3506 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3507 burst_size[i], "failed to generate packet burst");
3510 /* Add rx data to slave 0 */
3511 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3512 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3513 &gen_pkt_burst[i][0], burst_size[i]);
3517 /* Call rx burst on bonded device */
3518 /* Send burst on bonded port */
3519 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3520 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3521 burst_size[0] + burst_size[1] + burst_size[2],
3524 /* Verify bonded device rx count */
3525 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3526 TEST_ASSERT_EQUAL(port_stats.ipackets,
3527 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3528 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3529 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3530 burst_size[0] + burst_size[1] + burst_size[2]);
3533 /* Verify bonded slave devices rx counts */
3534 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3535 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3536 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3537 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3540 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3541 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3542 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3543 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3546 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3547 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3548 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3549 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3552 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3553 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3554 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3555 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3558 /* free mbufs allocate for rx testing */
3559 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3560 for (j = 0; j < MAX_PKT_BURST; j++) {
3561 if (gen_pkt_burst[i][j] != NULL) {
3562 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3563 gen_pkt_burst[i][j] = NULL;
3568 /* Clean up and remove slaves from bonded device */
3569 return remove_slaves_and_stop_bonded_device();
3573 test_broadcast_verify_promiscuous_enable_disable(void)
3577 /* Initialize bonded device with 4 slaves in round robin mode */
3578 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3579 BONDING_MODE_BROADCAST, 0, 4, 1),
3580 "Failed to intialise bonded device");
3582 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3585 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3586 "Port (%d) promiscuous mode not enabled",
3587 test_params->bonded_port_id);
3589 for (i = 0; i < test_params->bonded_slave_count; i++) {
3590 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3591 test_params->slave_port_ids[i]), 1,
3592 "Port (%d) promiscuous mode not enabled",
3593 test_params->slave_port_ids[i]);
3596 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3598 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3599 "Port (%d) promiscuous mode not disabled",
3600 test_params->bonded_port_id);
3602 for (i = 0; i < test_params->bonded_slave_count; i++) {
3603 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3604 test_params->slave_port_ids[i]), 0,
3605 "Port (%d) promiscuous mode not disabled",
3606 test_params->slave_port_ids[i]);
3609 /* Clean up and remove slaves from bonded device */
3610 return remove_slaves_and_stop_bonded_device();
3614 test_broadcast_verify_mac_assignment(void)
3616 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3620 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3621 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3623 /* Initialize bonded device with 4 slaves in round robin mode */
3624 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3625 BONDING_MODE_BROADCAST, 0, 4, 1),
3626 "Failed to intialise bonded device");
3628 /* Verify that all MACs are the same as first slave added to bonded
3630 for (i = 0; i < test_params->bonded_slave_count; i++) {
3631 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3632 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3633 sizeof(read_mac_addr)),
3634 "slave port (%d) mac address not set to that of primary port",
3635 test_params->slave_port_ids[i]);
3638 /* change primary and verify that MAC addresses haven't changed */
3639 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3640 test_params->slave_port_ids[2]),
3641 "Failed to set bonded port (%d) primary port to (%d)",
3642 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3644 for (i = 0; i < test_params->bonded_slave_count; i++) {
3645 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3646 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3647 sizeof(read_mac_addr)),
3648 "slave port (%d) mac address has changed to that of primary "
3649 "port without stop/start toggle of bonded device",
3650 test_params->slave_port_ids[i]);
3653 /* stop / start bonded device and verify that primary MAC address is
3654 * propagated to bonded device and slaves */
3656 rte_eth_dev_stop(test_params->bonded_port_id);
3658 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3659 "Failed to start bonded device");
3661 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3662 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3663 sizeof(read_mac_addr)),
3664 "bonded port (%d) mac address not set to that of new primary port",
3665 test_params->slave_port_ids[i]);
3667 for (i = 0; i < test_params->bonded_slave_count; i++) {
3668 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3669 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3670 sizeof(read_mac_addr)),
3671 "slave port (%d) mac address not set to that of new primary "
3672 "port", test_params->slave_port_ids[i]);
3675 /* Set explicit MAC address */
3676 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3677 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3678 "Failed to set MAC address");
3680 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3681 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3682 sizeof(read_mac_addr)),
3683 "bonded port (%d) mac address not set to that of new primary port",
3684 test_params->slave_port_ids[i]);
3687 for (i = 0; i < test_params->bonded_slave_count; i++) {
3688 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3689 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3690 sizeof(read_mac_addr)),
3691 "slave port (%d) mac address not set to that of new primary "
3692 "port", test_params->slave_port_ids[i]);
3695 /* Clean up and remove slaves from bonded device */
3696 return remove_slaves_and_stop_bonded_device();
3699 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3701 test_broadcast_verify_slave_link_status_change_behaviour(void)
3703 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3704 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3705 struct rte_eth_stats port_stats;
3707 uint8_t slaves[RTE_MAX_ETHPORTS];
3709 int i, j, burst_size, slave_count;
3711 memset(pkt_burst, 0, sizeof(pkt_burst));
3713 /* Initialize bonded device with 4 slaves in round robin mode */
3714 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3715 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3716 1), "Failed to intialise bonded device");
3718 /* Verify Current Slaves Count /Active Slave Count is */
3719 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3721 TEST_ASSERT_EQUAL(slave_count, 4,
3722 "Number of slaves (%d) is not as expected (%d).",
3725 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3726 slaves, RTE_MAX_ETHPORTS);
3727 TEST_ASSERT_EQUAL(slave_count, 4,
3728 "Number of active slaves (%d) is not as expected (%d).",
3731 /* Set 2 slaves link status to down */
3732 virtual_ethdev_simulate_link_status_interrupt(
3733 test_params->slave_port_ids[1], 0);
3734 virtual_ethdev_simulate_link_status_interrupt(
3735 test_params->slave_port_ids[3], 0);
3737 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3738 slaves, RTE_MAX_ETHPORTS);
3739 TEST_ASSERT_EQUAL(slave_count, 2,
3740 "Number of active slaves (%d) is not as expected (%d).",
3743 for (i = 0; i < test_params->bonded_slave_count; i++)
3744 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3746 /* Verify that pkts are not sent on slaves with link status down */
3749 TEST_ASSERT_EQUAL(generate_test_burst(
3750 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3751 "generate_test_burst failed");
3753 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3754 &pkt_burst[0][0], burst_size), burst_size,
3755 "rte_eth_tx_burst failed\n");
3757 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3758 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3759 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3760 test_params->bonded_port_id, (int)port_stats.opackets,
3761 burst_size * slave_count);
3763 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3764 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3765 "(%d) port_stats.opackets not as expected",
3766 test_params->slave_port_ids[0]);
3768 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3769 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3770 "(%d) port_stats.opackets not as expected",
3771 test_params->slave_port_ids[1]);
3773 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3774 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3775 "(%d) port_stats.opackets not as expected",
3776 test_params->slave_port_ids[2]);
3779 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3780 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3781 "(%d) port_stats.opackets not as expected",
3782 test_params->slave_port_ids[3]);
3785 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3786 TEST_ASSERT_EQUAL(generate_test_burst(
3787 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3788 burst_size, "failed to generate packet burst");
3790 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3791 &pkt_burst[i][0], burst_size);
3794 /* Verify that pkts are not received on slaves with link status down */
3795 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3796 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3797 burst_size + burst_size, "rte_eth_rx_burst failed");
3800 /* Verify bonded device rx count */
3801 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3802 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3803 "(%d) port_stats.ipackets not as expected\n",
3804 test_params->bonded_port_id);
3806 /* free mbufs allocate for rx testing */
3807 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3808 for (j = 0; j < MAX_PKT_BURST; j++) {
3809 if (pkt_burst[i][j] != NULL) {
3810 rte_pktmbuf_free(pkt_burst[i][j]);
3811 pkt_burst[i][j] = NULL;
3816 /* Clean up and remove slaves from bonded device */
3817 return remove_slaves_and_stop_bonded_device();
3822 test_reconfigure_bonded_device(void)
3824 test_params->nb_rx_q = 4;
3825 test_params->nb_tx_q = 4;
3827 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3828 "failed to reconfigure bonded device");
3830 test_params->nb_rx_q = 2;
3831 test_params->nb_tx_q = 2;
3833 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3834 "failed to reconfigure bonded device with less rx/tx queues");
3841 test_close_bonded_device(void)
3843 rte_eth_dev_close(test_params->bonded_port_id);
3848 testsuite_teardown(void)
3850 if (test_params->pkt_eth_hdr != NULL) {
3851 free(test_params->pkt_eth_hdr);
3852 test_params->pkt_eth_hdr = NULL;
3855 /* Clean up and remove slaves from bonded device */
3856 return remove_slaves_and_stop_bonded_device();
3860 test_tlb_tx_burst(void)
3862 int i, burst_size, nb_tx;
3863 uint64_t nb_tx2 = 0;
3864 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
3865 struct rte_eth_stats port_stats[32];
3866 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
3868 uint64_t floor_obytes = 0, ceiling_obytes = 0;
3870 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
3871 (BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 1, 3, 1),
3872 "Failed to initialise bonded device");
3874 burst_size = 20 * test_params->bonded_slave_count;
3876 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3877 "Burst size specified is greater than supported.\n");
3880 /* Generate 400000 test bursts in 2s of packets to transmit */
3881 for (i = 0; i < 400000; i++) {
3882 /*test two types of mac src own(bonding) and others */
3884 initialize_eth_header(test_params->pkt_eth_hdr,
3885 (struct ether_addr *)src_mac,
3886 (struct ether_addr *)dst_mac_0, 0, 0);
3888 initialize_eth_header(test_params->pkt_eth_hdr,
3889 (struct ether_addr *)test_params->default_slave_mac,
3890 (struct ether_addr *)dst_mac_0, 0, 0);
3892 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3894 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3895 dst_addr_0, pktlen);
3896 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
3897 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3898 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
3899 /* Send burst on bonded port */
3900 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
3904 TEST_ASSERT_EQUAL(nb_tx, burst_size,
3905 "number of packet not equal burst size");
3911 /* Verify bonded port tx stats */
3912 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
3914 all_bond_opackets = port_stats[0].opackets;
3915 all_bond_obytes = port_stats[0].obytes;
3917 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
3918 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
3919 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
3923 /* Verify slave ports tx stats */
3924 for (i = 0; i < test_params->bonded_slave_count; i++) {
3925 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
3926 sum_ports_opackets += port_stats[i].opackets;
3929 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
3930 "Total packets sent by slaves is not equal to packets sent by bond interface");
3931 /* distribution of packets on each slave within +/- 10% of the expected value. */
3932 for (i = 0; i < test_params->bonded_slave_count; i++) {
3934 floor_obytes = (all_bond_obytes*90)/(test_params->bonded_slave_count*100);
3935 ceiling_obytes = (all_bond_obytes*110)/(test_params->bonded_slave_count*100);
3936 TEST_ASSERT(port_stats[i].obytes >= floor_obytes &&
3937 port_stats[i].obytes <= ceiling_obytes,
3938 "Distribution is not even");
3940 /* Put all slaves down and try and transmit */
3941 for (i = 0; i < test_params->bonded_slave_count; i++) {
3942 virtual_ethdev_simulate_link_status_interrupt(
3943 test_params->slave_port_ids[i], 0);
3946 /* Send burst on bonded port */
3947 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
3949 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
3951 /* Clean ugit checkout masterp and remove slaves from bonded device */
3952 return remove_slaves_and_stop_bonded_device();
3955 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
3958 test_tlb_rx_burst(void)
3960 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
3961 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3963 struct rte_eth_stats port_stats;
3967 uint16_t i, j, nb_rx, burst_size = 17;
3969 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
3970 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3971 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING,
3972 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
3973 "Failed to initialize bonded device");
3976 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
3977 TEST_ASSERT(primary_port >= 0,
3978 "failed to get primary slave for bonded port (%d)",
3979 test_params->bonded_port_id);
3981 for (i = 0; i < test_params->bonded_slave_count; i++) {
3982 /* Generate test bursts of packets to transmit */
3983 TEST_ASSERT_EQUAL(generate_test_burst(
3984 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
3985 "burst generation failed");
3987 /* Add rx data to slave */
3988 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3989 &gen_pkt_burst[0], burst_size);
3991 /* Call rx burst on bonded device */
3992 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
3993 &rx_pkt_burst[0], MAX_PKT_BURST);
3995 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
3997 if (test_params->slave_port_ids[i] == primary_port) {
3998 /* Verify bonded device rx count */
3999 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4000 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4001 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4002 test_params->bonded_port_id,
4003 (unsigned int)port_stats.ipackets, burst_size);
4005 /* Verify bonded slave devices rx count */
4006 for (j = 0; j < test_params->bonded_slave_count; j++) {
4007 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4009 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4010 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4011 test_params->slave_port_ids[i],
4012 (unsigned int)port_stats.ipackets, burst_size);
4014 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4015 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4016 test_params->slave_port_ids[i],
4017 (unsigned int)port_stats.ipackets, 0);
4021 for (j = 0; j < test_params->bonded_slave_count; j++) {
4022 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4023 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4024 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4025 test_params->slave_port_ids[i],
4026 (unsigned int)port_stats.ipackets, 0);
4031 for (i = 0; i < burst_size; i++)
4032 rte_pktmbuf_free(rx_pkt_burst[i]);
4034 /* reset bonded device stats */
4035 rte_eth_stats_reset(test_params->bonded_port_id);
4038 /* Clean up and remove slaves from bonded device */
4039 return remove_slaves_and_stop_bonded_device();
4043 test_tlb_verify_promiscuous_enable_disable(void)
4045 int i, primary_port, promiscuous_en;
4047 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4048 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4049 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0, 4, 1),
4050 "Failed to initialize bonded device");
4052 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4053 TEST_ASSERT(primary_port >= 0,
4054 "failed to get primary slave for bonded port (%d)",
4055 test_params->bonded_port_id);
4057 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4059 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4060 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4061 "Port (%d) promiscuous mode not enabled\n",
4062 test_params->bonded_port_id);
4063 for (i = 0; i < test_params->bonded_slave_count; i++) {
4064 promiscuous_en = rte_eth_promiscuous_get(
4065 test_params->slave_port_ids[i]);
4066 if (primary_port == test_params->slave_port_ids[i]) {
4067 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4068 "Port (%d) promiscuous mode not enabled\n",
4069 test_params->bonded_port_id);
4071 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4072 "Port (%d) promiscuous mode enabled\n",
4073 test_params->bonded_port_id);
4078 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4080 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4081 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4082 "Port (%d) promiscuous mode not disabled\n",
4083 test_params->bonded_port_id);
4085 for (i = 0; i < test_params->bonded_slave_count; i++) {
4086 promiscuous_en = rte_eth_promiscuous_get(
4087 test_params->slave_port_ids[i]);
4088 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4089 "slave port (%d) promiscuous mode not disabled\n",
4090 test_params->slave_port_ids[i]);
4093 /* Clean up and remove slaves from bonded device */
4094 return remove_slaves_and_stop_bonded_device();
4098 test_tlb_verify_mac_assignment(void)
4100 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4102 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4103 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4105 /* Initialize bonded device with 2 slaves in active backup mode */
4106 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4107 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0, 2, 1),
4108 "Failed to initialize bonded device");
4110 /* Verify that bonded MACs is that of first slave and that the other slave
4111 * MAC hasn't been changed */
4112 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4113 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4114 sizeof(read_mac_addr)),
4115 "bonded port (%d) mac address not set to that of primary port",
4116 test_params->bonded_port_id);
4118 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4119 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4120 sizeof(read_mac_addr)),
4121 "slave port (%d) mac address not set to that of primary port",
4122 test_params->slave_port_ids[0]);
4124 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4125 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4126 sizeof(read_mac_addr)),
4127 "slave port (%d) mac address not as expected",
4128 test_params->slave_port_ids[1]);
4130 /* change primary and verify that MAC addresses haven't changed */
4131 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4132 test_params->slave_port_ids[1]), 0,
4133 "Failed to set bonded port (%d) primary port to (%d)",
4134 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4136 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4137 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4138 sizeof(read_mac_addr)),
4139 "bonded port (%d) mac address not set to that of primary port",
4140 test_params->bonded_port_id);
4142 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4143 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4144 sizeof(read_mac_addr)),
4145 "slave port (%d) mac address not set to that of primary port",
4146 test_params->slave_port_ids[0]);
4148 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4149 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4150 sizeof(read_mac_addr)),
4151 "slave port (%d) mac address not as expected",
4152 test_params->slave_port_ids[1]);
4154 /* stop / start bonded device and verify that primary MAC address is
4155 * propagated to bonded device and slaves */
4157 rte_eth_dev_stop(test_params->bonded_port_id);
4159 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4160 "Failed to start device");
4162 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4163 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4164 sizeof(read_mac_addr)),
4165 "bonded port (%d) mac address not set to that of primary port",
4166 test_params->bonded_port_id);
4168 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4169 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4170 sizeof(read_mac_addr)),
4171 "slave port (%d) mac address not as expected",
4172 test_params->slave_port_ids[0]);
4174 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4175 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4176 sizeof(read_mac_addr)),
4177 "slave port (%d) mac address not set to that of primary port",
4178 test_params->slave_port_ids[1]);
4181 /* Set explicit MAC address */
4182 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4183 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4184 "failed to set MAC addres");
4186 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4187 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4188 sizeof(read_mac_addr)),
4189 "bonded port (%d) mac address not set to that of bonded port",
4190 test_params->bonded_port_id);
4192 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4193 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4194 sizeof(read_mac_addr)),
4195 "slave port (%d) mac address not as expected",
4196 test_params->slave_port_ids[0]);
4198 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4199 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4200 sizeof(read_mac_addr)),
4201 "slave port (%d) mac address not set to that of bonded port",
4202 test_params->slave_port_ids[1]);
4204 /* Clean up and remove slaves from bonded device */
4205 return remove_slaves_and_stop_bonded_device();
4209 test_tlb_verify_slave_link_status_change_failover(void)
4211 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4212 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4213 struct rte_eth_stats port_stats;
4215 uint8_t slaves[RTE_MAX_ETHPORTS];
4217 int i, j, burst_size, slave_count, primary_port;
4221 memset(pkt_burst, 0, sizeof(pkt_burst));
4225 /* Initialize bonded device with 4 slaves in round robin mode */
4226 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4227 BONDING_MODE_ADAPTIVE_TRANSMIT_LOAD_BALANCING, 0,
4228 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4229 "Failed to initialize bonded device with slaves");
4231 /* Verify Current Slaves Count /Active Slave Count is */
4232 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4234 TEST_ASSERT_EQUAL(slave_count, 4,
4235 "Number of slaves (%d) is not as expected (%d).\n",
4238 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4239 slaves, RTE_MAX_ETHPORTS);
4240 TEST_ASSERT_EQUAL(slave_count, (int)4,
4241 "Number of slaves (%d) is not as expected (%d).\n",
4244 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4245 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4246 "Primary port not as expected");
4248 /* Bring 2 slaves down and verify active slave count */
4249 virtual_ethdev_simulate_link_status_interrupt(
4250 test_params->slave_port_ids[1], 0);
4251 virtual_ethdev_simulate_link_status_interrupt(
4252 test_params->slave_port_ids[3], 0);
4254 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4255 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4256 "Number of active slaves (%d) is not as expected (%d).",
4259 virtual_ethdev_simulate_link_status_interrupt(
4260 test_params->slave_port_ids[1], 1);
4261 virtual_ethdev_simulate_link_status_interrupt(
4262 test_params->slave_port_ids[3], 1);
4265 /* Bring primary port down, verify that active slave count is 3 and primary
4267 virtual_ethdev_simulate_link_status_interrupt(
4268 test_params->slave_port_ids[0], 0);
4270 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4271 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4272 "Number of active slaves (%d) is not as expected (%d).",
4275 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4276 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4277 "Primary port not as expected");
4278 rte_delay_us(500000);
4279 /* Verify that pkts are sent on new primary slave */
4280 for (i = 0; i < 4; i++) {
4281 TEST_ASSERT_EQUAL(generate_test_burst(
4282 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4283 "generate_test_burst failed\n");
4284 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4285 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4286 "rte_eth_tx_burst failed\n");
4287 rte_delay_us(11000);
4290 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4291 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4292 "(%d) port_stats.opackets not as expected\n",
4293 test_params->slave_port_ids[2]);
4295 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4296 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4297 "(%d) port_stats.opackets not as expected\n",
4298 test_params->slave_port_ids[0]);
4300 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4301 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4302 "(%d) port_stats.opackets not as expected\n",
4303 test_params->slave_port_ids[1]);
4305 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4306 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4307 "(%d) port_stats.opackets not as expected\n",
4308 test_params->slave_port_ids[3]);
4311 /* Generate packet burst for testing */
4313 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4314 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4318 virtual_ethdev_add_mbufs_to_rx_queue(
4319 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4322 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4323 MAX_PKT_BURST) != burst_size) {
4324 printf("rte_eth_rx_burst\n");
4329 /* Verify bonded device rx count */
4330 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4331 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4332 "(%d) port_stats.ipackets not as expected\n",
4333 test_params->bonded_port_id);
4337 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4338 for (j = 0; j < MAX_PKT_BURST; j++) {
4339 if (pkt_burst[i][j] != NULL) {
4340 rte_pktmbuf_free(pkt_burst[i][j]);
4341 pkt_burst[i][j] = NULL;
4347 /* Clean up and remove slaves from bonded device */
4348 return remove_slaves_and_stop_bonded_device();
4352 static struct unit_test_suite link_bonding_test_suite = {
4353 .suite_name = "Link Bonding Unit Test Suite",
4354 .setup = test_setup,
4355 .teardown = testsuite_teardown,
4356 .unit_test_cases = {
4357 TEST_CASE(test_create_bonded_device),
4358 TEST_CASE(test_create_bonded_device_with_invalid_params),
4359 TEST_CASE(test_add_slave_to_bonded_device),
4360 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4361 TEST_CASE(test_remove_slave_from_bonded_device),
4362 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4363 TEST_CASE(test_get_slaves_from_bonded_device),
4364 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4365 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4366 TEST_CASE(test_start_bonded_device),
4367 TEST_CASE(test_stop_bonded_device),
4368 TEST_CASE(test_set_bonding_mode),
4369 TEST_CASE(test_set_primary_slave),
4370 TEST_CASE(test_set_explicit_bonded_mac),
4371 TEST_CASE(test_status_interrupt),
4372 TEST_CASE(test_adding_slave_after_bonded_device_started),
4373 TEST_CASE(test_roundrobin_tx_burst),
4374 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4375 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4376 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4377 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4378 TEST_CASE(test_roundrobin_verify_mac_assignment),
4379 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4380 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4381 TEST_CASE(test_activebackup_tx_burst),
4382 TEST_CASE(test_activebackup_rx_burst),
4383 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4384 TEST_CASE(test_activebackup_verify_mac_assignment),
4385 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4386 TEST_CASE(test_balance_xmit_policy_configuration),
4387 TEST_CASE(test_balance_l2_tx_burst),
4388 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4389 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4390 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4391 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4392 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4393 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4394 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4395 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4396 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4397 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4398 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4399 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4400 TEST_CASE(test_balance_rx_burst),
4401 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4402 TEST_CASE(test_balance_verify_mac_assignment),
4403 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4404 TEST_CASE(test_tlb_tx_burst),
4405 TEST_CASE(test_tlb_rx_burst),
4406 TEST_CASE(test_tlb_verify_mac_assignment),
4407 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4408 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4409 #ifdef RTE_MBUF_REFCNT
4410 TEST_CASE(test_broadcast_tx_burst),
4411 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4412 TEST_CASE(test_broadcast_rx_burst),
4413 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4414 TEST_CASE(test_broadcast_verify_mac_assignment),
4415 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4417 TEST_CASE(test_reconfigure_bonded_device),
4418 TEST_CASE(test_close_bonded_device),
4420 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
4426 test_link_bonding(void)
4428 return unit_test_suite_runner(&link_bonding_test_suite);
4431 static struct test_command link_bonding_cmd = {
4432 .command = "link_bonding_autotest",
4433 .callback = test_link_bonding,
4435 REGISTER_TEST_COMMAND(link_bonding_cmd);