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 (6)
62 #define RX_RING_SIZE 128
63 #define RX_FREE_THRESH 32
68 #define TX_RING_SIZE 512
69 #define TX_FREE_THRESH 32
73 #define TX_RSBIT_THRESH 32
74 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
75 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
76 ETH_TXQ_FLAGS_NOXSUMTCP)
78 #define MBUF_PAYLOAD_SIZE (2048)
79 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
80 #define MBUF_CACHE_SIZE (250)
81 #define BURST_SIZE (32)
83 #define DEFAULT_MBUF_DATA_SIZE (2048)
84 #define RTE_TEST_RX_DESC_MAX (2048)
85 #define RTE_TEST_TX_DESC_MAX (2048)
86 #define MAX_PKT_BURST (512)
87 #define DEF_PKT_BURST (16)
89 #define BONDED_DEV_NAME ("unit_test_bonded_device")
91 #define INVALID_SOCKET_ID (-1)
92 #define INVALID_PORT_ID (-1)
93 #define INVALID_BONDING_MODE (-1)
96 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
97 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
99 struct link_bonding_unittest_params {
100 int8_t bonded_port_id;
101 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
102 uint8_t bonded_slave_count;
103 uint8_t bonding_mode;
108 struct rte_mempool *mbuf_pool;
110 struct ether_addr *default_slave_mac;
111 struct ether_addr *default_bonded_mac;
114 struct ether_hdr *pkt_eth_hdr;
115 struct ipv4_hdr *pkt_ipv4_hdr;
116 struct ipv6_hdr *pkt_ipv6_hdr;
117 struct udp_hdr *pkt_udp_hdr;
121 static struct ipv4_hdr pkt_ipv4_hdr;
122 static struct ipv6_hdr pkt_ipv6_hdr;
123 static struct udp_hdr pkt_udp_hdr;
125 static struct link_bonding_unittest_params default_params = {
126 .bonded_port_id = -1,
127 .slave_port_ids = { -1 },
128 .bonded_slave_count = 0,
129 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
136 .default_slave_mac = (struct ether_addr *)slave_mac,
137 .default_bonded_mac = (struct ether_addr *)bonded_mac,
140 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
141 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
142 .pkt_udp_hdr = &pkt_udp_hdr
146 static struct link_bonding_unittest_params *test_params = &default_params;
148 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
150 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
152 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
154 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
156 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
157 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
158 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
159 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
160 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
161 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
163 static uint16_t src_port = 1024;
164 static uint16_t dst_port_0 = 1024;
165 static uint16_t dst_port_1 = 2024;
167 static uint16_t vlan_id = 0x100;
169 struct rte_eth_rxmode rx_mode = {
170 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
172 .header_split = 0, /**< Header Split disabled. */
173 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
174 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
175 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
176 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
177 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
178 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
181 struct rte_fdir_conf fdir_conf = {
182 .mode = RTE_FDIR_MODE_NONE,
183 .pballoc = RTE_FDIR_PBALLOC_64K,
184 .status = RTE_FDIR_REPORT_STATUS,
185 .flexbytes_offset = 0x6,
189 static struct rte_eth_conf default_pmd_conf = {
191 .mq_mode = ETH_MQ_RX_NONE,
192 .max_rx_pkt_len = ETHER_MAX_LEN,
194 .header_split = 0, /**< Header Split disabled */
195 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
196 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
197 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
198 .hw_strip_crc = 0, /**< CRC stripped by hardware */
201 .mq_mode = ETH_MQ_TX_NONE,
206 static const struct rte_eth_rxconf rx_conf_default = {
208 .pthresh = RX_PTHRESH,
209 .hthresh = RX_HTHRESH,
210 .wthresh = RX_WTHRESH,
212 .rx_free_thresh = RX_FREE_THRESH,
216 static struct rte_eth_txconf tx_conf_default = {
218 .pthresh = TX_PTHRESH,
219 .hthresh = TX_HTHRESH,
220 .wthresh = TX_WTHRESH,
222 .tx_free_thresh = TX_FREE_THRESH,
223 .tx_rs_thresh = TX_RSBIT_THRESH,
224 .txq_flags = TX_Q_FLAGS
229 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
234 default_pmd_conf.intr_conf.lsc = 1;
236 default_pmd_conf.intr_conf.lsc = 0;
238 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
239 test_params->nb_tx_q, &default_pmd_conf),
240 "rte_eth_dev_configure for port %d failed", port_id);
242 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
243 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
244 rte_eth_dev_socket_id(port_id), &rx_conf_default,
245 test_params->mbuf_pool) ,
246 "rte_eth_rx_queue_setup for port %d failed", port_id);
248 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
249 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
250 rte_eth_dev_socket_id(port_id), &tx_conf_default),
251 "rte_eth_tx_queue_setup for port %d failed", port_id);
254 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
255 "rte_eth_dev_start for port %d failed", port_id);
260 static int slaves_initialized;
262 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
263 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
269 int i, nb_mbuf_per_pool;
270 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
272 /* Allocate ethernet packet header with space for VLAN header */
273 if (test_params->pkt_eth_hdr == NULL) {
274 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
275 sizeof(struct vlan_hdr));
277 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
278 "Ethernet header struct allocation failed!");
281 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
282 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
283 if (test_params->mbuf_pool == NULL) {
284 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
285 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
286 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
288 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
289 "rte_mempool_create failed");
292 /* Create / Initialize virtual eth devs */
293 if (!slaves_initialized) {
294 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
295 char pmd_name[RTE_ETH_NAME_MAX_LEN];
297 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
299 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
301 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
302 mac_addr, rte_socket_id(), 1);
303 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
304 "Failed to create virtual virtual ethdev %s", pmd_name);
306 TEST_ASSERT_SUCCESS(configure_ethdev(
307 test_params->slave_port_ids[i], 1, 0),
308 "Failed to configure virtual ethdev %s", pmd_name);
310 slaves_initialized = 1;
317 test_create_bonded_device(void)
319 int current_slave_count;
321 uint8_t slaves[RTE_MAX_ETHPORTS];
323 /* Don't try to recreate bonded device if re-running test suite*/
324 if (test_params->bonded_port_id == -1) {
325 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
326 test_params->bonding_mode, rte_socket_id());
328 TEST_ASSERT(test_params->bonded_port_id >= 0,
329 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
331 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
332 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
335 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
336 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
337 test_params->bonded_port_id, test_params->bonding_mode);
339 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
340 slaves, RTE_MAX_ETHPORTS);
342 TEST_ASSERT_EQUAL(current_slave_count, 0,
343 "Number of slaves %d is great than expected %d.",
344 current_slave_count, 0);
346 current_slave_count = rte_eth_bond_active_slaves_get(
347 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
349 TEST_ASSERT_EQUAL(current_slave_count, 0,
350 "Number of active slaves %d is great than expected %d.",
351 current_slave_count, 0);
358 test_create_bonded_device_with_invalid_params(void)
362 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
365 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
367 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
369 test_params->bonding_mode = INVALID_BONDING_MODE;
371 /* Invalid bonding mode */
372 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
374 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
376 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
378 /* Invalid socket id */
379 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
381 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
387 test_add_slave_to_bonded_device(void)
389 int current_slave_count;
391 uint8_t slaves[RTE_MAX_ETHPORTS];
393 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
394 test_params->slave_port_ids[test_params->bonded_slave_count]),
395 "Failed to add slave (%d) to bonded port (%d).",
396 test_params->slave_port_ids[test_params->bonded_slave_count],
397 test_params->bonded_port_id);
399 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
400 slaves, RTE_MAX_ETHPORTS);
401 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
402 "Number of slaves (%d) is greater than expected (%d).",
403 current_slave_count, test_params->bonded_slave_count + 1);
405 current_slave_count = rte_eth_bond_active_slaves_get(
406 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
407 TEST_ASSERT_EQUAL(current_slave_count, 0,
408 "Number of active slaves (%d) is not as expected (%d).\n",
409 current_slave_count, 0);
411 test_params->bonded_slave_count++;
417 test_add_slave_to_invalid_bonded_device(void)
419 /* Invalid port ID */
420 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
421 test_params->slave_port_ids[test_params->bonded_slave_count]),
422 "Expected call to failed as invalid port specified.");
424 /* Non bonded device */
425 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
426 test_params->slave_port_ids[test_params->bonded_slave_count]),
427 "Expected call to failed as invalid port specified.");
434 test_remove_slave_from_bonded_device(void)
436 int current_slave_count;
437 struct ether_addr read_mac_addr, *mac_addr;
438 uint8_t slaves[RTE_MAX_ETHPORTS];
440 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
441 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
442 "Failed to remove slave %d from bonded port (%d).",
443 test_params->slave_port_ids[test_params->bonded_slave_count-1],
444 test_params->bonded_port_id);
447 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
448 slaves, RTE_MAX_ETHPORTS);
450 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
451 "Number of slaves (%d) is great than expected (%d).\n",
452 current_slave_count, test_params->bonded_slave_count - 1);
455 mac_addr = (struct ether_addr *)slave_mac;
456 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
457 test_params->bonded_slave_count-1;
460 test_params->slave_port_ids[test_params->bonded_slave_count-1],
462 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
463 "bonded port mac address not set to that of primary port\n");
466 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
468 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
471 test_params->bonded_slave_count--;
477 test_remove_slave_from_invalid_bonded_device(void)
479 /* Invalid port ID */
480 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
481 test_params->bonded_port_id + 5,
482 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
483 "Expected call to failed as invalid port specified.");
485 /* Non bonded device */
486 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
487 test_params->slave_port_ids[0],
488 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
489 "Expected call to failed as invalid port specified.");
494 static int bonded_id = 2;
497 test_add_already_bonded_slave_to_bonded_device(void)
499 int port_id, current_slave_count;
500 uint8_t slaves[RTE_MAX_ETHPORTS];
501 char pmd_name[RTE_ETH_NAME_MAX_LEN];
503 test_add_slave_to_bonded_device();
505 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
506 slaves, RTE_MAX_ETHPORTS);
507 TEST_ASSERT_EQUAL(current_slave_count, 1,
508 "Number of slaves (%d) is not that expected (%d).",
509 current_slave_count, 1);
511 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
513 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
515 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
517 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
518 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
520 "Added slave (%d) to bonded port (%d) unexpectedly.",
521 test_params->slave_port_ids[test_params->bonded_slave_count-1],
524 return test_remove_slave_from_bonded_device();
529 test_get_slaves_from_bonded_device(void)
531 int current_slave_count;
532 uint8_t slaves[RTE_MAX_ETHPORTS];
534 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
535 "Failed to add slave to bonded device");
537 /* Invalid port id */
538 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
540 TEST_ASSERT(current_slave_count < 0,
541 "Invalid port id unexpectedly succeeded");
543 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
544 slaves, RTE_MAX_ETHPORTS);
545 TEST_ASSERT(current_slave_count < 0,
546 "Invalid port id unexpectedly succeeded");
548 /* Invalid slaves pointer */
549 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
550 NULL, RTE_MAX_ETHPORTS);
551 TEST_ASSERT(current_slave_count < 0,
552 "Invalid slave array unexpectedly succeeded");
554 current_slave_count = rte_eth_bond_active_slaves_get(
555 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
556 TEST_ASSERT(current_slave_count < 0,
557 "Invalid slave array unexpectedly succeeded");
559 /* non bonded device*/
560 current_slave_count = rte_eth_bond_slaves_get(
561 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
562 TEST_ASSERT(current_slave_count < 0,
563 "Invalid port id unexpectedly succeeded");
565 current_slave_count = rte_eth_bond_active_slaves_get(
566 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
567 TEST_ASSERT(current_slave_count < 0,
568 "Invalid port id unexpectedly succeeded");
570 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
571 "Failed to remove slaves from bonded device");
578 test_add_remove_multiple_slaves_to_from_bonded_device(void)
582 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
583 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
584 "Failed to add slave to bonded device");
586 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
587 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
588 "Failed to remove slaves from bonded device");
594 enable_bonded_slaves(void)
598 for (i = 0; i < test_params->bonded_slave_count; i++) {
599 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
602 virtual_ethdev_simulate_link_status_interrupt(
603 test_params->slave_port_ids[i], 1);
608 test_start_bonded_device(void)
610 struct rte_eth_link link_status;
612 int current_slave_count, current_bonding_mode, primary_port;
613 uint8_t slaves[RTE_MAX_ETHPORTS];
615 /* Add slave to bonded device*/
616 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
617 "Failed to add slave to bonded device");
619 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
620 "Failed to start bonded pmd eth device %d.",
621 test_params->bonded_port_id);
623 /* Change link status of virtual pmd so it will be added to the active
624 * slave list of the bonded device*/
625 virtual_ethdev_simulate_link_status_interrupt(
626 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
628 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
629 slaves, RTE_MAX_ETHPORTS);
630 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
631 "Number of slaves (%d) is not expected value (%d).",
632 current_slave_count, test_params->bonded_slave_count);
634 current_slave_count = rte_eth_bond_active_slaves_get(
635 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
636 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
637 "Number of active slaves (%d) is not expected value (%d).",
638 current_slave_count, test_params->bonded_slave_count);
640 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
641 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
642 "Bonded device mode (%d) is not expected value (%d).\n",
643 current_bonding_mode, test_params->bonding_mode);
645 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
646 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
647 "Primary port (%d) is not expected value (%d).",
648 primary_port, test_params->slave_port_ids[0]);
650 rte_eth_link_get(test_params->bonded_port_id, &link_status);
651 TEST_ASSERT_EQUAL(link_status.link_status, 1,
652 "Bonded port (%d) status (%d) is not expected value (%d).\n",
653 test_params->bonded_port_id, link_status.link_status, 1);
659 test_stop_bonded_device(void)
661 int current_slave_count;
662 uint8_t slaves[RTE_MAX_ETHPORTS];
664 struct rte_eth_link link_status;
666 rte_eth_dev_stop(test_params->bonded_port_id);
668 rte_eth_link_get(test_params->bonded_port_id, &link_status);
669 TEST_ASSERT_EQUAL(link_status.link_status, 0,
670 "Bonded port (%d) status (%d) is not expected value (%d).",
671 test_params->bonded_port_id, link_status.link_status, 0);
673 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
674 slaves, RTE_MAX_ETHPORTS);
675 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
676 "Number of slaves (%d) is not expected value (%d).",
677 current_slave_count, test_params->bonded_slave_count);
679 current_slave_count = rte_eth_bond_active_slaves_get(
680 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
681 TEST_ASSERT_EQUAL(current_slave_count, 0,
682 "Number of active slaves (%d) is not expected value (%d).",
683 current_slave_count, 0);
689 remove_slaves_and_stop_bonded_device(void)
691 /* Clean up and remove slaves from bonded device */
692 while (test_params->bonded_slave_count > 0)
693 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
694 "test_remove_slave_from_bonded_device failed");
696 rte_eth_dev_stop(test_params->bonded_port_id);
697 rte_eth_stats_reset(test_params->bonded_port_id);
698 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
704 test_set_bonding_mode(void)
708 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
709 BONDING_MODE_ACTIVE_BACKUP,
710 BONDING_MODE_BALANCE,
711 #ifdef RTE_MBUF_REFCNT
712 BONDING_MODE_BROADCAST
716 /* Test supported link bonding modes */
717 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
718 /* Invalid port ID */
719 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
721 "Expected call to failed as invalid port (%d) specified.",
724 /* Non bonded device */
725 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
727 "Expected call to failed as invalid port (%d) specified.",
728 test_params->slave_port_ids[0]);
730 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
732 "Failed to set link bonding mode on port (%d) to (%d).",
733 test_params->bonded_port_id, bonding_modes[i]);
735 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
736 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
737 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
738 bonding_mode, test_params->bonded_port_id,
741 /* Invalid port ID */
742 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
743 TEST_ASSERT(bonding_mode < 0,
744 "Expected call to failed as invalid port (%d) specified.",
747 /* Non bonded device */
748 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
749 TEST_ASSERT(bonding_mode < 0,
750 "Expected call to failed as invalid port (%d) specified.",
751 test_params->slave_port_ids[0]);
754 return remove_slaves_and_stop_bonded_device();
758 test_set_primary_slave(void)
761 struct ether_addr read_mac_addr;
762 struct ether_addr *expected_mac_addr;
764 /* Add 4 slaves to bonded device */
765 for (i = test_params->bonded_slave_count; i < 4; i++)
766 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
767 "Failed to add slave to bonded device.");
769 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
770 BONDING_MODE_ROUND_ROBIN),
771 "Failed to set link bonding mode on port (%d) to (%d).",
772 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
774 /* Invalid port ID */
775 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
776 test_params->slave_port_ids[i]),
777 "Expected call to failed as invalid port specified.");
779 /* Non bonded device */
780 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
781 test_params->slave_port_ids[i]),
782 "Expected call to failed as invalid port specified.");
784 /* Set slave as primary
785 * Verify slave it is now primary slave
786 * Verify that MAC address of bonded device is that of primary slave
787 * Verify that MAC address of all bonded slaves are that of primary slave
789 for (i = 0; i < 4; i++) {
790 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
791 test_params->slave_port_ids[i]),
792 "Failed to set bonded port (%d) primary port to (%d)",
793 test_params->bonded_port_id, test_params->slave_port_ids[i]);
795 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
796 TEST_ASSERT(retval >= 0,
797 "Failed to read primary port from bonded port (%d)\n",
798 test_params->bonded_port_id);
800 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
801 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
802 test_params->bonded_port_id, retval,
803 test_params->slave_port_ids[i]);
805 /* stop/start bonded eth dev to apply new MAC */
806 rte_eth_dev_stop(test_params->bonded_port_id);
808 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
809 "Failed to start bonded port %d",
810 test_params->bonded_port_id);
812 expected_mac_addr = (struct ether_addr *)&slave_mac;
813 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
815 /* Check primary slave MAC */
816 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
817 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
818 sizeof(read_mac_addr)),
819 "bonded port mac address not set to that of primary port\n");
821 /* Check bonded MAC */
822 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
823 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
824 sizeof(read_mac_addr)),
825 "bonded port mac address not set to that of primary port\n");
827 /* Check other slaves MACs */
828 for (j = 0; j < 4; j++) {
830 rte_eth_macaddr_get(test_params->slave_port_ids[j],
832 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
833 sizeof(read_mac_addr)),
834 "slave port mac address not set to that of primary "
841 /* Test with none existent port */
842 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
843 "read primary port from expectedly");
845 /* Test with slave port */
846 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
847 "read primary port from expectedly\n");
849 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
850 "Failed to stop and remove slaves from bonded device");
853 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
854 "read primary port from expectedly\n");
860 test_set_explicit_bonded_mac(void)
863 struct ether_addr read_mac_addr;
864 struct ether_addr *mac_addr;
866 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
868 mac_addr = (struct ether_addr *)explicit_bonded_mac;
870 /* Invalid port ID */
871 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
872 "Expected call to failed as invalid port specified.");
874 /* Non bonded device */
875 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
876 test_params->slave_port_ids[0], mac_addr),
877 "Expected call to failed as invalid port specified.");
879 /* NULL MAC address */
880 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
881 test_params->bonded_port_id, NULL),
882 "Expected call to failed as NULL MAC specified");
884 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
885 test_params->bonded_port_id, mac_addr),
886 "Failed to set MAC address on bonded port (%d)",
887 test_params->bonded_port_id);
889 /* Add 4 slaves to bonded device */
890 for (i = test_params->bonded_slave_count; i < 4; i++) {
891 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
892 "Failed to add slave to bonded device.\n");
895 /* Check bonded MAC */
896 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
897 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
898 "bonded port mac address not set to that of primary port");
900 /* Check other slaves MACs */
901 for (i = 0; i < 4; i++) {
902 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
903 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
904 sizeof(read_mac_addr)),
905 "slave port mac address not set to that of primary port");
908 /* test resetting mac address on bonded device */
910 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
911 "Failed to reset MAC address on bonded port (%d)",
912 test_params->bonded_port_id);
915 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
916 "Reset MAC address on bonded port (%d) unexpectedly",
917 test_params->slave_port_ids[1]);
919 /* test resetting mac address on bonded device with no slaves */
920 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
921 "Failed to remove slaves and stop bonded device");
923 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
924 "Failed to reset MAC address on bonded port (%d)",
925 test_params->bonded_port_id);
930 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
933 test_set_bonded_port_initialization_mac_assignment(void)
935 int i, slave_count, bonded_port_id;
937 uint8_t slaves[RTE_MAX_ETHPORTS];
938 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
940 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
942 /* Initialize default values for MAC addresses */
943 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
944 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
947 * 1. a - Create / configure bonded / slave ethdevs
949 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
950 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
951 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
953 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
954 "Failed to configure bonded ethdev");
956 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
957 char pmd_name[RTE_ETH_NAME_MAX_LEN];
959 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
961 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
963 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
964 &slave_mac_addr, rte_socket_id(), 1);
966 TEST_ASSERT(slave_port_ids[i] >= 0,
967 "Failed to create slave ethdev %s", pmd_name);
969 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
970 "Failed to configure virtual ethdev %s",
976 * 2. Add slave ethdevs to bonded device
978 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
979 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
981 "Failed to add slave (%d) to bonded port (%d).",
982 slave_port_ids[i], bonded_port_id);
985 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
987 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
988 "Number of slaves (%d) is not as expected (%d)",
989 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
993 * 3. Set explicit MAC address on bonded ethdev
995 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
996 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
998 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
999 bonded_port_id, &bonded_mac_addr),
1000 "Failed to set MAC address on bonded port (%d)",
1004 /* 4. a - Start bonded ethdev
1005 * b - Enable slave devices
1006 * c - Verify bonded/slaves ethdev MAC addresses
1008 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1009 "Failed to start bonded pmd eth device %d.",
1012 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1013 virtual_ethdev_simulate_link_status_interrupt(
1014 slave_port_ids[i], 1);
1017 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1018 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1019 sizeof(read_mac_addr)),
1020 "bonded port mac address not as expected");
1022 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1023 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1024 sizeof(read_mac_addr)),
1025 "slave port 0 mac address not as expected");
1027 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1028 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1029 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1030 sizeof(read_mac_addr)),
1031 "slave port 1 mac address not as expected");
1033 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1034 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1035 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1036 sizeof(read_mac_addr)),
1037 "slave port 2 mac address not as expected");
1040 /* 7. a - Change primary port
1041 * b - Stop / Start bonded port
1042 * d - Verify slave ethdev MAC addresses
1044 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1046 "failed to set primary port on bonded device.");
1048 rte_eth_dev_stop(bonded_port_id);
1049 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1050 "Failed to start bonded pmd eth device %d.",
1053 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1054 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1055 sizeof(read_mac_addr)),
1056 "bonded port mac address not as expected");
1058 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1059 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1060 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1061 sizeof(read_mac_addr)),
1062 "slave port 0 mac address not as expected");
1064 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1065 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1066 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1067 sizeof(read_mac_addr)),
1068 "slave port 1 mac address not as expected");
1070 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1071 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1072 sizeof(read_mac_addr)),
1073 "slave port 2 mac address not as expected");
1075 /* 6. a - Stop bonded ethdev
1076 * b - remove slave ethdevs
1077 * c - Verify slave ethdevs MACs are restored
1079 rte_eth_dev_stop(bonded_port_id);
1081 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1082 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1084 "Failed to remove slave %d from bonded port (%d).",
1085 slave_port_ids[i], bonded_port_id);
1088 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1091 TEST_ASSERT_EQUAL(slave_count, 0,
1092 "Number of slaves (%d) is great than expected (%d).",
1095 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1096 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1097 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1098 sizeof(read_mac_addr)),
1099 "slave port 0 mac address not as expected");
1101 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1102 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1103 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1104 sizeof(read_mac_addr)),
1105 "slave port 1 mac address not as expected");
1107 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1108 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1109 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1110 sizeof(read_mac_addr)),
1111 "slave port 2 mac address not as expected");
1118 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1119 uint8_t number_of_slaves, uint8_t enable_slave)
1121 /* Configure bonded device */
1122 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1123 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1124 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1127 /* Add slaves to bonded device */
1128 while (number_of_slaves > test_params->bonded_slave_count)
1129 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1130 "Failed to add slave (%d to bonding port (%d).",
1131 test_params->bonded_slave_count - 1,
1132 test_params->bonded_port_id);
1134 /* Set link bonding mode */
1135 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1137 "Failed to set link bonding mode on port (%d) to (%d).",
1138 test_params->bonded_port_id, bonding_mode);
1140 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1141 "Failed to start bonded pmd eth device %d.",
1142 test_params->bonded_port_id);
1145 enable_bonded_slaves();
1151 test_adding_slave_after_bonded_device_started(void)
1155 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1156 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1157 "Failed to add slaves to bonded device");
1159 /* Enabled slave devices */
1160 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1161 virtual_ethdev_simulate_link_status_interrupt(
1162 test_params->slave_port_ids[i], 1);
1165 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1166 test_params->slave_port_ids[test_params->bonded_slave_count]),
1167 "Failed to add slave to bonded port.\n");
1169 rte_eth_stats_reset(
1170 test_params->slave_port_ids[test_params->bonded_slave_count]);
1172 test_params->bonded_slave_count++;
1174 return remove_slaves_and_stop_bonded_device();
1177 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1178 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1180 int test_lsc_interrupt_count;
1184 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1185 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1187 pthread_mutex_lock(&mutex);
1188 test_lsc_interrupt_count++;
1190 pthread_cond_signal(&cvar);
1191 pthread_mutex_unlock(&mutex);
1195 lsc_timeout(int wait_us)
1202 gettimeofday(&tp, NULL);
1204 /* Convert from timeval to timespec */
1205 ts.tv_sec = tp.tv_sec;
1206 ts.tv_nsec = tp.tv_usec * 1000;
1207 ts.tv_nsec += wait_us * 1000;
1209 pthread_mutex_lock(&mutex);
1210 if (test_lsc_interrupt_count < 1)
1211 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1213 pthread_mutex_unlock(&mutex);
1215 if (retval == 0 && test_lsc_interrupt_count < 1)
1222 test_status_interrupt(void)
1225 uint8_t slaves[RTE_MAX_ETHPORTS];
1227 /* initialized bonding device with T slaves */
1228 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1229 BONDING_MODE_ROUND_ROBIN, 1,
1230 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1231 "Failed to initialise bonded device");
1233 test_lsc_interrupt_count = 0;
1235 /* register link status change interrupt callback */
1236 rte_eth_dev_callback_register(test_params->bonded_port_id,
1237 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1238 &test_params->bonded_port_id);
1240 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1241 slaves, RTE_MAX_ETHPORTS);
1243 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1244 "Number of active slaves (%d) is not as expected (%d)",
1245 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1247 /* Bring all 4 slaves link status to down and test that we have received a
1249 virtual_ethdev_simulate_link_status_interrupt(
1250 test_params->slave_port_ids[0], 0);
1251 virtual_ethdev_simulate_link_status_interrupt(
1252 test_params->slave_port_ids[1], 0);
1253 virtual_ethdev_simulate_link_status_interrupt(
1254 test_params->slave_port_ids[2], 0);
1256 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1257 "Received a link status change interrupt unexpectedly");
1259 virtual_ethdev_simulate_link_status_interrupt(
1260 test_params->slave_port_ids[3], 0);
1262 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1263 "timed out waiting for interrupt");
1265 TEST_ASSERT(test_lsc_interrupt_count > 0,
1266 "Did not receive link status change interrupt");
1268 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1269 slaves, RTE_MAX_ETHPORTS);
1271 TEST_ASSERT_EQUAL(slave_count, 0,
1272 "Number of active slaves (%d) is not as expected (%d)",
1275 /* bring one slave port up so link status will change */
1276 test_lsc_interrupt_count = 0;
1278 virtual_ethdev_simulate_link_status_interrupt(
1279 test_params->slave_port_ids[0], 1);
1281 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1282 "timed out waiting for interrupt");
1284 /* test that we have received another lsc interrupt */
1285 TEST_ASSERT(test_lsc_interrupt_count > 0,
1286 "Did not receive link status change interrupt");
1288 /* Verify that calling the same slave lsc interrupt doesn't cause another
1289 * lsc interrupt from bonded device */
1290 test_lsc_interrupt_count = 0;
1292 virtual_ethdev_simulate_link_status_interrupt(
1293 test_params->slave_port_ids[0], 1);
1295 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1296 "received unexpected interrupt");
1298 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1299 "Did not receive link status change interrupt");
1302 /* unregister lsc callback before exiting */
1303 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1304 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1305 &test_params->bonded_port_id);
1307 /* Clean up and remove slaves from bonded device */
1308 return remove_slaves_and_stop_bonded_device();
1312 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1313 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1314 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1316 uint16_t pktlen, generated_burst_size, ether_type;
1320 ether_type = ETHER_TYPE_IPv4;
1322 ether_type = ETHER_TYPE_IPv6;
1325 initialize_eth_header(test_params->pkt_eth_hdr,
1326 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1327 ether_type, vlan, vlan_id);
1329 initialize_eth_header(test_params->pkt_eth_hdr,
1330 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1331 ether_type, vlan, vlan_id);
1334 if (toggle_udp_port)
1335 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1338 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1343 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1344 dst_addr_1, pktlen);
1346 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1347 dst_addr_0, pktlen);
1349 ip_hdr = test_params->pkt_ipv4_hdr;
1352 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1353 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1356 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1357 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1360 ip_hdr = test_params->pkt_ipv6_hdr;
1363 /* Generate burst of packets to transmit */
1364 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1365 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1366 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1368 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1369 "Failed to generate packet burst");
1371 return generated_burst_size;
1374 /** Round Robin Mode Tests */
1377 test_roundrobin_tx_burst(void)
1380 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1381 struct rte_eth_stats port_stats;
1383 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1384 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1385 "Failed to intialise bonded device");
1387 burst_size = 20 * test_params->bonded_slave_count;
1389 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1390 "Burst size specified is greater than supported.");
1392 /* Generate test bursts of packets to transmit */
1393 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1394 burst_size, "failed to generate test burst");
1396 /* Send burst on bonded port */
1397 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1398 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1401 /* Verify bonded port tx stats */
1402 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1403 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1404 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1405 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1408 /* Verify slave ports tx stats */
1409 for (i = 0; i < test_params->bonded_slave_count; i++) {
1410 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1411 TEST_ASSERT_EQUAL(port_stats.opackets,
1412 (uint64_t)burst_size / test_params->bonded_slave_count,
1413 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1414 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1415 burst_size / test_params->bonded_slave_count);
1418 /* Put all slaves down and try and transmit */
1419 for (i = 0; i < test_params->bonded_slave_count; i++) {
1420 virtual_ethdev_simulate_link_status_interrupt(
1421 test_params->slave_port_ids[i], 0);
1424 /* Send burst on bonded port */
1425 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1426 pkt_burst, burst_size), 0,
1427 "tx burst return unexpected value");
1429 /* Clean up and remove slaves from bonded device */
1430 return remove_slaves_and_stop_bonded_device();
1433 #ifdef RTE_MBUF_REFCNT
1435 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1439 for (i = 0; i < nb_mbufs; i++) {
1440 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1441 TEST_ASSERT_EQUAL(refcnt, val,
1442 "mbuf ref count (%d)is not the expected value (%d)",
1451 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1455 for (i = 0; i < nb_mbufs; i++)
1456 rte_pktmbuf_free(mbufs[i]);
1459 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1460 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1461 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1462 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1465 test_roundrobin_tx_burst_slave_tx_fail(void)
1467 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1468 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1470 struct rte_eth_stats port_stats;
1472 int i, first_fail_idx, tx_count;
1474 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1475 BONDING_MODE_ROUND_ROBIN, 0,
1476 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1477 "Failed to intialise bonded device");
1479 /* Generate test bursts of packets to transmit */
1480 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1481 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1482 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1483 "Failed to generate test packet burst");
1485 /* Copy references to packets which we expect not to be transmitted */
1486 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1487 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1488 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1489 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1491 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1492 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1493 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1496 /* Set virtual slave to only fail transmission of
1497 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1498 virtual_ethdev_tx_burst_fn_set_success(
1499 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1502 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1503 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1504 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1506 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1507 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1509 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1510 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1511 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1512 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1513 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1515 /* Verify that failed packet are expected failed packets */
1516 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1517 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1518 "expected mbuf (%d) pointer %p not expected pointer %p",
1519 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1522 /* Verify bonded port tx stats */
1523 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1525 TEST_ASSERT_EQUAL(port_stats.opackets,
1526 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1527 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1528 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1529 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1530 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1531 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1533 /* Verify slave ports tx stats */
1534 for (i = 0; i < test_params->bonded_slave_count; i++) {
1535 int slave_expected_tx_count;
1537 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1539 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1540 test_params->bonded_slave_count;
1542 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1543 slave_expected_tx_count = slave_expected_tx_count -
1544 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1546 TEST_ASSERT_EQUAL(port_stats.opackets,
1547 (uint64_t)slave_expected_tx_count,
1548 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1549 test_params->slave_port_ids[i],
1550 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1553 #ifdef RTE_MBUF_REFCNT
1554 /* Verify that all mbufs have a ref value of zero */
1555 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1556 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1557 "mbufs refcnts not as expected");
1559 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1561 /* Clean up and remove slaves from bonded device */
1562 return remove_slaves_and_stop_bonded_device();
1566 test_roundrobin_rx_burst_on_single_slave(void)
1568 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1569 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1571 struct rte_eth_stats port_stats;
1573 int i, j, burst_size = 25;
1575 /* Initialize bonded device with 4 slaves in round robin mode */
1576 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1577 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1578 "Failed to initialize bonded device with slaves");
1580 /* Generate test bursts of packets to transmit */
1581 TEST_ASSERT_EQUAL(generate_test_burst(
1582 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1583 "burst generation failed");
1585 for (i = 0; i < test_params->bonded_slave_count; i++) {
1586 /* Add rx data to slave */
1587 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1588 &gen_pkt_burst[0], burst_size);
1590 /* Call rx burst on bonded device */
1591 /* Send burst on bonded port */
1592 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1593 test_params->bonded_port_id, 0, rx_pkt_burst,
1594 MAX_PKT_BURST), burst_size,
1595 "round-robin rx burst failed");
1597 /* Verify bonded device rx count */
1598 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1599 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1600 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1601 test_params->bonded_port_id,
1602 (unsigned int)port_stats.ipackets, burst_size);
1606 /* Verify bonded slave devices rx count */
1607 /* Verify slave ports tx stats */
1608 for (j = 0; j < test_params->bonded_slave_count; j++) {
1609 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1612 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1613 "Slave Port (%d) ipackets value (%u) not as expected"
1614 " (%d)", test_params->slave_port_ids[i],
1615 (unsigned int)port_stats.ipackets, burst_size);
1617 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1618 "Slave Port (%d) ipackets value (%u) not as expected"
1619 " (%d)", test_params->slave_port_ids[i],
1620 (unsigned int)port_stats.ipackets, 0);
1623 /* Reset bonded slaves stats */
1624 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1626 /* reset bonded device stats */
1627 rte_eth_stats_reset(test_params->bonded_port_id);
1631 for (i = 0; i < MAX_PKT_BURST; i++) {
1632 if (gen_pkt_burst[i] != NULL)
1633 rte_pktmbuf_free(gen_pkt_burst[i]);
1635 if (rx_pkt_burst[i] != NULL)
1636 rte_pktmbuf_free(rx_pkt_burst[i]);
1640 /* Clean up and remove slaves from bonded device */
1641 return remove_slaves_and_stop_bonded_device();
1644 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1647 test_roundrobin_rx_burst_on_multiple_slaves(void)
1649 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1651 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1652 struct rte_eth_stats port_stats;
1654 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1657 /* Initialize bonded device with 4 slaves in round robin mode */
1658 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1659 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1660 "Failed to initialize bonded device with slaves");
1662 /* Generate test bursts of packets to transmit */
1663 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1664 TEST_ASSERT_EQUAL(generate_test_burst(
1665 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1666 burst_size[i], "burst generation failed");
1669 /* Add rx data to slaves */
1670 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1671 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1672 &gen_pkt_burst[i][0], burst_size[i]);
1675 /* Call rx burst on bonded device */
1676 /* Send burst on bonded port */
1677 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1679 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1680 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1681 burst_size[0] + burst_size[1] + burst_size[2]);
1683 /* Verify bonded device rx count */
1684 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1685 TEST_ASSERT_EQUAL(port_stats.ipackets,
1686 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1687 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1688 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1689 burst_size[0] + burst_size[1] + burst_size[2]);
1691 /* Verify bonded slave devices rx counts */
1692 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1693 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1694 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1695 test_params->slave_port_ids[0],
1696 (unsigned int)port_stats.ipackets, burst_size[0]);
1698 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1699 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1700 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1701 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1704 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1705 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1706 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1707 test_params->slave_port_ids[2],
1708 (unsigned int)port_stats.ipackets, burst_size[2]);
1710 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1711 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1712 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1713 test_params->slave_port_ids[3],
1714 (unsigned int)port_stats.ipackets, 0);
1717 for (i = 0; i < MAX_PKT_BURST; i++) {
1718 if (rx_pkt_burst[i] != NULL)
1719 rte_pktmbuf_free(rx_pkt_burst[i]);
1722 /* Clean up and remove slaves from bonded device */
1723 return remove_slaves_and_stop_bonded_device();
1727 test_roundrobin_verify_mac_assignment(void)
1729 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1733 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1734 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1736 /* Initialize bonded device with 4 slaves in round robin mode */
1737 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1738 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1739 "Failed to initialize bonded device with slaves");
1741 /* Verify that all MACs are the same as first slave added to bonded dev */
1742 for (i = 0; i < test_params->bonded_slave_count; i++) {
1743 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1744 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1745 sizeof(read_mac_addr)),
1746 "slave port (%d) mac address not set to that of primary port",
1747 test_params->slave_port_ids[i]);
1750 /* change primary and verify that MAC addresses haven't changed */
1751 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1752 test_params->slave_port_ids[2]),
1753 "Failed to set bonded port (%d) primary port to (%d)",
1754 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1756 for (i = 0; i < test_params->bonded_slave_count; i++) {
1757 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1758 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1759 sizeof(read_mac_addr)),
1760 "slave port (%d) mac address has changed to that of primary"
1761 " port without stop/start toggle of bonded device",
1762 test_params->slave_port_ids[i]);
1765 /* stop / start bonded device and verify that primary MAC address is
1766 * propagate to bonded device and slaves */
1767 rte_eth_dev_stop(test_params->bonded_port_id);
1769 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1770 "Failed to start bonded device");
1772 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1773 TEST_ASSERT_SUCCESS(
1774 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1775 "bonded port (%d) mac address not set to that of new primary port",
1776 test_params->slave_port_ids[i]);
1778 for (i = 0; i < test_params->bonded_slave_count; i++) {
1779 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1780 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1781 sizeof(read_mac_addr)),
1782 "slave port (%d) mac address not set to that of new primary"
1783 " port", test_params->slave_port_ids[i]);
1786 /* Set explicit MAC address */
1787 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1788 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1789 "Failed to set MAC");
1791 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1792 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1793 sizeof(read_mac_addr)),
1794 "bonded port (%d) mac address not set to that of new primary port",
1795 test_params->slave_port_ids[i]);
1797 for (i = 0; i < test_params->bonded_slave_count; i++) {
1798 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1799 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1800 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1801 " that of new primary port\n", test_params->slave_port_ids[i]);
1804 /* Clean up and remove slaves from bonded device */
1805 return remove_slaves_and_stop_bonded_device();
1809 test_roundrobin_verify_promiscuous_enable_disable(void)
1811 int i, promiscuous_en;
1813 /* Initialize bonded device with 4 slaves in round robin mode */
1814 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1815 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1816 "Failed to initialize bonded device with slaves");
1818 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1820 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1821 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1822 "Port (%d) promiscuous mode not enabled",
1823 test_params->bonded_port_id);
1825 for (i = 0; i < test_params->bonded_slave_count; i++) {
1826 promiscuous_en = rte_eth_promiscuous_get(
1827 test_params->slave_port_ids[i]);
1828 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1829 "slave port (%d) promiscuous mode not enabled",
1830 test_params->slave_port_ids[i]);
1833 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1835 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1836 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1837 "Port (%d) promiscuous mode not disabled\n",
1838 test_params->bonded_port_id);
1840 for (i = 0; i < test_params->bonded_slave_count; i++) {
1841 promiscuous_en = rte_eth_promiscuous_get(
1842 test_params->slave_port_ids[i]);
1843 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1844 "Port (%d) promiscuous mode not disabled\n",
1845 test_params->slave_port_ids[i]);
1848 /* Clean up and remove slaves from bonded device */
1849 return remove_slaves_and_stop_bonded_device();
1852 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1853 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1856 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1858 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1859 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1860 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1862 struct rte_eth_stats port_stats;
1863 uint8_t slaves[RTE_MAX_ETHPORTS];
1865 int i, burst_size, slave_count;
1867 /* NULL all pointers in array to simplify cleanup */
1868 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1870 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1871 * in round robin mode */
1872 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1873 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1874 "Failed to initialize bonded device with slaves");
1876 /* Verify Current Slaves Count /Active Slave Count is */
1877 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1879 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1880 "Number of slaves (%d) is not as expected (%d).",
1881 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1883 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1884 slaves, RTE_MAX_ETHPORTS);
1885 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1886 "Number of active slaves (%d) is not as expected (%d).",
1887 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1889 /* Set 2 slaves eth_devs link status to down */
1890 virtual_ethdev_simulate_link_status_interrupt(
1891 test_params->slave_port_ids[1], 0);
1892 virtual_ethdev_simulate_link_status_interrupt(
1893 test_params->slave_port_ids[3], 0);
1895 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1896 slaves, RTE_MAX_ETHPORTS);
1897 TEST_ASSERT_EQUAL(slave_count,
1898 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1899 "Number of active slaves (%d) is not as expected (%d).\n",
1900 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1904 /* Verify that pkts are not sent on slaves with link status down:
1906 * 1. Generate test burst of traffic
1907 * 2. Transmit burst on bonded eth_dev
1908 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1909 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1912 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1913 burst_size, "generate_test_burst failed");
1915 rte_eth_stats_reset(test_params->bonded_port_id);
1919 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1920 burst_size), burst_size, "rte_eth_tx_burst failed");
1922 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1923 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1924 "Port (%d) opackets stats (%d) not expected (%d) value",
1925 test_params->bonded_port_id, (int)port_stats.opackets,
1928 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1929 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1930 "Port (%d) opackets stats (%d) not expected (%d) value",
1931 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1933 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1934 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1935 "Port (%d) opackets stats (%d) not expected (%d) value",
1936 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1938 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1939 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1940 "Port (%d) opackets stats (%d) not expected (%d) value",
1941 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1943 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1944 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1945 "Port (%d) opackets stats (%d) not expected (%d) value",
1946 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1948 /* Verify that pkts are not sent on slaves with link status down:
1950 * 1. Generate test bursts of traffic
1951 * 2. Add bursts on to virtual eth_devs
1952 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1953 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1954 * 4. Verify stats for bonded eth_dev
1955 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1957 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1958 TEST_ASSERT_EQUAL(generate_test_burst(
1959 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1960 burst_size, "failed to generate packet burst");
1962 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1963 &gen_pkt_burst[i][0], burst_size);
1966 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1967 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1968 burst_size + burst_size,
1969 "rte_eth_rx_burst failed");
1971 /* Verify bonded device rx count */
1972 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1973 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1974 "(%d) port_stats.ipackets not as expected\n",
1975 test_params->bonded_port_id);
1978 for (i = 0; i < MAX_PKT_BURST; i++) {
1979 if (rx_pkt_burst[i] != NULL)
1980 rte_pktmbuf_free(rx_pkt_burst[i]);
1982 if (gen_pkt_burst[1][i] != NULL)
1983 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1985 if (gen_pkt_burst[3][i] != NULL)
1986 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1989 /* Clean up and remove slaves from bonded device */
1990 return remove_slaves_and_stop_bonded_device();
1993 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1995 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1998 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2001 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2003 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
2004 char slave_name[RTE_ETH_NAME_MAX_LEN];
2008 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2009 /* Generate slave name / MAC address */
2010 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2011 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2013 /* Create slave devices with no ISR Support */
2014 if (polling_test_slaves[i] == -1) {
2015 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2016 rte_socket_id(), 0);
2017 TEST_ASSERT(polling_test_slaves[i] >= 0,
2018 "Failed to create virtual virtual ethdev %s\n", slave_name);
2020 /* Configure slave */
2021 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2022 "Failed to configure virtual ethdev %s(%d)", slave_name,
2023 polling_test_slaves[i]);
2026 /* Add slave to bonded device */
2027 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2028 polling_test_slaves[i]),
2029 "Failed to add slave %s(%d) to bonded device %d",
2030 slave_name, polling_test_slaves[i],
2031 test_params->bonded_port_id);
2034 /* Initialize bonded device */
2035 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2036 "Failed to configure bonded device %d",
2037 test_params->bonded_port_id);
2040 /* Register link status change interrupt callback */
2041 rte_eth_dev_callback_register(test_params->bonded_port_id,
2042 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2043 &test_params->bonded_port_id);
2045 /* link status change callback for first slave link up */
2046 test_lsc_interrupt_count = 0;
2048 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2050 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2053 /* no link status change callback for second slave link up */
2054 test_lsc_interrupt_count = 0;
2056 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2058 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2060 /* link status change callback for both slave links down */
2061 test_lsc_interrupt_count = 0;
2063 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2064 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2066 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2068 /* Un-Register link status change interrupt callback */
2069 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2070 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2071 &test_params->bonded_port_id);
2074 /* Clean up and remove slaves from bonded device */
2075 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2077 TEST_ASSERT_SUCCESS(
2078 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2079 polling_test_slaves[i]),
2080 "Failed to remove slave %d from bonded port (%d)",
2081 polling_test_slaves[i], test_params->bonded_port_id);
2084 return remove_slaves_and_stop_bonded_device();
2088 /** Active Backup Mode Tests */
2091 test_activebackup_tx_burst(void)
2093 int i, pktlen, primary_port, burst_size;
2094 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2095 struct rte_eth_stats port_stats;
2097 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2098 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2099 "Failed to initialize bonded device with slaves");
2101 initialize_eth_header(test_params->pkt_eth_hdr,
2102 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2103 ETHER_TYPE_IPv4, 0, 0);
2104 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2106 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2107 dst_addr_0, pktlen);
2109 burst_size = 20 * test_params->bonded_slave_count;
2111 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2112 "Burst size specified is greater than supported.");
2114 /* Generate a burst of packets to transmit */
2115 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2116 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2117 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2118 burst_size, "failed to generate burst correctly");
2120 /* Send burst on bonded port */
2121 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2122 burst_size), burst_size, "tx burst failed");
2124 /* Verify bonded port tx stats */
2125 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2126 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2127 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2128 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2131 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2133 /* Verify slave ports tx stats */
2134 for (i = 0; i < test_params->bonded_slave_count; i++) {
2135 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2136 if (test_params->slave_port_ids[i] == primary_port) {
2137 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2138 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2139 test_params->bonded_port_id,
2140 (unsigned int)port_stats.opackets,
2141 burst_size / test_params->bonded_slave_count);
2143 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2144 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2145 test_params->bonded_port_id,
2146 (unsigned int)port_stats.opackets, 0);
2150 /* Put all slaves down and try and transmit */
2151 for (i = 0; i < test_params->bonded_slave_count; i++) {
2152 virtual_ethdev_simulate_link_status_interrupt(
2153 test_params->slave_port_ids[i], 0);
2156 /* Send burst on bonded port */
2157 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2158 pkts_burst, burst_size), 0, "Sending empty burst failed");
2160 /* Clean up and remove slaves from bonded device */
2161 return remove_slaves_and_stop_bonded_device();
2164 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2167 test_activebackup_rx_burst(void)
2169 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2170 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2172 struct rte_eth_stats port_stats;
2176 int i, j, burst_size = 17;
2178 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2179 BONDING_MODE_ACTIVE_BACKUP, 0,
2180 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2181 "Failed to initialize bonded device with slaves");
2183 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2184 TEST_ASSERT(primary_port >= 0,
2185 "failed to get primary slave for bonded port (%d)",
2186 test_params->bonded_port_id);
2188 for (i = 0; i < test_params->bonded_slave_count; i++) {
2189 /* Generate test bursts of packets to transmit */
2190 TEST_ASSERT_EQUAL(generate_test_burst(
2191 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2192 burst_size, "burst generation failed");
2194 /* Add rx data to slave */
2195 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2196 &gen_pkt_burst[0], burst_size);
2198 /* Call rx burst on bonded device */
2199 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2200 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2201 "rte_eth_rx_burst failed");
2203 if (test_params->slave_port_ids[i] == primary_port) {
2204 /* Verify bonded device rx count */
2205 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2206 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2207 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2208 test_params->bonded_port_id,
2209 (unsigned int)port_stats.ipackets, burst_size);
2211 /* Verify bonded slave devices rx count */
2212 for (j = 0; j < test_params->bonded_slave_count; j++) {
2213 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2215 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2216 "Slave Port (%d) ipackets value (%u) not as "
2217 "expected (%d)", test_params->slave_port_ids[i],
2218 (unsigned int)port_stats.ipackets, burst_size);
2220 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2221 "Slave Port (%d) ipackets value (%u) not as "
2222 "expected (%d)\n", test_params->slave_port_ids[i],
2223 (unsigned int)port_stats.ipackets, 0);
2227 for (j = 0; j < test_params->bonded_slave_count; j++) {
2228 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2229 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2230 "Slave Port (%d) ipackets value (%u) not as expected "
2231 "(%d)", test_params->slave_port_ids[i],
2232 (unsigned int)port_stats.ipackets, 0);
2237 for (i = 0; i < MAX_PKT_BURST; i++) {
2238 if (rx_pkt_burst[i] != NULL) {
2239 rte_pktmbuf_free(rx_pkt_burst[i]);
2240 rx_pkt_burst[i] = NULL;
2244 /* reset bonded device stats */
2245 rte_eth_stats_reset(test_params->bonded_port_id);
2248 /* Clean up and remove slaves from bonded device */
2249 return remove_slaves_and_stop_bonded_device();
2253 test_activebackup_verify_promiscuous_enable_disable(void)
2255 int i, primary_port, promiscuous_en;
2257 /* Initialize bonded device with 4 slaves in round robin mode */
2258 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2259 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2260 "Failed to initialize bonded device with slaves");
2262 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2263 TEST_ASSERT(primary_port >= 0,
2264 "failed to get primary slave for bonded port (%d)",
2265 test_params->bonded_port_id);
2267 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2269 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2270 "Port (%d) promiscuous mode not enabled",
2271 test_params->bonded_port_id);
2273 for (i = 0; i < test_params->bonded_slave_count; i++) {
2274 promiscuous_en = rte_eth_promiscuous_get(
2275 test_params->slave_port_ids[i]);
2276 if (primary_port == test_params->slave_port_ids[i]) {
2277 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2278 "slave port (%d) promiscuous mode not enabled",
2279 test_params->slave_port_ids[i]);
2281 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2282 "slave port (%d) promiscuous mode enabled",
2283 test_params->slave_port_ids[i]);
2288 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2290 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2291 "Port (%d) promiscuous mode not disabled\n",
2292 test_params->bonded_port_id);
2294 for (i = 0; i < test_params->bonded_slave_count; i++) {
2295 promiscuous_en = rte_eth_promiscuous_get(
2296 test_params->slave_port_ids[i]);
2297 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2298 "slave port (%d) promiscuous mode not disabled\n",
2299 test_params->slave_port_ids[i]);
2302 /* Clean up and remove slaves from bonded device */
2303 return remove_slaves_and_stop_bonded_device();
2307 test_activebackup_verify_mac_assignment(void)
2309 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2311 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2312 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2314 /* Initialize bonded device with 2 slaves in active backup mode */
2315 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2316 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2317 "Failed to initialize bonded device with slaves");
2319 /* Verify that bonded MACs is that of first slave and that the other slave
2320 * MAC hasn't been changed */
2321 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2323 sizeof(read_mac_addr)),
2324 "bonded port (%d) mac address not set to that of primary port",
2325 test_params->bonded_port_id);
2327 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2328 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2329 sizeof(read_mac_addr)),
2330 "slave port (%d) mac address not set to that of primary port",
2331 test_params->slave_port_ids[0]);
2333 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2335 sizeof(read_mac_addr)),
2336 "slave port (%d) mac address not as expected",
2337 test_params->slave_port_ids[1]);
2339 /* change primary and verify that MAC addresses haven't changed */
2340 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2341 test_params->slave_port_ids[1]), 0,
2342 "Failed to set bonded port (%d) primary port to (%d)",
2343 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2345 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2347 sizeof(read_mac_addr)),
2348 "bonded port (%d) mac address not set to that of primary port",
2349 test_params->bonded_port_id);
2351 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2352 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2353 sizeof(read_mac_addr)),
2354 "slave port (%d) mac address not set to that of primary port",
2355 test_params->slave_port_ids[0]);
2357 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2358 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2359 sizeof(read_mac_addr)),
2360 "slave port (%d) mac address not as expected",
2361 test_params->slave_port_ids[1]);
2363 /* stop / start bonded device and verify that primary MAC address is
2364 * propagated to bonded device and slaves */
2366 rte_eth_dev_stop(test_params->bonded_port_id);
2368 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2369 "Failed to start device");
2371 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2372 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2373 sizeof(read_mac_addr)),
2374 "bonded port (%d) mac address not set to that of primary port",
2375 test_params->bonded_port_id);
2377 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2378 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2379 sizeof(read_mac_addr)),
2380 "slave port (%d) mac address not as expected",
2381 test_params->slave_port_ids[0]);
2383 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2384 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2385 sizeof(read_mac_addr)),
2386 "slave port (%d) mac address not set to that of primary port",
2387 test_params->slave_port_ids[1]);
2389 /* Set explicit MAC address */
2390 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2391 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2392 "failed to set MAC address");
2394 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2395 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2396 sizeof(read_mac_addr)),
2397 "bonded port (%d) mac address not set to that of bonded port",
2398 test_params->bonded_port_id);
2400 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2401 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2402 sizeof(read_mac_addr)),
2403 "slave port (%d) mac address not as expected",
2404 test_params->slave_port_ids[0]);
2406 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2407 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2408 sizeof(read_mac_addr)),
2409 "slave port (%d) mac address not set to that of bonded port",
2410 test_params->slave_port_ids[1]);
2412 /* Clean up and remove slaves from bonded device */
2413 return remove_slaves_and_stop_bonded_device();
2417 test_activebackup_verify_slave_link_status_change_failover(void)
2419 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2420 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2421 struct rte_eth_stats port_stats;
2423 uint8_t slaves[RTE_MAX_ETHPORTS];
2425 int i, j, burst_size, slave_count, primary_port;
2429 memset(pkt_burst, 0, sizeof(pkt_burst));
2431 /* Generate packet burst for testing */
2432 TEST_ASSERT_EQUAL(generate_test_burst(
2433 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2434 "generate_test_burst failed");
2436 /* Initialize bonded device with 4 slaves in round robin mode */
2437 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2438 BONDING_MODE_ACTIVE_BACKUP, 0,
2439 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2440 "Failed to initialize bonded device with slaves");
2442 /* Verify Current Slaves Count /Active Slave Count is */
2443 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2445 TEST_ASSERT_EQUAL(slave_count, 4,
2446 "Number of slaves (%d) is not as expected (%d).",
2449 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2450 slaves, RTE_MAX_ETHPORTS);
2451 TEST_ASSERT_EQUAL(slave_count, 4,
2452 "Number of active slaves (%d) is not as expected (%d).",
2455 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2456 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2457 "Primary port not as expected");
2459 /* Bring 2 slaves down and verify active slave count */
2460 virtual_ethdev_simulate_link_status_interrupt(
2461 test_params->slave_port_ids[1], 0);
2462 virtual_ethdev_simulate_link_status_interrupt(
2463 test_params->slave_port_ids[3], 0);
2465 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2466 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2467 "Number of active slaves (%d) is not as expected (%d).",
2470 virtual_ethdev_simulate_link_status_interrupt(
2471 test_params->slave_port_ids[1], 1);
2472 virtual_ethdev_simulate_link_status_interrupt(
2473 test_params->slave_port_ids[3], 1);
2476 /* Bring primary port down, verify that active slave count is 3 and primary
2478 virtual_ethdev_simulate_link_status_interrupt(
2479 test_params->slave_port_ids[0], 0);
2481 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2482 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2484 "Number of active slaves (%d) is not as expected (%d).",
2487 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2488 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2489 "Primary port not as expected");
2491 /* Verify that pkts are sent on new primary slave */
2493 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2494 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2495 burst_size), burst_size, "rte_eth_tx_burst failed");
2497 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2498 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2499 "(%d) port_stats.opackets not as expected",
2500 test_params->slave_port_ids[2]);
2502 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2503 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2504 "(%d) port_stats.opackets not as expected\n",
2505 test_params->slave_port_ids[0]);
2507 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2508 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2509 "(%d) port_stats.opackets not as expected\n",
2510 test_params->slave_port_ids[1]);
2512 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2513 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2514 "(%d) port_stats.opackets not as expected\n",
2515 test_params->slave_port_ids[3]);
2517 /* Generate packet burst for testing */
2519 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2520 TEST_ASSERT_EQUAL(generate_test_burst(
2521 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2522 "generate_test_burst failed");
2524 virtual_ethdev_add_mbufs_to_rx_queue(
2525 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2528 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2529 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2530 burst_size, "rte_eth_rx_burst\n");
2532 /* Verify bonded device rx count */
2533 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2534 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2535 "(%d) port_stats.ipackets not as expected",
2536 test_params->bonded_port_id);
2538 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2539 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2540 "(%d) port_stats.opackets not as expected",
2541 test_params->slave_port_ids[2]);
2543 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2544 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2545 "(%d) port_stats.opackets not as expected",
2546 test_params->slave_port_ids[0]);
2548 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2549 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2550 "(%d) port_stats.opackets not as expected",
2551 test_params->slave_port_ids[1]);
2553 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2554 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2555 "(%d) port_stats.opackets not as expected",
2556 test_params->slave_port_ids[3]);
2559 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2560 for (j = 0; j < MAX_PKT_BURST; j++) {
2561 if (pkt_burst[i][j] != NULL) {
2562 rte_pktmbuf_free(pkt_burst[i][j]);
2563 pkt_burst[i][j] = NULL;
2568 /* Clean up and remove slaves from bonded device */
2569 return remove_slaves_and_stop_bonded_device();
2572 /** Balance Mode Tests */
2575 test_balance_xmit_policy_configuration(void)
2577 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2578 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2579 "Failed to initialize_bonded_device_with_slaves.");
2581 /* Invalid port id */
2582 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2583 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2584 "Expected call to failed as invalid port specified.");
2586 /* Set xmit policy on non bonded device */
2587 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2588 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2589 "Expected call to failed as invalid port specified.");
2592 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2593 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2594 "Failed to set balance xmit policy.");
2596 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2597 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2600 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2601 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2602 "Failed to set balance xmit policy.");
2604 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2605 BALANCE_XMIT_POLICY_LAYER23,
2606 "balance xmit policy not as expected.");
2609 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2610 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2611 "Failed to set balance xmit policy.");
2613 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2614 BALANCE_XMIT_POLICY_LAYER34,
2615 "balance xmit policy not as expected.");
2617 /* Invalid port id */
2618 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2619 "Expected call to failed as invalid port specified.");
2621 /* Clean up and remove slaves from bonded device */
2622 return remove_slaves_and_stop_bonded_device();
2625 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2628 test_balance_l2_tx_burst(void)
2630 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2631 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2635 struct rte_eth_stats port_stats;
2637 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2638 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2639 "Failed to initialize_bonded_device_with_slaves.");
2641 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2642 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2643 "Failed to set balance xmit policy.");
2645 initialize_eth_header(test_params->pkt_eth_hdr,
2646 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2647 ETHER_TYPE_IPv4, 0, 0);
2648 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2650 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2651 dst_addr_0, pktlen);
2653 /* Generate a burst 1 of packets to transmit */
2654 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2655 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2656 test_params->pkt_udp_hdr, burst_size[0],
2657 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2658 "failed to generate packet burst");
2660 initialize_eth_header(test_params->pkt_eth_hdr,
2661 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2662 ETHER_TYPE_IPv4, 0, 0);
2664 /* Generate a burst 2 of packets to transmit */
2665 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2666 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2667 test_params->pkt_udp_hdr, burst_size[1],
2668 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2669 "failed to generate packet burst");
2671 /* Send burst 1 on bonded port */
2672 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2673 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2674 &pkts_burst[i][0], burst_size[i]),
2675 burst_size[i], "Failed to transmit packet burst");
2678 /* Verify bonded port tx stats */
2679 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2680 TEST_ASSERT_EQUAL(port_stats.opackets,
2681 (uint64_t)(burst_size[0] + burst_size[1]),
2682 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2683 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2684 burst_size[0] + burst_size[1]);
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)burst_size[0],
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)burst_size[1],
2696 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
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[0][0], burst_size[0]),
2710 0, "Expected zero packet");
2712 /* Clean up and remove slaves from bonded device */
2713 return remove_slaves_and_stop_bonded_device();
2717 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2718 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2720 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2722 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2723 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2725 struct rte_eth_stats port_stats;
2727 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2728 BONDING_MODE_BALANCE, 0, 2, 1),
2729 "Failed to initialize_bonded_device_with_slaves.");
2731 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2732 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2733 "Failed to set balance xmit policy.");
2738 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2739 "Burst size specified is greater than supported.");
2741 /* Generate test bursts of packets to transmit */
2742 TEST_ASSERT_EQUAL(generate_test_burst(
2743 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2744 burst_size_1, "failed to generate packet burst");
2746 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2747 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2748 "failed to generate packet burst");
2750 /* Send burst 1 on bonded port */
2751 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2753 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2755 /* Send burst 2 on bonded port */
2756 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2758 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2760 /* Verify bonded port tx stats */
2761 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2762 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2763 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2764 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2767 /* Verify slave ports tx stats */
2768 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2769 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2770 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2771 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2774 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2775 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2776 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2777 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2780 /* Put all slaves down and try and transmit */
2781 for (i = 0; i < test_params->bonded_slave_count; i++) {
2783 virtual_ethdev_simulate_link_status_interrupt(
2784 test_params->slave_port_ids[i], 0);
2787 /* Send burst on bonded port */
2788 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2789 test_params->bonded_port_id, 0, pkts_burst_1,
2790 burst_size_1), 0, "Expected zero packet");
2793 /* Clean up and remove slaves from bonded device */
2794 return remove_slaves_and_stop_bonded_device();
2798 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2800 return balance_l23_tx_burst(0, 1, 1, 0);
2804 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2806 return balance_l23_tx_burst(1, 1, 0, 1);
2810 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2812 return balance_l23_tx_burst(0, 0, 0, 1);
2816 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2818 return balance_l23_tx_burst(1, 0, 0, 1);
2822 test_balance_l23_tx_burst_toggle_mac_addr(void)
2824 return balance_l23_tx_burst(0, 0, 1, 0);
2828 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2829 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2830 uint8_t toggle_udp_port)
2832 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2834 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2835 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2837 struct rte_eth_stats port_stats;
2839 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2840 BONDING_MODE_BALANCE, 0, 2, 1),
2841 "Failed to initialize_bonded_device_with_slaves.");
2843 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2844 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2845 "Failed to set balance xmit policy.");
2850 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2851 "Burst size specified is greater than supported.");
2853 /* Generate test bursts of packets to transmit */
2854 TEST_ASSERT_EQUAL(generate_test_burst(
2855 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2856 burst_size_1, "failed to generate burst");
2858 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2859 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2860 toggle_udp_port), burst_size_2, "failed to generate burst");
2862 /* Send burst 1 on bonded port */
2863 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2865 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2867 /* Send burst 2 on bonded port */
2868 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2870 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2873 /* Verify bonded port tx stats */
2874 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2875 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2876 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2877 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2880 /* Verify slave ports tx stats */
2881 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2882 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2883 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2884 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2887 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2888 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2889 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2890 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2893 /* Put all slaves down and try and transmit */
2894 for (i = 0; i < test_params->bonded_slave_count; i++) {
2896 virtual_ethdev_simulate_link_status_interrupt(
2897 test_params->slave_port_ids[i], 0);
2900 /* Send burst on bonded port */
2901 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2902 test_params->bonded_port_id, 0, pkts_burst_1,
2903 burst_size_1), 0, "Expected zero packet");
2905 /* Clean up and remove slaves from bonded device */
2906 return remove_slaves_and_stop_bonded_device();
2910 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2912 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2916 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2918 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2922 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2924 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2928 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2930 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2934 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2936 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2940 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2942 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2945 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2946 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2947 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2948 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2949 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2952 test_balance_tx_burst_slave_tx_fail(void)
2954 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2955 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2957 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2959 struct rte_eth_stats port_stats;
2961 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2963 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2964 BONDING_MODE_BALANCE, 0,
2965 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2966 "Failed to intialise bonded device");
2968 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2969 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2970 "Failed to set balance xmit policy.");
2973 /* Generate test bursts for transmission */
2974 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2975 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2976 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2977 "Failed to generate test packet burst 1");
2979 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2980 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2982 /* copy mbuf referneces for expected transmission failures */
2983 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2984 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2986 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2987 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2988 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2989 "Failed to generate test packet burst 2");
2992 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2993 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2994 virtual_ethdev_tx_burst_fn_set_success(
2995 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2998 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2999 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
3000 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3003 /* Transmit burst 1 */
3004 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3005 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3007 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3008 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3009 "Transmitted (%d) packets, expected to transmit (%d) packets",
3010 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3011 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3013 /* Verify that failed packet are expected failed packets */
3014 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3015 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3016 "expected mbuf (%d) pointer %p not expected pointer %p",
3017 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3020 /* Transmit burst 2 */
3021 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3022 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3024 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3025 "Transmitted (%d) packets, expected to transmit (%d) packets",
3026 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3029 /* Verify bonded port tx stats */
3030 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3032 TEST_ASSERT_EQUAL(port_stats.opackets,
3033 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3034 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3035 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3036 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3037 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3038 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3039 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3040 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3042 /* Verify slave ports tx stats */
3044 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3046 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3047 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3048 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3049 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3050 test_params->slave_port_ids[0],
3051 (unsigned int)port_stats.opackets,
3052 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3053 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3058 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3060 TEST_ASSERT_EQUAL(port_stats.opackets,
3061 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3062 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3063 test_params->slave_port_ids[1],
3064 (unsigned int)port_stats.opackets,
3065 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3067 #ifdef RTE_MBUF_REFCNT
3068 /* Verify that all mbufs have a ref value of zero */
3069 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3070 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3071 "mbufs refcnts not as expected");
3074 free_mbufs(&pkts_burst_1[tx_count_1],
3075 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3077 /* Clean up and remove slaves from bonded device */
3078 return remove_slaves_and_stop_bonded_device();
3081 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3084 test_balance_rx_burst(void)
3086 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3088 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3089 struct rte_eth_stats port_stats;
3091 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3094 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3096 /* Initialize bonded device with 4 slaves in round robin mode */
3097 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3098 BONDING_MODE_BALANCE, 0, 3, 1),
3099 "Failed to intialise bonded device");
3101 /* Generate test bursts of packets to transmit */
3102 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3103 TEST_ASSERT_EQUAL(generate_test_burst(
3104 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3105 0, 0), burst_size[i],
3106 "failed to generate packet burst");
3109 /* Add rx data to slaves */
3110 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3111 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3112 &gen_pkt_burst[i][0], burst_size[i]);
3115 /* Call rx burst on bonded device */
3116 /* Send burst on bonded port */
3117 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3118 rx_pkt_burst, MAX_PKT_BURST),
3119 burst_size[0] + burst_size[1] + burst_size[2],
3120 "balance rx burst failed\n");
3122 /* Verify bonded device rx count */
3123 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3124 TEST_ASSERT_EQUAL(port_stats.ipackets,
3125 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3126 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3127 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3128 burst_size[0] + burst_size[1] + burst_size[2]);
3131 /* Verify bonded slave devices rx counts */
3132 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3133 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3134 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3135 test_params->slave_port_ids[0],
3136 (unsigned int)port_stats.ipackets, burst_size[0]);
3138 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3139 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3140 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3141 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3144 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3145 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3146 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3147 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3150 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3151 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3152 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3153 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3157 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3158 for (j = 0; j < MAX_PKT_BURST; j++) {
3159 if (gen_pkt_burst[i][j] != NULL) {
3160 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3161 gen_pkt_burst[i][j] = NULL;
3166 /* Clean up and remove slaves from bonded device */
3167 return remove_slaves_and_stop_bonded_device();
3171 test_balance_verify_promiscuous_enable_disable(void)
3175 /* Initialize bonded device with 4 slaves in round robin mode */
3176 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3177 BONDING_MODE_BALANCE, 0, 4, 1),
3178 "Failed to intialise bonded device");
3180 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3182 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3183 "Port (%d) promiscuous mode not enabled",
3184 test_params->bonded_port_id);
3186 for (i = 0; i < test_params->bonded_slave_count; i++) {
3187 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3188 test_params->slave_port_ids[i]), 1,
3189 "Port (%d) promiscuous mode not enabled",
3190 test_params->slave_port_ids[i]);
3193 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3195 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3196 "Port (%d) promiscuous mode not disabled",
3197 test_params->bonded_port_id);
3199 for (i = 0; i < test_params->bonded_slave_count; i++) {
3200 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3201 test_params->slave_port_ids[i]), 0,
3202 "Port (%d) promiscuous mode not disabled",
3203 test_params->slave_port_ids[i]);
3206 /* Clean up and remove slaves from bonded device */
3207 return remove_slaves_and_stop_bonded_device();
3211 test_balance_verify_mac_assignment(void)
3213 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3215 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3216 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3218 /* Initialize bonded device with 2 slaves in active backup mode */
3219 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3220 BONDING_MODE_BALANCE, 0, 2, 1),
3221 "Failed to intialise bonded device");
3223 /* Verify that bonded MACs is that of first slave and that the other slave
3224 * MAC hasn't been changed */
3225 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3226 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3227 sizeof(read_mac_addr)),
3228 "bonded port (%d) mac address not set to that of primary port",
3229 test_params->bonded_port_id);
3231 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3232 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3233 sizeof(read_mac_addr)),
3234 "slave port (%d) mac address not set to that of primary port",
3235 test_params->slave_port_ids[0]);
3237 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3238 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3239 sizeof(read_mac_addr)),
3240 "slave port (%d) mac address not set to that of primary port",
3241 test_params->slave_port_ids[1]);
3243 /* change primary and verify that MAC addresses haven't changed */
3244 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3245 test_params->slave_port_ids[1]),
3246 "Failed to set bonded port (%d) primary port to (%d)\n",
3247 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3249 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3250 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3251 sizeof(read_mac_addr)),
3252 "bonded port (%d) mac address not set to that of primary port",
3253 test_params->bonded_port_id);
3255 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3256 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3257 sizeof(read_mac_addr)),
3258 "slave port (%d) mac address not set to that of primary port",
3259 test_params->slave_port_ids[0]);
3261 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3262 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3263 sizeof(read_mac_addr)),
3264 "slave port (%d) mac address not set to that of primary port",
3265 test_params->slave_port_ids[1]);
3267 /* stop / start bonded device and verify that primary MAC address is
3268 * propagated to bonded device and slaves */
3270 rte_eth_dev_stop(test_params->bonded_port_id);
3272 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3273 "Failed to start bonded device");
3275 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3276 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3277 sizeof(read_mac_addr)),
3278 "bonded port (%d) mac address not set to that of primary port",
3279 test_params->bonded_port_id);
3281 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3282 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3283 sizeof(read_mac_addr)),
3284 "slave port (%d) mac address not set to that of primary port",
3285 test_params->slave_port_ids[0]);
3287 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3288 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3289 sizeof(read_mac_addr)),
3290 "slave port (%d) mac address not set to that of primary port",
3291 test_params->slave_port_ids[1]);
3293 /* Set explicit MAC address */
3294 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3295 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3296 "failed to set MAC");
3298 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3299 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3300 sizeof(read_mac_addr)),
3301 "bonded port (%d) mac address not set to that of bonded port",
3302 test_params->bonded_port_id);
3304 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3305 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3306 sizeof(read_mac_addr)),
3307 "slave port (%d) mac address not as expected\n",
3308 test_params->slave_port_ids[0]);
3310 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3311 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3312 sizeof(read_mac_addr)),
3313 "slave port (%d) mac address not set to that of bonded port",
3314 test_params->slave_port_ids[1]);
3316 /* Clean up and remove slaves from bonded device */
3317 return remove_slaves_and_stop_bonded_device();
3320 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3323 test_balance_verify_slave_link_status_change_behaviour(void)
3325 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3326 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3327 struct rte_eth_stats port_stats;
3329 uint8_t slaves[RTE_MAX_ETHPORTS];
3331 int i, j, burst_size, slave_count;
3333 memset(pkt_burst, 0, sizeof(pkt_burst));
3335 /* Initialize bonded device with 4 slaves in round robin mode */
3336 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3337 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3338 "Failed to intialise bonded device");
3340 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3341 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3342 "Failed to set balance xmit policy.");
3345 /* Verify Current Slaves Count /Active Slave Count is */
3346 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3348 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3349 "Number of slaves (%d) is not as expected (%d).",
3350 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3352 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3353 slaves, RTE_MAX_ETHPORTS);
3354 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3355 "Number of active slaves (%d) is not as expected (%d).",
3356 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3358 /* Set 2 slaves link status to down */
3359 virtual_ethdev_simulate_link_status_interrupt(
3360 test_params->slave_port_ids[1], 0);
3361 virtual_ethdev_simulate_link_status_interrupt(
3362 test_params->slave_port_ids[3], 0);
3364 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3365 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3366 "Number of active slaves (%d) is not as expected (%d).",
3369 /* Send to sets of packet burst and verify that they are balanced across
3373 TEST_ASSERT_EQUAL(generate_test_burst(
3374 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3375 "generate_test_burst failed");
3377 TEST_ASSERT_EQUAL(generate_test_burst(
3378 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3379 "generate_test_burst failed");
3381 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3382 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3383 burst_size, "rte_eth_tx_burst failed");
3385 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3386 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3387 burst_size, "rte_eth_tx_burst failed");
3390 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3391 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3392 "(%d) port_stats.opackets (%d) not as expected (%d).",
3393 test_params->bonded_port_id, (int)port_stats.opackets,
3394 burst_size + burst_size);
3396 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3397 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3398 "(%d) port_stats.opackets (%d) not as expected (%d).",
3399 test_params->slave_port_ids[0], (int)port_stats.opackets,
3402 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3403 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3404 "(%d) port_stats.opackets (%d) not as expected (%d).",
3405 test_params->slave_port_ids[2], (int)port_stats.opackets,
3408 /* verify that all packets get send on primary slave when no other slaves
3410 virtual_ethdev_simulate_link_status_interrupt(
3411 test_params->slave_port_ids[2], 0);
3413 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3414 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3415 "Number of active slaves (%d) is not as expected (%d).",
3418 TEST_ASSERT_EQUAL(generate_test_burst(
3419 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3420 "generate_test_burst failed");
3422 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3423 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3424 burst_size, "rte_eth_tx_burst failed");
3426 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3427 TEST_ASSERT_EQUAL(port_stats.opackets,
3428 (uint64_t)(burst_size + burst_size + burst_size),
3429 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3430 test_params->bonded_port_id, (int)port_stats.opackets,
3431 burst_size + burst_size + burst_size);
3433 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3434 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3435 "(%d) port_stats.opackets (%d) not as expected (%d).",
3436 test_params->slave_port_ids[0], (int)port_stats.opackets,
3437 burst_size + burst_size);
3439 virtual_ethdev_simulate_link_status_interrupt(
3440 test_params->slave_port_ids[0], 0);
3441 virtual_ethdev_simulate_link_status_interrupt(
3442 test_params->slave_port_ids[1], 1);
3443 virtual_ethdev_simulate_link_status_interrupt(
3444 test_params->slave_port_ids[2], 1);
3445 virtual_ethdev_simulate_link_status_interrupt(
3446 test_params->slave_port_ids[3], 1);
3448 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3449 TEST_ASSERT_EQUAL(generate_test_burst(
3450 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3451 "Failed to generate packet burst");
3453 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3454 &pkt_burst[i][0], burst_size);
3457 /* Verify that pkts are not received on slaves with link status down */
3459 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3462 /* Verify bonded device rx count */
3463 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3464 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3465 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3466 test_params->bonded_port_id, (int)port_stats.ipackets,
3469 /* free mbufs allocate for rx testing */
3470 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3471 for (j = 0; j < MAX_PKT_BURST; j++) {
3472 if (pkt_burst[i][j] != NULL) {
3473 rte_pktmbuf_free(pkt_burst[i][j]);
3474 pkt_burst[i][j] = NULL;
3479 /* Clean up and remove slaves from bonded device */
3480 return remove_slaves_and_stop_bonded_device();
3483 #ifdef RTE_MBUF_REFCNT
3484 /** Broadcast Mode Tests */
3487 test_broadcast_tx_burst(void)
3489 int i, pktlen, burst_size;
3490 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3492 struct rte_eth_stats port_stats;
3494 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3495 BONDING_MODE_BROADCAST, 0, 2, 1),
3496 "Failed to intialise bonded device");
3498 initialize_eth_header(test_params->pkt_eth_hdr,
3499 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3500 ETHER_TYPE_IPv4, 0, 0);
3502 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3504 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3505 dst_addr_0, pktlen);
3507 burst_size = 20 * test_params->bonded_slave_count;
3509 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3510 "Burst size specified is greater than supported.");
3512 /* Generate a burst of packets to transmit */
3513 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3514 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3515 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3516 1), burst_size, "Failed to generate packet burst");
3518 /* Send burst on bonded port */
3519 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3520 pkts_burst, burst_size), burst_size,
3521 "Bonded Port (%d) rx burst failed, packets transmitted value "
3522 "not as expected (%d)",
3523 test_params->bonded_port_id, burst_size);
3525 /* Verify bonded port tx stats */
3526 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3527 TEST_ASSERT_EQUAL(port_stats.opackets,
3528 (uint64_t)burst_size * test_params->bonded_slave_count,
3529 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3530 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3533 /* Verify slave ports tx stats */
3534 for (i = 0; i < test_params->bonded_slave_count; i++) {
3535 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3536 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3537 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3538 test_params->bonded_port_id,
3539 (unsigned int)port_stats.opackets, burst_size);
3542 /* Put all slaves down and try and transmit */
3543 for (i = 0; i < test_params->bonded_slave_count; i++) {
3545 virtual_ethdev_simulate_link_status_interrupt(
3546 test_params->slave_port_ids[i], 0);
3549 /* Send burst on bonded port */
3550 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3551 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3552 "transmitted an unexpected number of packets");
3554 /* Clean up and remove slaves from bonded device */
3555 return remove_slaves_and_stop_bonded_device();
3559 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3560 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3561 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3562 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3565 test_broadcast_tx_burst_slave_tx_fail(void)
3567 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3568 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3570 struct rte_eth_stats port_stats;
3574 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3575 BONDING_MODE_BROADCAST, 0,
3576 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3577 "Failed to intialise bonded device");
3579 /* Generate test bursts for transmission */
3580 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3581 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3582 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3583 "Failed to generate test packet burst");
3585 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3586 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3587 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3590 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3591 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3592 virtual_ethdev_tx_burst_fn_set_success(
3593 test_params->slave_port_ids[0],
3595 virtual_ethdev_tx_burst_fn_set_success(
3596 test_params->slave_port_ids[1],
3598 virtual_ethdev_tx_burst_fn_set_success(
3599 test_params->slave_port_ids[2],
3602 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3603 test_params->slave_port_ids[0],
3604 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3606 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3607 test_params->slave_port_ids[1],
3608 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3610 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3611 test_params->slave_port_ids[2],
3612 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3614 /* Transmit burst */
3615 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3616 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3618 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3619 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3620 "Transmitted (%d) packets, expected to transmit (%d) packets",
3621 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3622 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3624 /* Verify that failed packet are expected failed packets */
3625 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3626 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3627 "expected mbuf (%d) pointer %p not expected pointer %p",
3628 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3631 /* Verify slave ports tx stats */
3633 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3635 TEST_ASSERT_EQUAL(port_stats.opackets,
3636 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3637 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3638 "Port (%d) opackets value (%u) not as expected (%d)",
3639 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3640 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3641 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3644 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3646 TEST_ASSERT_EQUAL(port_stats.opackets,
3647 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3648 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3649 "Port (%d) opackets value (%u) not as expected (%d)",
3650 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3651 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3652 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3654 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3656 TEST_ASSERT_EQUAL(port_stats.opackets,
3657 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3658 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3659 "Port (%d) opackets value (%u) not as expected (%d)",
3660 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3661 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3662 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3665 /* Verify that all mbufs who transmission failed have a ref value of one */
3666 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3667 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3668 "mbufs refcnts not as expected");
3670 free_mbufs(&pkts_burst[tx_count],
3671 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3673 /* Clean up and remove slaves from bonded device */
3674 return remove_slaves_and_stop_bonded_device();
3677 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3680 test_broadcast_rx_burst(void)
3682 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3684 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3685 struct rte_eth_stats port_stats;
3687 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3690 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3692 /* Initialize bonded device with 4 slaves in round robin mode */
3693 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3694 BONDING_MODE_BROADCAST, 0, 3, 1),
3695 "Failed to intialise bonded device");
3697 /* Generate test bursts of packets to transmit */
3698 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3699 TEST_ASSERT_EQUAL(generate_test_burst(
3700 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3701 burst_size[i], "failed to generate packet burst");
3704 /* Add rx data to slave 0 */
3705 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3706 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3707 &gen_pkt_burst[i][0], burst_size[i]);
3711 /* Call rx burst on bonded device */
3712 /* Send burst on bonded port */
3713 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3714 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3715 burst_size[0] + burst_size[1] + burst_size[2],
3718 /* Verify bonded device rx count */
3719 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3720 TEST_ASSERT_EQUAL(port_stats.ipackets,
3721 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3722 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3723 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3724 burst_size[0] + burst_size[1] + burst_size[2]);
3727 /* Verify bonded slave devices rx counts */
3728 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3729 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3730 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3731 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3734 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3735 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3736 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3737 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3740 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3741 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3742 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3743 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3746 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3747 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3748 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3749 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3752 /* free mbufs allocate for rx testing */
3753 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3754 for (j = 0; j < MAX_PKT_BURST; j++) {
3755 if (gen_pkt_burst[i][j] != NULL) {
3756 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3757 gen_pkt_burst[i][j] = NULL;
3762 /* Clean up and remove slaves from bonded device */
3763 return remove_slaves_and_stop_bonded_device();
3767 test_broadcast_verify_promiscuous_enable_disable(void)
3771 /* Initialize bonded device with 4 slaves in round robin mode */
3772 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3773 BONDING_MODE_BROADCAST, 0, 4, 1),
3774 "Failed to intialise bonded device");
3776 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3779 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3780 "Port (%d) promiscuous mode not enabled",
3781 test_params->bonded_port_id);
3783 for (i = 0; i < test_params->bonded_slave_count; i++) {
3784 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3785 test_params->slave_port_ids[i]), 1,
3786 "Port (%d) promiscuous mode not enabled",
3787 test_params->slave_port_ids[i]);
3790 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3792 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3793 "Port (%d) promiscuous mode not disabled",
3794 test_params->bonded_port_id);
3796 for (i = 0; i < test_params->bonded_slave_count; i++) {
3797 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3798 test_params->slave_port_ids[i]), 0,
3799 "Port (%d) promiscuous mode not disabled",
3800 test_params->slave_port_ids[i]);
3803 /* Clean up and remove slaves from bonded device */
3804 return remove_slaves_and_stop_bonded_device();
3808 test_broadcast_verify_mac_assignment(void)
3810 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3814 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3815 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3817 /* Initialize bonded device with 4 slaves in round robin mode */
3818 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3819 BONDING_MODE_BROADCAST, 0, 4, 1),
3820 "Failed to intialise bonded device");
3822 /* Verify that all MACs are the same as first slave added to bonded
3824 for (i = 0; i < test_params->bonded_slave_count; i++) {
3825 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3826 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3827 sizeof(read_mac_addr)),
3828 "slave port (%d) mac address not set to that of primary port",
3829 test_params->slave_port_ids[i]);
3832 /* change primary and verify that MAC addresses haven't changed */
3833 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3834 test_params->slave_port_ids[2]),
3835 "Failed to set bonded port (%d) primary port to (%d)",
3836 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3838 for (i = 0; i < test_params->bonded_slave_count; i++) {
3839 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3840 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3841 sizeof(read_mac_addr)),
3842 "slave port (%d) mac address has changed to that of primary "
3843 "port without stop/start toggle of bonded device",
3844 test_params->slave_port_ids[i]);
3847 /* stop / start bonded device and verify that primary MAC address is
3848 * propagated to bonded device and slaves */
3850 rte_eth_dev_stop(test_params->bonded_port_id);
3852 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3853 "Failed to start bonded device");
3855 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3856 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3857 sizeof(read_mac_addr)),
3858 "bonded port (%d) mac address not set to that of new primary port",
3859 test_params->slave_port_ids[i]);
3861 for (i = 0; i < test_params->bonded_slave_count; i++) {
3862 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3863 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3864 sizeof(read_mac_addr)),
3865 "slave port (%d) mac address not set to that of new primary "
3866 "port", test_params->slave_port_ids[i]);
3869 /* Set explicit MAC address */
3870 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3871 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3872 "Failed to set MAC address");
3874 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3875 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3876 sizeof(read_mac_addr)),
3877 "bonded port (%d) mac address not set to that of new primary port",
3878 test_params->slave_port_ids[i]);
3881 for (i = 0; i < test_params->bonded_slave_count; i++) {
3882 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3883 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3884 sizeof(read_mac_addr)),
3885 "slave port (%d) mac address not set to that of new primary "
3886 "port", test_params->slave_port_ids[i]);
3889 /* Clean up and remove slaves from bonded device */
3890 return remove_slaves_and_stop_bonded_device();
3893 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3895 test_broadcast_verify_slave_link_status_change_behaviour(void)
3897 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3898 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3899 struct rte_eth_stats port_stats;
3901 uint8_t slaves[RTE_MAX_ETHPORTS];
3903 int i, j, burst_size, slave_count;
3905 memset(pkt_burst, 0, sizeof(pkt_burst));
3907 /* Initialize bonded device with 4 slaves in round robin mode */
3908 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3909 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3910 1), "Failed to intialise bonded device");
3912 /* Verify Current Slaves Count /Active Slave Count is */
3913 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3915 TEST_ASSERT_EQUAL(slave_count, 4,
3916 "Number of slaves (%d) is not as expected (%d).",
3919 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3920 slaves, RTE_MAX_ETHPORTS);
3921 TEST_ASSERT_EQUAL(slave_count, 4,
3922 "Number of active slaves (%d) is not as expected (%d).",
3925 /* Set 2 slaves link status to down */
3926 virtual_ethdev_simulate_link_status_interrupt(
3927 test_params->slave_port_ids[1], 0);
3928 virtual_ethdev_simulate_link_status_interrupt(
3929 test_params->slave_port_ids[3], 0);
3931 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3932 slaves, RTE_MAX_ETHPORTS);
3933 TEST_ASSERT_EQUAL(slave_count, 2,
3934 "Number of active slaves (%d) is not as expected (%d).",
3937 for (i = 0; i < test_params->bonded_slave_count; i++)
3938 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3940 /* Verify that pkts are not sent on slaves with link status down */
3943 TEST_ASSERT_EQUAL(generate_test_burst(
3944 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3945 "generate_test_burst failed");
3947 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3948 &pkt_burst[0][0], burst_size), burst_size,
3949 "rte_eth_tx_burst failed\n");
3951 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3952 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3953 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3954 test_params->bonded_port_id, (int)port_stats.opackets,
3955 burst_size * slave_count);
3957 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3958 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3959 "(%d) port_stats.opackets not as expected",
3960 test_params->slave_port_ids[0]);
3962 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3963 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3964 "(%d) port_stats.opackets not as expected",
3965 test_params->slave_port_ids[1]);
3967 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3968 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3969 "(%d) port_stats.opackets not as expected",
3970 test_params->slave_port_ids[2]);
3973 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3974 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3975 "(%d) port_stats.opackets not as expected",
3976 test_params->slave_port_ids[3]);
3979 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3980 TEST_ASSERT_EQUAL(generate_test_burst(
3981 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3982 burst_size, "failed to generate packet burst");
3984 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3985 &pkt_burst[i][0], burst_size);
3988 /* Verify that pkts are not received on slaves with link status down */
3989 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3990 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3991 burst_size + burst_size, "rte_eth_rx_burst failed");
3994 /* Verify bonded device rx count */
3995 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3996 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3997 "(%d) port_stats.ipackets not as expected\n",
3998 test_params->bonded_port_id);
4000 /* free mbufs allocate for rx testing */
4001 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4002 for (j = 0; j < MAX_PKT_BURST; j++) {
4003 if (pkt_burst[i][j] != NULL) {
4004 rte_pktmbuf_free(pkt_burst[i][j]);
4005 pkt_burst[i][j] = NULL;
4010 /* Clean up and remove slaves from bonded device */
4011 return remove_slaves_and_stop_bonded_device();
4016 test_reconfigure_bonded_device(void)
4018 test_params->nb_rx_q = 4;
4019 test_params->nb_tx_q = 4;
4021 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4022 "failed to reconfigure bonded device");
4024 test_params->nb_rx_q = 2;
4025 test_params->nb_tx_q = 2;
4027 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4028 "failed to reconfigure bonded device with less rx/tx queues");
4035 test_close_bonded_device(void)
4037 rte_eth_dev_close(test_params->bonded_port_id);
4042 testsuite_teardown(void)
4044 if (test_params->pkt_eth_hdr != NULL) {
4045 free(test_params->pkt_eth_hdr);
4046 test_params->pkt_eth_hdr = NULL;
4049 /* Clean up and remove slaves from bonded device */
4050 return remove_slaves_and_stop_bonded_device();
4054 free_virtualpmd_tx_queue(void)
4056 int i, slave_port, to_free_cnt;
4057 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4059 /* Free tx queue of virtual pmd */
4060 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4062 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4063 test_params->slave_port_ids[slave_port],
4064 pkts_to_free, MAX_PKT_BURST);
4065 for (i = 0; i < to_free_cnt; i++)
4066 rte_pktmbuf_free(pkts_to_free[i]);
4071 test_tlb_tx_burst(void)
4073 int i, burst_size, nb_tx;
4074 uint64_t nb_tx2 = 0;
4075 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4076 struct rte_eth_stats port_stats[32];
4077 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4079 uint64_t floor_obytes = 0, ceiling_obytes = 0;
4081 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4082 (BONDING_MODE_TLB, 1, 3, 1),
4083 "Failed to initialise bonded device");
4085 burst_size = 20 * test_params->bonded_slave_count;
4087 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4088 "Burst size specified is greater than supported.\n");
4091 /* Generate 400000 test bursts in 2s of packets to transmit */
4092 for (i = 0; i < 400000; i++) {
4093 /*test two types of mac src own(bonding) and others */
4095 initialize_eth_header(test_params->pkt_eth_hdr,
4096 (struct ether_addr *)src_mac,
4097 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4099 initialize_eth_header(test_params->pkt_eth_hdr,
4100 (struct ether_addr *)test_params->default_slave_mac,
4101 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4103 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4105 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4106 dst_addr_0, pktlen);
4107 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4108 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4109 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4110 /* Send burst on bonded port */
4111 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4115 free_virtualpmd_tx_queue();
4117 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4118 "number of packet not equal burst size");
4124 /* Verify bonded port tx stats */
4125 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4127 all_bond_opackets = port_stats[0].opackets;
4128 all_bond_obytes = port_stats[0].obytes;
4130 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4131 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4132 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4136 /* Verify slave ports tx stats */
4137 for (i = 0; i < test_params->bonded_slave_count; i++) {
4138 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4139 sum_ports_opackets += port_stats[i].opackets;
4142 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4143 "Total packets sent by slaves is not equal to packets sent by bond interface");
4144 /* distribution of packets on each slave within +/- 10% of the expected value. */
4145 for (i = 0; i < test_params->bonded_slave_count; i++) {
4147 floor_obytes = (all_bond_obytes*90)/(test_params->bonded_slave_count*100);
4148 ceiling_obytes = (all_bond_obytes*110)/(test_params->bonded_slave_count*100);
4149 TEST_ASSERT(port_stats[i].obytes >= floor_obytes &&
4150 port_stats[i].obytes <= ceiling_obytes,
4151 "Distribution is not even");
4153 /* Put all slaves down and try and transmit */
4154 for (i = 0; i < test_params->bonded_slave_count; i++) {
4155 virtual_ethdev_simulate_link_status_interrupt(
4156 test_params->slave_port_ids[i], 0);
4159 /* Send burst on bonded port */
4160 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4162 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4164 /* Clean ugit checkout masterp and remove slaves from bonded device */
4165 return remove_slaves_and_stop_bonded_device();
4168 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4171 test_tlb_rx_burst(void)
4173 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4174 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4176 struct rte_eth_stats port_stats;
4180 uint16_t i, j, nb_rx, burst_size = 17;
4182 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4183 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4185 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4186 "Failed to initialize bonded device");
4189 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4190 TEST_ASSERT(primary_port >= 0,
4191 "failed to get primary slave for bonded port (%d)",
4192 test_params->bonded_port_id);
4194 for (i = 0; i < test_params->bonded_slave_count; i++) {
4195 /* Generate test bursts of packets to transmit */
4196 TEST_ASSERT_EQUAL(generate_test_burst(
4197 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4198 "burst generation failed");
4200 /* Add rx data to slave */
4201 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4202 &gen_pkt_burst[0], burst_size);
4204 /* Call rx burst on bonded device */
4205 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4206 &rx_pkt_burst[0], MAX_PKT_BURST);
4208 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4210 if (test_params->slave_port_ids[i] == primary_port) {
4211 /* Verify bonded device rx count */
4212 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4213 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4214 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4215 test_params->bonded_port_id,
4216 (unsigned int)port_stats.ipackets, burst_size);
4218 /* Verify bonded slave devices rx count */
4219 for (j = 0; j < test_params->bonded_slave_count; j++) {
4220 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4222 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4223 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4224 test_params->slave_port_ids[i],
4225 (unsigned int)port_stats.ipackets, burst_size);
4227 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4228 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4229 test_params->slave_port_ids[i],
4230 (unsigned int)port_stats.ipackets, 0);
4234 for (j = 0; j < test_params->bonded_slave_count; j++) {
4235 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4236 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4237 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4238 test_params->slave_port_ids[i],
4239 (unsigned int)port_stats.ipackets, 0);
4244 for (i = 0; i < burst_size; i++)
4245 rte_pktmbuf_free(rx_pkt_burst[i]);
4247 /* reset bonded device stats */
4248 rte_eth_stats_reset(test_params->bonded_port_id);
4251 /* Clean up and remove slaves from bonded device */
4252 return remove_slaves_and_stop_bonded_device();
4256 test_tlb_verify_promiscuous_enable_disable(void)
4258 int i, primary_port, promiscuous_en;
4260 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4261 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4262 BONDING_MODE_TLB, 0, 4, 1),
4263 "Failed to initialize bonded device");
4265 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4266 TEST_ASSERT(primary_port >= 0,
4267 "failed to get primary slave for bonded port (%d)",
4268 test_params->bonded_port_id);
4270 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4272 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4273 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4274 "Port (%d) promiscuous mode not enabled\n",
4275 test_params->bonded_port_id);
4276 for (i = 0; i < test_params->bonded_slave_count; i++) {
4277 promiscuous_en = rte_eth_promiscuous_get(
4278 test_params->slave_port_ids[i]);
4279 if (primary_port == test_params->slave_port_ids[i]) {
4280 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4281 "Port (%d) promiscuous mode not enabled\n",
4282 test_params->bonded_port_id);
4284 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4285 "Port (%d) promiscuous mode enabled\n",
4286 test_params->bonded_port_id);
4291 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4293 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4294 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4295 "Port (%d) promiscuous mode not disabled\n",
4296 test_params->bonded_port_id);
4298 for (i = 0; i < test_params->bonded_slave_count; i++) {
4299 promiscuous_en = rte_eth_promiscuous_get(
4300 test_params->slave_port_ids[i]);
4301 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4302 "slave port (%d) promiscuous mode not disabled\n",
4303 test_params->slave_port_ids[i]);
4306 /* Clean up and remove slaves from bonded device */
4307 return remove_slaves_and_stop_bonded_device();
4311 test_tlb_verify_mac_assignment(void)
4313 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4315 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4316 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4318 /* Initialize bonded device with 2 slaves in active backup mode */
4319 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4320 BONDING_MODE_TLB, 0, 2, 1),
4321 "Failed to initialize bonded device");
4323 /* Verify that bonded MACs is that of first slave and that the other slave
4324 * MAC hasn't been changed */
4325 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4326 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4327 sizeof(read_mac_addr)),
4328 "bonded port (%d) mac address not set to that of primary port",
4329 test_params->bonded_port_id);
4331 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4332 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4333 sizeof(read_mac_addr)),
4334 "slave port (%d) mac address not set to that of primary port",
4335 test_params->slave_port_ids[0]);
4337 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4338 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4339 sizeof(read_mac_addr)),
4340 "slave port (%d) mac address not as expected",
4341 test_params->slave_port_ids[1]);
4343 /* change primary and verify that MAC addresses haven't changed */
4344 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4345 test_params->slave_port_ids[1]), 0,
4346 "Failed to set bonded port (%d) primary port to (%d)",
4347 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4349 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4350 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4351 sizeof(read_mac_addr)),
4352 "bonded port (%d) mac address not set to that of primary port",
4353 test_params->bonded_port_id);
4355 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4356 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4357 sizeof(read_mac_addr)),
4358 "slave port (%d) mac address not set to that of primary port",
4359 test_params->slave_port_ids[0]);
4361 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4362 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4363 sizeof(read_mac_addr)),
4364 "slave port (%d) mac address not as expected",
4365 test_params->slave_port_ids[1]);
4367 /* stop / start bonded device and verify that primary MAC address is
4368 * propagated to bonded device and slaves */
4370 rte_eth_dev_stop(test_params->bonded_port_id);
4372 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4373 "Failed to start device");
4375 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4376 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4377 sizeof(read_mac_addr)),
4378 "bonded port (%d) mac address not set to that of primary port",
4379 test_params->bonded_port_id);
4381 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4382 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4383 sizeof(read_mac_addr)),
4384 "slave port (%d) mac address not as expected",
4385 test_params->slave_port_ids[0]);
4387 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4388 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4389 sizeof(read_mac_addr)),
4390 "slave port (%d) mac address not set to that of primary port",
4391 test_params->slave_port_ids[1]);
4394 /* Set explicit MAC address */
4395 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4396 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4397 "failed to set MAC addres");
4399 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4400 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4401 sizeof(read_mac_addr)),
4402 "bonded port (%d) mac address not set to that of bonded port",
4403 test_params->bonded_port_id);
4405 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4406 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4407 sizeof(read_mac_addr)),
4408 "slave port (%d) mac address not as expected",
4409 test_params->slave_port_ids[0]);
4411 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4412 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4413 sizeof(read_mac_addr)),
4414 "slave port (%d) mac address not set to that of bonded port",
4415 test_params->slave_port_ids[1]);
4417 /* Clean up and remove slaves from bonded device */
4418 return remove_slaves_and_stop_bonded_device();
4422 test_tlb_verify_slave_link_status_change_failover(void)
4424 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4425 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4426 struct rte_eth_stats port_stats;
4428 uint8_t slaves[RTE_MAX_ETHPORTS];
4430 int i, j, burst_size, slave_count, primary_port;
4434 memset(pkt_burst, 0, sizeof(pkt_burst));
4438 /* Initialize bonded device with 4 slaves in round robin mode */
4439 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4440 BONDING_MODE_TLB, 0,
4441 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4442 "Failed to initialize bonded device with slaves");
4444 /* Verify Current Slaves Count /Active Slave Count is */
4445 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4447 TEST_ASSERT_EQUAL(slave_count, 4,
4448 "Number of slaves (%d) is not as expected (%d).\n",
4451 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4452 slaves, RTE_MAX_ETHPORTS);
4453 TEST_ASSERT_EQUAL(slave_count, (int)4,
4454 "Number of slaves (%d) is not as expected (%d).\n",
4457 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4458 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4459 "Primary port not as expected");
4461 /* Bring 2 slaves down and verify active slave count */
4462 virtual_ethdev_simulate_link_status_interrupt(
4463 test_params->slave_port_ids[1], 0);
4464 virtual_ethdev_simulate_link_status_interrupt(
4465 test_params->slave_port_ids[3], 0);
4467 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4468 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4469 "Number of active slaves (%d) is not as expected (%d).",
4472 virtual_ethdev_simulate_link_status_interrupt(
4473 test_params->slave_port_ids[1], 1);
4474 virtual_ethdev_simulate_link_status_interrupt(
4475 test_params->slave_port_ids[3], 1);
4478 /* Bring primary port down, verify that active slave count is 3 and primary
4480 virtual_ethdev_simulate_link_status_interrupt(
4481 test_params->slave_port_ids[0], 0);
4483 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4484 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4485 "Number of active slaves (%d) is not as expected (%d).",
4488 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4489 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4490 "Primary port not as expected");
4491 rte_delay_us(500000);
4492 /* Verify that pkts are sent on new primary slave */
4493 for (i = 0; i < 4; i++) {
4494 TEST_ASSERT_EQUAL(generate_test_burst(
4495 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4496 "generate_test_burst failed\n");
4497 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4498 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4499 "rte_eth_tx_burst failed\n");
4500 rte_delay_us(11000);
4503 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4504 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4505 "(%d) port_stats.opackets not as expected\n",
4506 test_params->slave_port_ids[0]);
4508 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4509 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4510 "(%d) port_stats.opackets not as expected\n",
4511 test_params->slave_port_ids[1]);
4513 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4514 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4515 "(%d) port_stats.opackets not as expected\n",
4516 test_params->slave_port_ids[2]);
4518 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4519 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4520 "(%d) port_stats.opackets not as expected\n",
4521 test_params->slave_port_ids[3]);
4524 /* Generate packet burst for testing */
4526 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4527 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4531 virtual_ethdev_add_mbufs_to_rx_queue(
4532 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4535 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4536 MAX_PKT_BURST) != burst_size) {
4537 printf("rte_eth_rx_burst\n");
4542 /* Verify bonded device rx count */
4543 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4544 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4545 "(%d) port_stats.ipackets not as expected\n",
4546 test_params->bonded_port_id);
4550 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4551 for (j = 0; j < MAX_PKT_BURST; j++) {
4552 if (pkt_burst[i][j] != NULL) {
4553 rte_pktmbuf_free(pkt_burst[i][j]);
4554 pkt_burst[i][j] = NULL;
4560 /* Clean up and remove slaves from bonded device */
4561 return remove_slaves_and_stop_bonded_device();
4564 #define TEST_ALB_SLAVE_COUNT 2
4566 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4567 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4568 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4569 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4571 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4572 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4573 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4574 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4575 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4578 test_alb_change_mac_in_reply_sent(void)
4580 struct rte_mbuf *pkt;
4581 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4583 struct ether_hdr *eth_pkt;
4584 struct arp_hdr *arp_pkt;
4586 int slave_idx, nb_pkts, pkt_idx;
4589 struct ether_addr bond_mac, client_mac;
4590 struct ether_addr *slave_mac1, *slave_mac2;
4592 TEST_ASSERT_SUCCESS(
4593 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4594 0, TEST_ALB_SLAVE_COUNT, 1),
4595 "Failed to initialize_bonded_device_with_slaves.");
4597 /* Flush tx queue */
4598 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4599 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4601 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4602 test_params->slave_port_ids[slave_idx], pkts_sent,
4607 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4611 * Generating four packets with different mac and ip addresses and sending
4612 * them through the bonding port.
4614 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4615 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4616 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4617 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4619 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4620 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4622 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4624 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4625 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4626 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4627 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4629 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4630 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4632 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4634 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4635 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4636 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4637 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4639 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4640 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4642 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4644 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4645 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4646 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4647 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4649 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4650 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4652 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4655 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4657 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4660 * Checking if packets are properly distributed on bonding ports. Packets
4661 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4663 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4664 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4665 test_params->slave_port_ids[slave_idx], pkts_sent,
4668 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4669 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4670 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4672 if (slave_idx%2 == 0) {
4673 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4678 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4687 retval += remove_slaves_and_stop_bonded_device();
4692 test_alb_reply_from_client(void)
4694 struct ether_hdr *eth_pkt;
4695 struct arp_hdr *arp_pkt;
4697 struct rte_mbuf *pkt;
4698 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4700 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4703 struct ether_addr bond_mac, client_mac;
4704 struct ether_addr *slave_mac1, *slave_mac2;
4706 TEST_ASSERT_SUCCESS(
4707 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4708 0, TEST_ALB_SLAVE_COUNT, 1),
4709 "Failed to initialize_bonded_device_with_slaves.");
4711 /* Flush tx queue */
4712 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4713 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4714 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4715 test_params->slave_port_ids[slave_idx], pkts_sent,
4720 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4724 * Generating four packets with different mac and ip addresses and placing
4725 * them in the rx queue to be received by the bonding driver on rx_burst.
4727 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4728 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4729 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4730 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4732 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4733 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4735 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4738 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4739 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4740 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4741 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4743 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4744 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4746 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4749 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4750 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4751 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4752 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4754 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4755 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4757 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4760 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4761 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4762 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4763 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4765 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4766 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4768 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4772 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4773 * packets to every client in alb table.
4775 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4776 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4778 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4779 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4782 * Checking if update ARP packets were properly send on slave ports.
4784 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4785 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4786 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4787 nb_pkts_sum += nb_pkts;
4789 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4790 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4791 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4793 if (slave_idx%2 == 0) {
4794 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4799 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4807 /* Check if proper number of packets was send */
4808 if (nb_pkts_sum < 4) {
4814 retval += remove_slaves_and_stop_bonded_device();
4819 test_alb_receive_vlan_reply(void)
4821 struct ether_hdr *eth_pkt;
4822 struct vlan_hdr *vlan_pkt;
4823 struct arp_hdr *arp_pkt;
4825 struct rte_mbuf *pkt;
4826 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4828 int slave_idx, nb_pkts, pkt_idx;
4831 struct ether_addr bond_mac, client_mac;
4833 TEST_ASSERT_SUCCESS(
4834 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4835 0, TEST_ALB_SLAVE_COUNT, 1),
4836 "Failed to initialize_bonded_device_with_slaves.");
4838 /* Flush tx queue */
4839 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4840 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4841 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4842 test_params->slave_port_ids[slave_idx], pkts_sent,
4847 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4851 * Generating packet with double VLAN header and placing it in the rx queue.
4853 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4854 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4855 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4856 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4858 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4859 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4860 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4861 vlan_pkt = vlan_pkt+1;
4862 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4863 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4864 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4865 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4867 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4870 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4871 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4874 * Checking if VLAN headers in generated ARP Update packet are correct.
4876 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4877 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4878 test_params->slave_port_ids[slave_idx], pkts_sent,
4881 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4882 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4883 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4884 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4888 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4892 vlan_pkt = vlan_pkt+1;
4893 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4897 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4905 retval += remove_slaves_and_stop_bonded_device();
4910 test_alb_ipv4_tx(void)
4912 int burst_size, retval, pkts_send;
4913 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4917 TEST_ASSERT_SUCCESS(
4918 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4919 0, TEST_ALB_SLAVE_COUNT, 1),
4920 "Failed to initialize_bonded_device_with_slaves.");
4924 /* Generate test bursts of packets to transmit */
4925 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4931 * Checking if ipv4 traffic is transmitted via TLB policy.
4933 pkts_send = rte_eth_tx_burst(
4934 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4935 if (pkts_send != burst_size) {
4941 retval += remove_slaves_and_stop_bonded_device();
4945 static struct unit_test_suite link_bonding_test_suite = {
4946 .suite_name = "Link Bonding Unit Test Suite",
4947 .setup = test_setup,
4948 .teardown = testsuite_teardown,
4949 .unit_test_cases = {
4950 TEST_CASE(test_create_bonded_device),
4951 TEST_CASE(test_create_bonded_device_with_invalid_params),
4952 TEST_CASE(test_add_slave_to_bonded_device),
4953 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4954 TEST_CASE(test_remove_slave_from_bonded_device),
4955 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4956 TEST_CASE(test_get_slaves_from_bonded_device),
4957 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4958 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4959 TEST_CASE(test_start_bonded_device),
4960 TEST_CASE(test_stop_bonded_device),
4961 TEST_CASE(test_set_bonding_mode),
4962 TEST_CASE(test_set_primary_slave),
4963 TEST_CASE(test_set_explicit_bonded_mac),
4964 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4965 TEST_CASE(test_status_interrupt),
4966 TEST_CASE(test_adding_slave_after_bonded_device_started),
4967 TEST_CASE(test_roundrobin_tx_burst),
4968 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4969 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4970 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4971 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4972 TEST_CASE(test_roundrobin_verify_mac_assignment),
4973 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4974 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4975 TEST_CASE(test_activebackup_tx_burst),
4976 TEST_CASE(test_activebackup_rx_burst),
4977 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4978 TEST_CASE(test_activebackup_verify_mac_assignment),
4979 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4980 TEST_CASE(test_balance_xmit_policy_configuration),
4981 TEST_CASE(test_balance_l2_tx_burst),
4982 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4983 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4984 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4985 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4986 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4987 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4988 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4989 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4990 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4991 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4992 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4993 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4994 TEST_CASE(test_balance_rx_burst),
4995 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4996 TEST_CASE(test_balance_verify_mac_assignment),
4997 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4998 TEST_CASE(test_tlb_tx_burst),
4999 TEST_CASE(test_tlb_rx_burst),
5000 TEST_CASE(test_tlb_verify_mac_assignment),
5001 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
5002 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
5003 TEST_CASE(test_alb_change_mac_in_reply_sent),
5004 TEST_CASE(test_alb_reply_from_client),
5005 TEST_CASE(test_alb_receive_vlan_reply),
5006 TEST_CASE(test_alb_ipv4_tx),
5007 #ifdef RTE_MBUF_REFCNT
5008 TEST_CASE(test_broadcast_tx_burst),
5009 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
5010 TEST_CASE(test_broadcast_rx_burst),
5011 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
5012 TEST_CASE(test_broadcast_verify_mac_assignment),
5013 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
5015 TEST_CASE(test_reconfigure_bonded_device),
5016 TEST_CASE(test_close_bonded_device),
5018 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
5024 test_link_bonding(void)
5026 return unit_test_suite_runner(&link_bonding_test_suite);
5029 static struct test_command link_bonding_cmd = {
5030 .command = "link_bonding_autotest",
5031 .callback = test_link_bonding,
5033 REGISTER_TEST_COMMAND(link_bonding_cmd);