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_CACHE_SIZE (250)
79 #define BURST_SIZE (32)
81 #define RTE_TEST_RX_DESC_MAX (2048)
82 #define RTE_TEST_TX_DESC_MAX (2048)
83 #define MAX_PKT_BURST (512)
84 #define DEF_PKT_BURST (16)
86 #define BONDED_DEV_NAME ("unit_test_bonded_device")
88 #define INVALID_SOCKET_ID (-1)
89 #define INVALID_PORT_ID (-1)
90 #define INVALID_BONDING_MODE (-1)
93 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
94 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
96 struct link_bonding_unittest_params {
97 int8_t bonded_port_id;
98 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
99 uint8_t bonded_slave_count;
100 uint8_t bonding_mode;
105 struct rte_mempool *mbuf_pool;
107 struct ether_addr *default_slave_mac;
108 struct ether_addr *default_bonded_mac;
111 struct ether_hdr *pkt_eth_hdr;
112 struct ipv4_hdr *pkt_ipv4_hdr;
113 struct ipv6_hdr *pkt_ipv6_hdr;
114 struct udp_hdr *pkt_udp_hdr;
118 static struct ipv4_hdr pkt_ipv4_hdr;
119 static struct ipv6_hdr pkt_ipv6_hdr;
120 static struct udp_hdr pkt_udp_hdr;
122 static struct link_bonding_unittest_params default_params = {
123 .bonded_port_id = -1,
124 .slave_port_ids = { -1 },
125 .bonded_slave_count = 0,
126 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
133 .default_slave_mac = (struct ether_addr *)slave_mac,
134 .default_bonded_mac = (struct ether_addr *)bonded_mac,
137 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
138 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
139 .pkt_udp_hdr = &pkt_udp_hdr
143 static struct link_bonding_unittest_params *test_params = &default_params;
145 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
146 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
147 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
149 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
150 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
151 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
153 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
154 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
155 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
156 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
157 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
158 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
160 static uint16_t src_port = 1024;
161 static uint16_t dst_port_0 = 1024;
162 static uint16_t dst_port_1 = 2024;
164 static uint16_t vlan_id = 0x100;
166 struct rte_eth_rxmode rx_mode = {
167 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
169 .header_split = 0, /**< Header Split disabled. */
170 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
171 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
172 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
173 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
174 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
175 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
178 struct rte_fdir_conf fdir_conf = {
179 .mode = RTE_FDIR_MODE_NONE,
180 .pballoc = RTE_FDIR_PBALLOC_64K,
181 .status = RTE_FDIR_REPORT_STATUS,
185 static struct rte_eth_conf default_pmd_conf = {
187 .mq_mode = ETH_MQ_RX_NONE,
188 .max_rx_pkt_len = ETHER_MAX_LEN,
190 .header_split = 0, /**< Header Split disabled */
191 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
192 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
193 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
194 .hw_strip_crc = 0, /**< CRC stripped by hardware */
197 .mq_mode = ETH_MQ_TX_NONE,
202 static const struct rte_eth_rxconf rx_conf_default = {
204 .pthresh = RX_PTHRESH,
205 .hthresh = RX_HTHRESH,
206 .wthresh = RX_WTHRESH,
208 .rx_free_thresh = RX_FREE_THRESH,
212 static struct rte_eth_txconf tx_conf_default = {
214 .pthresh = TX_PTHRESH,
215 .hthresh = TX_HTHRESH,
216 .wthresh = TX_WTHRESH,
218 .tx_free_thresh = TX_FREE_THRESH,
219 .tx_rs_thresh = TX_RSBIT_THRESH,
220 .txq_flags = TX_Q_FLAGS
225 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
230 default_pmd_conf.intr_conf.lsc = 1;
232 default_pmd_conf.intr_conf.lsc = 0;
234 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
235 test_params->nb_tx_q, &default_pmd_conf),
236 "rte_eth_dev_configure for port %d failed", port_id);
238 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
239 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
240 rte_eth_dev_socket_id(port_id), &rx_conf_default,
241 test_params->mbuf_pool) ,
242 "rte_eth_rx_queue_setup for port %d failed", port_id);
244 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
245 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
246 rte_eth_dev_socket_id(port_id), &tx_conf_default),
247 "rte_eth_tx_queue_setup for port %d failed", port_id);
250 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
251 "rte_eth_dev_start for port %d failed", port_id);
256 static int slaves_initialized;
258 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
259 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
265 int i, nb_mbuf_per_pool;
266 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
268 /* Allocate ethernet packet header with space for VLAN header */
269 if (test_params->pkt_eth_hdr == NULL) {
270 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
271 sizeof(struct vlan_hdr));
273 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
274 "Ethernet header struct allocation failed!");
277 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
278 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
279 if (test_params->mbuf_pool == NULL) {
280 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
281 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
282 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
283 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
284 "rte_mempool_create failed");
287 /* Create / Initialize virtual eth devs */
288 if (!slaves_initialized) {
289 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
290 char pmd_name[RTE_ETH_NAME_MAX_LEN];
292 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
294 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
296 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
297 mac_addr, rte_socket_id(), 1);
298 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
299 "Failed to create virtual virtual ethdev %s", pmd_name);
301 TEST_ASSERT_SUCCESS(configure_ethdev(
302 test_params->slave_port_ids[i], 1, 0),
303 "Failed to configure virtual ethdev %s", pmd_name);
305 slaves_initialized = 1;
312 test_create_bonded_device(void)
314 int current_slave_count;
316 uint8_t slaves[RTE_MAX_ETHPORTS];
318 /* Don't try to recreate bonded device if re-running test suite*/
319 if (test_params->bonded_port_id == -1) {
320 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
321 test_params->bonding_mode, rte_socket_id());
323 TEST_ASSERT(test_params->bonded_port_id >= 0,
324 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
326 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
327 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
330 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
331 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
332 test_params->bonded_port_id, test_params->bonding_mode);
334 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
335 slaves, RTE_MAX_ETHPORTS);
337 TEST_ASSERT_EQUAL(current_slave_count, 0,
338 "Number of slaves %d is great than expected %d.",
339 current_slave_count, 0);
341 current_slave_count = rte_eth_bond_active_slaves_get(
342 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
344 TEST_ASSERT_EQUAL(current_slave_count, 0,
345 "Number of active slaves %d is great than expected %d.",
346 current_slave_count, 0);
353 test_create_bonded_device_with_invalid_params(void)
357 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
360 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
362 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
364 test_params->bonding_mode = INVALID_BONDING_MODE;
366 /* Invalid bonding mode */
367 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
369 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
371 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
373 /* Invalid socket id */
374 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
376 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
382 test_add_slave_to_bonded_device(void)
384 int current_slave_count;
386 uint8_t slaves[RTE_MAX_ETHPORTS];
388 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
389 test_params->slave_port_ids[test_params->bonded_slave_count]),
390 "Failed to add slave (%d) to bonded port (%d).",
391 test_params->slave_port_ids[test_params->bonded_slave_count],
392 test_params->bonded_port_id);
394 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
395 slaves, RTE_MAX_ETHPORTS);
396 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
397 "Number of slaves (%d) is greater than expected (%d).",
398 current_slave_count, test_params->bonded_slave_count + 1);
400 current_slave_count = rte_eth_bond_active_slaves_get(
401 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
402 TEST_ASSERT_EQUAL(current_slave_count, 0,
403 "Number of active slaves (%d) is not as expected (%d).\n",
404 current_slave_count, 0);
406 test_params->bonded_slave_count++;
412 test_add_slave_to_invalid_bonded_device(void)
414 /* Invalid port ID */
415 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
416 test_params->slave_port_ids[test_params->bonded_slave_count]),
417 "Expected call to failed as invalid port specified.");
419 /* Non bonded device */
420 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
421 test_params->slave_port_ids[test_params->bonded_slave_count]),
422 "Expected call to failed as invalid port specified.");
429 test_remove_slave_from_bonded_device(void)
431 int current_slave_count;
432 struct ether_addr read_mac_addr, *mac_addr;
433 uint8_t slaves[RTE_MAX_ETHPORTS];
435 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
436 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
437 "Failed to remove slave %d from bonded port (%d).",
438 test_params->slave_port_ids[test_params->bonded_slave_count-1],
439 test_params->bonded_port_id);
442 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
443 slaves, RTE_MAX_ETHPORTS);
445 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
446 "Number of slaves (%d) is great than expected (%d).\n",
447 current_slave_count, test_params->bonded_slave_count - 1);
450 mac_addr = (struct ether_addr *)slave_mac;
451 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
452 test_params->bonded_slave_count-1;
455 test_params->slave_port_ids[test_params->bonded_slave_count-1],
457 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
458 "bonded port mac address not set to that of primary port\n");
461 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
463 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
466 test_params->bonded_slave_count--;
472 test_remove_slave_from_invalid_bonded_device(void)
474 /* Invalid port ID */
475 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
476 test_params->bonded_port_id + 5,
477 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
478 "Expected call to failed as invalid port specified.");
480 /* Non bonded device */
481 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
482 test_params->slave_port_ids[0],
483 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
484 "Expected call to failed as invalid port specified.");
489 static int bonded_id = 2;
492 test_add_already_bonded_slave_to_bonded_device(void)
494 int port_id, current_slave_count;
495 uint8_t slaves[RTE_MAX_ETHPORTS];
496 char pmd_name[RTE_ETH_NAME_MAX_LEN];
498 test_add_slave_to_bonded_device();
500 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
501 slaves, RTE_MAX_ETHPORTS);
502 TEST_ASSERT_EQUAL(current_slave_count, 1,
503 "Number of slaves (%d) is not that expected (%d).",
504 current_slave_count, 1);
506 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
508 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
510 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
512 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
513 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
515 "Added slave (%d) to bonded port (%d) unexpectedly.",
516 test_params->slave_port_ids[test_params->bonded_slave_count-1],
519 return test_remove_slave_from_bonded_device();
524 test_get_slaves_from_bonded_device(void)
526 int current_slave_count;
527 uint8_t slaves[RTE_MAX_ETHPORTS];
529 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
530 "Failed to add slave to bonded device");
532 /* Invalid port id */
533 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
535 TEST_ASSERT(current_slave_count < 0,
536 "Invalid port id unexpectedly succeeded");
538 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
539 slaves, RTE_MAX_ETHPORTS);
540 TEST_ASSERT(current_slave_count < 0,
541 "Invalid port id unexpectedly succeeded");
543 /* Invalid slaves pointer */
544 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
545 NULL, RTE_MAX_ETHPORTS);
546 TEST_ASSERT(current_slave_count < 0,
547 "Invalid slave array unexpectedly succeeded");
549 current_slave_count = rte_eth_bond_active_slaves_get(
550 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
551 TEST_ASSERT(current_slave_count < 0,
552 "Invalid slave array unexpectedly succeeded");
554 /* non bonded device*/
555 current_slave_count = rte_eth_bond_slaves_get(
556 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
557 TEST_ASSERT(current_slave_count < 0,
558 "Invalid port id unexpectedly succeeded");
560 current_slave_count = rte_eth_bond_active_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 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
566 "Failed to remove slaves from bonded device");
573 test_add_remove_multiple_slaves_to_from_bonded_device(void)
577 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
578 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
579 "Failed to add slave to bonded device");
581 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
582 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
583 "Failed to remove slaves from bonded device");
589 enable_bonded_slaves(void)
593 for (i = 0; i < test_params->bonded_slave_count; i++) {
594 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
597 virtual_ethdev_simulate_link_status_interrupt(
598 test_params->slave_port_ids[i], 1);
603 test_start_bonded_device(void)
605 struct rte_eth_link link_status;
607 int current_slave_count, current_bonding_mode, primary_port;
608 uint8_t slaves[RTE_MAX_ETHPORTS];
610 /* Add slave to bonded device*/
611 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
612 "Failed to add slave to bonded device");
614 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
615 "Failed to start bonded pmd eth device %d.",
616 test_params->bonded_port_id);
618 /* Change link status of virtual pmd so it will be added to the active
619 * slave list of the bonded device*/
620 virtual_ethdev_simulate_link_status_interrupt(
621 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
623 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
624 slaves, RTE_MAX_ETHPORTS);
625 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
626 "Number of slaves (%d) is not expected value (%d).",
627 current_slave_count, test_params->bonded_slave_count);
629 current_slave_count = rte_eth_bond_active_slaves_get(
630 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
631 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
632 "Number of active slaves (%d) is not expected value (%d).",
633 current_slave_count, test_params->bonded_slave_count);
635 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
636 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
637 "Bonded device mode (%d) is not expected value (%d).\n",
638 current_bonding_mode, test_params->bonding_mode);
640 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
641 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
642 "Primary port (%d) is not expected value (%d).",
643 primary_port, test_params->slave_port_ids[0]);
645 rte_eth_link_get(test_params->bonded_port_id, &link_status);
646 TEST_ASSERT_EQUAL(link_status.link_status, 1,
647 "Bonded port (%d) status (%d) is not expected value (%d).\n",
648 test_params->bonded_port_id, link_status.link_status, 1);
654 test_stop_bonded_device(void)
656 int current_slave_count;
657 uint8_t slaves[RTE_MAX_ETHPORTS];
659 struct rte_eth_link link_status;
661 rte_eth_dev_stop(test_params->bonded_port_id);
663 rte_eth_link_get(test_params->bonded_port_id, &link_status);
664 TEST_ASSERT_EQUAL(link_status.link_status, 0,
665 "Bonded port (%d) status (%d) is not expected value (%d).",
666 test_params->bonded_port_id, link_status.link_status, 0);
668 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
669 slaves, RTE_MAX_ETHPORTS);
670 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
671 "Number of slaves (%d) is not expected value (%d).",
672 current_slave_count, test_params->bonded_slave_count);
674 current_slave_count = rte_eth_bond_active_slaves_get(
675 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
676 TEST_ASSERT_EQUAL(current_slave_count, 0,
677 "Number of active slaves (%d) is not expected value (%d).",
678 current_slave_count, 0);
684 remove_slaves_and_stop_bonded_device(void)
686 /* Clean up and remove slaves from bonded device */
687 while (test_params->bonded_slave_count > 0)
688 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
689 "test_remove_slave_from_bonded_device failed");
691 rte_eth_dev_stop(test_params->bonded_port_id);
692 rte_eth_stats_reset(test_params->bonded_port_id);
693 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
699 test_set_bonding_mode(void)
703 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
704 BONDING_MODE_ACTIVE_BACKUP,
705 BONDING_MODE_BALANCE,
706 BONDING_MODE_BROADCAST
709 /* Test supported link bonding modes */
710 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
711 /* Invalid port ID */
712 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
714 "Expected call to failed as invalid port (%d) specified.",
717 /* Non bonded device */
718 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
720 "Expected call to failed as invalid port (%d) specified.",
721 test_params->slave_port_ids[0]);
723 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
725 "Failed to set link bonding mode on port (%d) to (%d).",
726 test_params->bonded_port_id, bonding_modes[i]);
728 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
729 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
730 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
731 bonding_mode, test_params->bonded_port_id,
734 /* Invalid port ID */
735 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
736 TEST_ASSERT(bonding_mode < 0,
737 "Expected call to failed as invalid port (%d) specified.",
740 /* Non bonded device */
741 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
742 TEST_ASSERT(bonding_mode < 0,
743 "Expected call to failed as invalid port (%d) specified.",
744 test_params->slave_port_ids[0]);
747 return remove_slaves_and_stop_bonded_device();
751 test_set_primary_slave(void)
754 struct ether_addr read_mac_addr;
755 struct ether_addr *expected_mac_addr;
757 /* Add 4 slaves to bonded device */
758 for (i = test_params->bonded_slave_count; i < 4; i++)
759 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
760 "Failed to add slave to bonded device.");
762 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
763 BONDING_MODE_ROUND_ROBIN),
764 "Failed to set link bonding mode on port (%d) to (%d).",
765 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
767 /* Invalid port ID */
768 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
769 test_params->slave_port_ids[i]),
770 "Expected call to failed as invalid port specified.");
772 /* Non bonded device */
773 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
774 test_params->slave_port_ids[i]),
775 "Expected call to failed as invalid port specified.");
777 /* Set slave as primary
778 * Verify slave it is now primary slave
779 * Verify that MAC address of bonded device is that of primary slave
780 * Verify that MAC address of all bonded slaves are that of primary slave
782 for (i = 0; i < 4; i++) {
783 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
784 test_params->slave_port_ids[i]),
785 "Failed to set bonded port (%d) primary port to (%d)",
786 test_params->bonded_port_id, test_params->slave_port_ids[i]);
788 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
789 TEST_ASSERT(retval >= 0,
790 "Failed to read primary port from bonded port (%d)\n",
791 test_params->bonded_port_id);
793 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
794 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
795 test_params->bonded_port_id, retval,
796 test_params->slave_port_ids[i]);
798 /* stop/start bonded eth dev to apply new MAC */
799 rte_eth_dev_stop(test_params->bonded_port_id);
801 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
802 "Failed to start bonded port %d",
803 test_params->bonded_port_id);
805 expected_mac_addr = (struct ether_addr *)&slave_mac;
806 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
808 /* Check primary slave MAC */
809 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
810 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
811 sizeof(read_mac_addr)),
812 "bonded port mac address not set to that of primary port\n");
814 /* Check bonded MAC */
815 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
816 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
817 sizeof(read_mac_addr)),
818 "bonded port mac address not set to that of primary port\n");
820 /* Check other slaves MACs */
821 for (j = 0; j < 4; j++) {
823 rte_eth_macaddr_get(test_params->slave_port_ids[j],
825 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
826 sizeof(read_mac_addr)),
827 "slave port mac address not set to that of primary "
834 /* Test with none existent port */
835 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
836 "read primary port from expectedly");
838 /* Test with slave port */
839 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
840 "read primary port from expectedly\n");
842 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
843 "Failed to stop and remove slaves from bonded device");
846 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
847 "read primary port from expectedly\n");
853 test_set_explicit_bonded_mac(void)
856 struct ether_addr read_mac_addr;
857 struct ether_addr *mac_addr;
859 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
861 mac_addr = (struct ether_addr *)explicit_bonded_mac;
863 /* Invalid port ID */
864 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
865 "Expected call to failed as invalid port specified.");
867 /* Non bonded device */
868 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
869 test_params->slave_port_ids[0], mac_addr),
870 "Expected call to failed as invalid port specified.");
872 /* NULL MAC address */
873 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
874 test_params->bonded_port_id, NULL),
875 "Expected call to failed as NULL MAC specified");
877 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
878 test_params->bonded_port_id, mac_addr),
879 "Failed to set MAC address on bonded port (%d)",
880 test_params->bonded_port_id);
882 /* Add 4 slaves to bonded device */
883 for (i = test_params->bonded_slave_count; i < 4; i++) {
884 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
885 "Failed to add slave to bonded device.\n");
888 /* Check bonded MAC */
889 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
890 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
891 "bonded port mac address not set to that of primary port");
893 /* Check other slaves MACs */
894 for (i = 0; i < 4; i++) {
895 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
896 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
897 sizeof(read_mac_addr)),
898 "slave port mac address not set to that of primary port");
901 /* test resetting mac address on bonded device */
903 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
904 "Failed to reset MAC address on bonded port (%d)",
905 test_params->bonded_port_id);
908 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
909 "Reset MAC address on bonded port (%d) unexpectedly",
910 test_params->slave_port_ids[1]);
912 /* test resetting mac address on bonded device with no slaves */
913 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
914 "Failed to remove slaves and stop bonded device");
916 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
917 "Failed to reset MAC address on bonded port (%d)",
918 test_params->bonded_port_id);
923 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
926 test_set_bonded_port_initialization_mac_assignment(void)
928 int i, slave_count, bonded_port_id;
930 uint8_t slaves[RTE_MAX_ETHPORTS];
931 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
933 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
935 /* Initialize default values for MAC addresses */
936 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
937 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
940 * 1. a - Create / configure bonded / slave ethdevs
942 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
943 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
944 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
946 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
947 "Failed to configure bonded ethdev");
949 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
950 char pmd_name[RTE_ETH_NAME_MAX_LEN];
952 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
954 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
956 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
957 &slave_mac_addr, rte_socket_id(), 1);
959 TEST_ASSERT(slave_port_ids[i] >= 0,
960 "Failed to create slave ethdev %s", pmd_name);
962 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
963 "Failed to configure virtual ethdev %s",
969 * 2. Add slave ethdevs to bonded device
971 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
972 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
974 "Failed to add slave (%d) to bonded port (%d).",
975 slave_port_ids[i], bonded_port_id);
978 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
980 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
981 "Number of slaves (%d) is not as expected (%d)",
982 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
986 * 3. Set explicit MAC address on bonded ethdev
988 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
989 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
991 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
992 bonded_port_id, &bonded_mac_addr),
993 "Failed to set MAC address on bonded port (%d)",
997 /* 4. a - Start bonded ethdev
998 * b - Enable slave devices
999 * c - Verify bonded/slaves ethdev MAC addresses
1001 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1002 "Failed to start bonded pmd eth device %d.",
1005 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1006 virtual_ethdev_simulate_link_status_interrupt(
1007 slave_port_ids[i], 1);
1010 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1011 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1012 sizeof(read_mac_addr)),
1013 "bonded port mac address not as expected");
1015 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1016 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1017 sizeof(read_mac_addr)),
1018 "slave port 0 mac address not as expected");
1020 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1021 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1022 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1023 sizeof(read_mac_addr)),
1024 "slave port 1 mac address not as expected");
1026 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1027 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1028 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1029 sizeof(read_mac_addr)),
1030 "slave port 2 mac address not as expected");
1033 /* 7. a - Change primary port
1034 * b - Stop / Start bonded port
1035 * d - Verify slave ethdev MAC addresses
1037 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1039 "failed to set primary port on bonded device.");
1041 rte_eth_dev_stop(bonded_port_id);
1042 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1043 "Failed to start bonded pmd eth device %d.",
1046 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1047 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1048 sizeof(read_mac_addr)),
1049 "bonded port mac address not as expected");
1051 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1052 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1053 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1054 sizeof(read_mac_addr)),
1055 "slave port 0 mac address not as expected");
1057 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1058 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1059 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1060 sizeof(read_mac_addr)),
1061 "slave port 1 mac address not as expected");
1063 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1064 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1065 sizeof(read_mac_addr)),
1066 "slave port 2 mac address not as expected");
1068 /* 6. a - Stop bonded ethdev
1069 * b - remove slave ethdevs
1070 * c - Verify slave ethdevs MACs are restored
1072 rte_eth_dev_stop(bonded_port_id);
1074 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1075 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1077 "Failed to remove slave %d from bonded port (%d).",
1078 slave_port_ids[i], bonded_port_id);
1081 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1084 TEST_ASSERT_EQUAL(slave_count, 0,
1085 "Number of slaves (%d) is great than expected (%d).",
1088 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1089 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1090 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1091 sizeof(read_mac_addr)),
1092 "slave port 0 mac address not as expected");
1094 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1095 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1096 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1097 sizeof(read_mac_addr)),
1098 "slave port 1 mac address not as expected");
1100 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1101 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1102 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1103 sizeof(read_mac_addr)),
1104 "slave port 2 mac address not as expected");
1111 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1112 uint8_t number_of_slaves, uint8_t enable_slave)
1114 /* Configure bonded device */
1115 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1116 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1117 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1120 /* Add slaves to bonded device */
1121 while (number_of_slaves > test_params->bonded_slave_count)
1122 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1123 "Failed to add slave (%d to bonding port (%d).",
1124 test_params->bonded_slave_count - 1,
1125 test_params->bonded_port_id);
1127 /* Set link bonding mode */
1128 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1130 "Failed to set link bonding mode on port (%d) to (%d).",
1131 test_params->bonded_port_id, bonding_mode);
1133 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1134 "Failed to start bonded pmd eth device %d.",
1135 test_params->bonded_port_id);
1138 enable_bonded_slaves();
1144 test_adding_slave_after_bonded_device_started(void)
1148 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1149 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1150 "Failed to add slaves to bonded device");
1152 /* Enabled slave devices */
1153 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1154 virtual_ethdev_simulate_link_status_interrupt(
1155 test_params->slave_port_ids[i], 1);
1158 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1159 test_params->slave_port_ids[test_params->bonded_slave_count]),
1160 "Failed to add slave to bonded port.\n");
1162 rte_eth_stats_reset(
1163 test_params->slave_port_ids[test_params->bonded_slave_count]);
1165 test_params->bonded_slave_count++;
1167 return remove_slaves_and_stop_bonded_device();
1170 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1171 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1173 int test_lsc_interrupt_count;
1177 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1178 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1180 pthread_mutex_lock(&mutex);
1181 test_lsc_interrupt_count++;
1183 pthread_cond_signal(&cvar);
1184 pthread_mutex_unlock(&mutex);
1188 lsc_timeout(int wait_us)
1195 gettimeofday(&tp, NULL);
1197 /* Convert from timeval to timespec */
1198 ts.tv_sec = tp.tv_sec;
1199 ts.tv_nsec = tp.tv_usec * 1000;
1200 ts.tv_nsec += wait_us * 1000;
1202 pthread_mutex_lock(&mutex);
1203 if (test_lsc_interrupt_count < 1)
1204 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1206 pthread_mutex_unlock(&mutex);
1208 if (retval == 0 && test_lsc_interrupt_count < 1)
1215 test_status_interrupt(void)
1218 uint8_t slaves[RTE_MAX_ETHPORTS];
1220 /* initialized bonding device with T slaves */
1221 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1222 BONDING_MODE_ROUND_ROBIN, 1,
1223 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1224 "Failed to initialise bonded device");
1226 test_lsc_interrupt_count = 0;
1228 /* register link status change interrupt callback */
1229 rte_eth_dev_callback_register(test_params->bonded_port_id,
1230 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1231 &test_params->bonded_port_id);
1233 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1234 slaves, RTE_MAX_ETHPORTS);
1236 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1237 "Number of active slaves (%d) is not as expected (%d)",
1238 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1240 /* Bring all 4 slaves link status to down and test that we have received a
1242 virtual_ethdev_simulate_link_status_interrupt(
1243 test_params->slave_port_ids[0], 0);
1244 virtual_ethdev_simulate_link_status_interrupt(
1245 test_params->slave_port_ids[1], 0);
1246 virtual_ethdev_simulate_link_status_interrupt(
1247 test_params->slave_port_ids[2], 0);
1249 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1250 "Received a link status change interrupt unexpectedly");
1252 virtual_ethdev_simulate_link_status_interrupt(
1253 test_params->slave_port_ids[3], 0);
1255 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1256 "timed out waiting for interrupt");
1258 TEST_ASSERT(test_lsc_interrupt_count > 0,
1259 "Did not receive link status change interrupt");
1261 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1262 slaves, RTE_MAX_ETHPORTS);
1264 TEST_ASSERT_EQUAL(slave_count, 0,
1265 "Number of active slaves (%d) is not as expected (%d)",
1268 /* bring one slave port up so link status will change */
1269 test_lsc_interrupt_count = 0;
1271 virtual_ethdev_simulate_link_status_interrupt(
1272 test_params->slave_port_ids[0], 1);
1274 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1275 "timed out waiting for interrupt");
1277 /* test that we have received another lsc interrupt */
1278 TEST_ASSERT(test_lsc_interrupt_count > 0,
1279 "Did not receive link status change interrupt");
1281 /* Verify that calling the same slave lsc interrupt doesn't cause another
1282 * lsc interrupt from bonded device */
1283 test_lsc_interrupt_count = 0;
1285 virtual_ethdev_simulate_link_status_interrupt(
1286 test_params->slave_port_ids[0], 1);
1288 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1289 "received unexpected interrupt");
1291 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1292 "Did not receive link status change interrupt");
1295 /* unregister lsc callback before exiting */
1296 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1297 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1298 &test_params->bonded_port_id);
1300 /* Clean up and remove slaves from bonded device */
1301 return remove_slaves_and_stop_bonded_device();
1305 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1306 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1307 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1309 uint16_t pktlen, generated_burst_size, ether_type;
1313 ether_type = ETHER_TYPE_IPv4;
1315 ether_type = ETHER_TYPE_IPv6;
1318 initialize_eth_header(test_params->pkt_eth_hdr,
1319 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1320 ether_type, vlan, vlan_id);
1322 initialize_eth_header(test_params->pkt_eth_hdr,
1323 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1324 ether_type, vlan, vlan_id);
1327 if (toggle_udp_port)
1328 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1331 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1336 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1337 dst_addr_1, pktlen);
1339 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1340 dst_addr_0, pktlen);
1342 ip_hdr = test_params->pkt_ipv4_hdr;
1345 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1346 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1349 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1350 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1353 ip_hdr = test_params->pkt_ipv6_hdr;
1356 /* Generate burst of packets to transmit */
1357 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1358 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1359 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1361 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1362 "Failed to generate packet burst");
1364 return generated_burst_size;
1367 /** Round Robin Mode Tests */
1370 test_roundrobin_tx_burst(void)
1373 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1374 struct rte_eth_stats port_stats;
1376 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1377 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1378 "Failed to intialise bonded device");
1380 burst_size = 20 * test_params->bonded_slave_count;
1382 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1383 "Burst size specified is greater than supported.");
1385 /* Generate test bursts of packets to transmit */
1386 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1387 burst_size, "failed to generate test burst");
1389 /* Send burst on bonded port */
1390 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1391 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1394 /* Verify bonded port tx stats */
1395 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1396 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1397 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1398 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1401 /* Verify slave ports tx stats */
1402 for (i = 0; i < test_params->bonded_slave_count; i++) {
1403 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1404 TEST_ASSERT_EQUAL(port_stats.opackets,
1405 (uint64_t)burst_size / test_params->bonded_slave_count,
1406 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1407 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1408 burst_size / test_params->bonded_slave_count);
1411 /* Put all slaves down and try and transmit */
1412 for (i = 0; i < test_params->bonded_slave_count; i++) {
1413 virtual_ethdev_simulate_link_status_interrupt(
1414 test_params->slave_port_ids[i], 0);
1417 /* Send burst on bonded port */
1418 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1419 pkt_burst, burst_size), 0,
1420 "tx burst return unexpected value");
1422 /* Clean up and remove slaves from bonded device */
1423 return remove_slaves_and_stop_bonded_device();
1427 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1431 for (i = 0; i < nb_mbufs; i++) {
1432 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1433 TEST_ASSERT_EQUAL(refcnt, val,
1434 "mbuf ref count (%d)is not the expected value (%d)",
1441 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1445 for (i = 0; i < nb_mbufs; i++)
1446 rte_pktmbuf_free(mbufs[i]);
1449 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1450 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1451 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1452 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1455 test_roundrobin_tx_burst_slave_tx_fail(void)
1457 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1458 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1460 struct rte_eth_stats port_stats;
1462 int i, first_fail_idx, tx_count;
1464 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1465 BONDING_MODE_ROUND_ROBIN, 0,
1466 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1467 "Failed to intialise bonded device");
1469 /* Generate test bursts of packets to transmit */
1470 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1471 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1472 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1473 "Failed to generate test packet burst");
1475 /* Copy references to packets which we expect not to be transmitted */
1476 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1477 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1478 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1479 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1481 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1482 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1483 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1486 /* Set virtual slave to only fail transmission of
1487 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1488 virtual_ethdev_tx_burst_fn_set_success(
1489 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1492 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1493 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1494 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1496 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1497 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1499 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1500 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1501 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1502 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1503 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1505 /* Verify that failed packet are expected failed packets */
1506 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1507 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1508 "expected mbuf (%d) pointer %p not expected pointer %p",
1509 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1512 /* Verify bonded port tx stats */
1513 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1515 TEST_ASSERT_EQUAL(port_stats.opackets,
1516 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1517 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1518 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1519 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1520 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1521 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1523 /* Verify slave ports tx stats */
1524 for (i = 0; i < test_params->bonded_slave_count; i++) {
1525 int slave_expected_tx_count;
1527 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1529 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1530 test_params->bonded_slave_count;
1532 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1533 slave_expected_tx_count = slave_expected_tx_count -
1534 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1536 TEST_ASSERT_EQUAL(port_stats.opackets,
1537 (uint64_t)slave_expected_tx_count,
1538 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1539 test_params->slave_port_ids[i],
1540 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1543 /* Verify that all mbufs have a ref value of zero */
1544 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1545 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1546 "mbufs refcnts not as expected");
1547 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1549 /* Clean up and remove slaves from bonded device */
1550 return remove_slaves_and_stop_bonded_device();
1554 test_roundrobin_rx_burst_on_single_slave(void)
1556 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1557 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1559 struct rte_eth_stats port_stats;
1561 int i, j, burst_size = 25;
1563 /* Initialize bonded device with 4 slaves in round robin mode */
1564 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1565 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1566 "Failed to initialize bonded device with slaves");
1568 /* Generate test bursts of packets to transmit */
1569 TEST_ASSERT_EQUAL(generate_test_burst(
1570 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1571 "burst generation failed");
1573 for (i = 0; i < test_params->bonded_slave_count; i++) {
1574 /* Add rx data to slave */
1575 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1576 &gen_pkt_burst[0], burst_size);
1578 /* Call rx burst on bonded device */
1579 /* Send burst on bonded port */
1580 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1581 test_params->bonded_port_id, 0, rx_pkt_burst,
1582 MAX_PKT_BURST), burst_size,
1583 "round-robin rx burst failed");
1585 /* Verify bonded device rx count */
1586 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1587 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1588 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1589 test_params->bonded_port_id,
1590 (unsigned int)port_stats.ipackets, burst_size);
1594 /* Verify bonded slave devices rx count */
1595 /* Verify slave ports tx stats */
1596 for (j = 0; j < test_params->bonded_slave_count; j++) {
1597 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1600 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1601 "Slave Port (%d) ipackets value (%u) not as expected"
1602 " (%d)", test_params->slave_port_ids[i],
1603 (unsigned int)port_stats.ipackets, burst_size);
1605 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1606 "Slave Port (%d) ipackets value (%u) not as expected"
1607 " (%d)", test_params->slave_port_ids[i],
1608 (unsigned int)port_stats.ipackets, 0);
1611 /* Reset bonded slaves stats */
1612 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1614 /* reset bonded device stats */
1615 rte_eth_stats_reset(test_params->bonded_port_id);
1619 for (i = 0; i < MAX_PKT_BURST; i++) {
1620 if (gen_pkt_burst[i] != NULL)
1621 rte_pktmbuf_free(gen_pkt_burst[i]);
1623 if (rx_pkt_burst[i] != NULL)
1624 rte_pktmbuf_free(rx_pkt_burst[i]);
1628 /* Clean up and remove slaves from bonded device */
1629 return remove_slaves_and_stop_bonded_device();
1632 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1635 test_roundrobin_rx_burst_on_multiple_slaves(void)
1637 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1639 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1640 struct rte_eth_stats port_stats;
1642 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1645 /* Initialize bonded device with 4 slaves in round robin mode */
1646 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1647 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1648 "Failed to initialize bonded device with slaves");
1650 /* Generate test bursts of packets to transmit */
1651 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1652 TEST_ASSERT_EQUAL(generate_test_burst(
1653 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1654 burst_size[i], "burst generation failed");
1657 /* Add rx data to slaves */
1658 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1659 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1660 &gen_pkt_burst[i][0], burst_size[i]);
1663 /* Call rx burst on bonded device */
1664 /* Send burst on bonded port */
1665 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1667 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1668 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1669 burst_size[0] + burst_size[1] + burst_size[2]);
1671 /* Verify bonded device rx count */
1672 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1673 TEST_ASSERT_EQUAL(port_stats.ipackets,
1674 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1675 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1676 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1677 burst_size[0] + burst_size[1] + burst_size[2]);
1679 /* Verify bonded slave devices rx counts */
1680 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1681 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1682 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1683 test_params->slave_port_ids[0],
1684 (unsigned int)port_stats.ipackets, burst_size[0]);
1686 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1687 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1688 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1689 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1692 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1693 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1694 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1695 test_params->slave_port_ids[2],
1696 (unsigned int)port_stats.ipackets, burst_size[2]);
1698 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1699 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1700 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1701 test_params->slave_port_ids[3],
1702 (unsigned int)port_stats.ipackets, 0);
1705 for (i = 0; i < MAX_PKT_BURST; i++) {
1706 if (rx_pkt_burst[i] != NULL)
1707 rte_pktmbuf_free(rx_pkt_burst[i]);
1710 /* Clean up and remove slaves from bonded device */
1711 return remove_slaves_and_stop_bonded_device();
1715 test_roundrobin_verify_mac_assignment(void)
1717 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1721 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1722 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1724 /* Initialize bonded device with 4 slaves in round robin mode */
1725 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1726 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1727 "Failed to initialize bonded device with slaves");
1729 /* Verify that all MACs are the same as first slave added to bonded dev */
1730 for (i = 0; i < test_params->bonded_slave_count; i++) {
1731 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1732 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1733 sizeof(read_mac_addr)),
1734 "slave port (%d) mac address not set to that of primary port",
1735 test_params->slave_port_ids[i]);
1738 /* change primary and verify that MAC addresses haven't changed */
1739 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1740 test_params->slave_port_ids[2]),
1741 "Failed to set bonded port (%d) primary port to (%d)",
1742 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1744 for (i = 0; i < test_params->bonded_slave_count; i++) {
1745 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1746 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1747 sizeof(read_mac_addr)),
1748 "slave port (%d) mac address has changed to that of primary"
1749 " port without stop/start toggle of bonded device",
1750 test_params->slave_port_ids[i]);
1753 /* stop / start bonded device and verify that primary MAC address is
1754 * propagate to bonded device and slaves */
1755 rte_eth_dev_stop(test_params->bonded_port_id);
1757 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1758 "Failed to start bonded device");
1760 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1761 TEST_ASSERT_SUCCESS(
1762 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1763 "bonded port (%d) mac address not set to that of new primary port",
1764 test_params->slave_port_ids[i]);
1766 for (i = 0; i < test_params->bonded_slave_count; i++) {
1767 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1768 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1769 sizeof(read_mac_addr)),
1770 "slave port (%d) mac address not set to that of new primary"
1771 " port", test_params->slave_port_ids[i]);
1774 /* Set explicit MAC address */
1775 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1776 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1777 "Failed to set MAC");
1779 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1780 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1781 sizeof(read_mac_addr)),
1782 "bonded port (%d) mac address not set to that of new primary port",
1783 test_params->slave_port_ids[i]);
1785 for (i = 0; i < test_params->bonded_slave_count; i++) {
1786 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1787 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1788 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1789 " that of new primary port\n", test_params->slave_port_ids[i]);
1792 /* Clean up and remove slaves from bonded device */
1793 return remove_slaves_and_stop_bonded_device();
1797 test_roundrobin_verify_promiscuous_enable_disable(void)
1799 int i, promiscuous_en;
1801 /* Initialize bonded device with 4 slaves in round robin mode */
1802 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1803 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1804 "Failed to initialize bonded device with slaves");
1806 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1808 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1809 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1810 "Port (%d) promiscuous mode not enabled",
1811 test_params->bonded_port_id);
1813 for (i = 0; i < test_params->bonded_slave_count; i++) {
1814 promiscuous_en = rte_eth_promiscuous_get(
1815 test_params->slave_port_ids[i]);
1816 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1817 "slave port (%d) promiscuous mode not enabled",
1818 test_params->slave_port_ids[i]);
1821 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1823 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1824 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1825 "Port (%d) promiscuous mode not disabled\n",
1826 test_params->bonded_port_id);
1828 for (i = 0; i < test_params->bonded_slave_count; i++) {
1829 promiscuous_en = rte_eth_promiscuous_get(
1830 test_params->slave_port_ids[i]);
1831 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1832 "Port (%d) promiscuous mode not disabled\n",
1833 test_params->slave_port_ids[i]);
1836 /* Clean up and remove slaves from bonded device */
1837 return remove_slaves_and_stop_bonded_device();
1840 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1841 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1844 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1846 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1847 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1848 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1850 struct rte_eth_stats port_stats;
1851 uint8_t slaves[RTE_MAX_ETHPORTS];
1853 int i, burst_size, slave_count;
1855 /* NULL all pointers in array to simplify cleanup */
1856 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1858 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1859 * in round robin mode */
1860 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1861 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1862 "Failed to initialize bonded device with slaves");
1864 /* Verify Current Slaves Count /Active Slave Count is */
1865 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1867 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1868 "Number of slaves (%d) is not as expected (%d).",
1869 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1871 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1872 slaves, RTE_MAX_ETHPORTS);
1873 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1874 "Number of active slaves (%d) is not as expected (%d).",
1875 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1877 /* Set 2 slaves eth_devs link status to down */
1878 virtual_ethdev_simulate_link_status_interrupt(
1879 test_params->slave_port_ids[1], 0);
1880 virtual_ethdev_simulate_link_status_interrupt(
1881 test_params->slave_port_ids[3], 0);
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,
1886 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1887 "Number of active slaves (%d) is not as expected (%d).\n",
1888 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1892 /* Verify that pkts are not sent on slaves with link status down:
1894 * 1. Generate test burst of traffic
1895 * 2. Transmit burst on bonded eth_dev
1896 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1897 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1900 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1901 burst_size, "generate_test_burst failed");
1903 rte_eth_stats_reset(test_params->bonded_port_id);
1907 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1908 burst_size), burst_size, "rte_eth_tx_burst failed");
1910 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1911 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1912 "Port (%d) opackets stats (%d) not expected (%d) value",
1913 test_params->bonded_port_id, (int)port_stats.opackets,
1916 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1917 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1918 "Port (%d) opackets stats (%d) not expected (%d) value",
1919 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1921 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1922 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1923 "Port (%d) opackets stats (%d) not expected (%d) value",
1924 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1926 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1927 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1928 "Port (%d) opackets stats (%d) not expected (%d) value",
1929 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1931 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1932 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1933 "Port (%d) opackets stats (%d) not expected (%d) value",
1934 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1936 /* Verify that pkts are not sent on slaves with link status down:
1938 * 1. Generate test bursts of traffic
1939 * 2. Add bursts on to virtual eth_devs
1940 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1941 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1942 * 4. Verify stats for bonded eth_dev
1943 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1945 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1946 TEST_ASSERT_EQUAL(generate_test_burst(
1947 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1948 burst_size, "failed to generate packet burst");
1950 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1951 &gen_pkt_burst[i][0], burst_size);
1954 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1955 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1956 burst_size + burst_size,
1957 "rte_eth_rx_burst failed");
1959 /* Verify bonded device rx count */
1960 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1961 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1962 "(%d) port_stats.ipackets not as expected\n",
1963 test_params->bonded_port_id);
1966 for (i = 0; i < MAX_PKT_BURST; i++) {
1967 if (rx_pkt_burst[i] != NULL)
1968 rte_pktmbuf_free(rx_pkt_burst[i]);
1970 if (gen_pkt_burst[1][i] != NULL)
1971 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1973 if (gen_pkt_burst[3][i] != NULL)
1974 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1977 /* Clean up and remove slaves from bonded device */
1978 return remove_slaves_and_stop_bonded_device();
1981 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1983 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1986 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1989 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1991 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1992 char slave_name[RTE_ETH_NAME_MAX_LEN];
1996 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1997 /* Generate slave name / MAC address */
1998 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1999 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2001 /* Create slave devices with no ISR Support */
2002 if (polling_test_slaves[i] == -1) {
2003 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2004 rte_socket_id(), 0);
2005 TEST_ASSERT(polling_test_slaves[i] >= 0,
2006 "Failed to create virtual virtual ethdev %s\n", slave_name);
2008 /* Configure slave */
2009 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2010 "Failed to configure virtual ethdev %s(%d)", slave_name,
2011 polling_test_slaves[i]);
2014 /* Add slave to bonded device */
2015 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2016 polling_test_slaves[i]),
2017 "Failed to add slave %s(%d) to bonded device %d",
2018 slave_name, polling_test_slaves[i],
2019 test_params->bonded_port_id);
2022 /* Initialize bonded device */
2023 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2024 "Failed to configure bonded device %d",
2025 test_params->bonded_port_id);
2028 /* Register link status change interrupt callback */
2029 rte_eth_dev_callback_register(test_params->bonded_port_id,
2030 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2031 &test_params->bonded_port_id);
2033 /* link status change callback for first slave link up */
2034 test_lsc_interrupt_count = 0;
2036 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2038 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2041 /* no link status change callback for second slave link up */
2042 test_lsc_interrupt_count = 0;
2044 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2046 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2048 /* link status change callback for both slave links down */
2049 test_lsc_interrupt_count = 0;
2051 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2052 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2054 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2056 /* Un-Register link status change interrupt callback */
2057 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2058 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2059 &test_params->bonded_port_id);
2062 /* Clean up and remove slaves from bonded device */
2063 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2065 TEST_ASSERT_SUCCESS(
2066 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2067 polling_test_slaves[i]),
2068 "Failed to remove slave %d from bonded port (%d)",
2069 polling_test_slaves[i], test_params->bonded_port_id);
2072 return remove_slaves_and_stop_bonded_device();
2076 /** Active Backup Mode Tests */
2079 test_activebackup_tx_burst(void)
2081 int i, pktlen, primary_port, burst_size;
2082 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2083 struct rte_eth_stats port_stats;
2085 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2086 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2087 "Failed to initialize bonded device with slaves");
2089 initialize_eth_header(test_params->pkt_eth_hdr,
2090 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2091 ETHER_TYPE_IPv4, 0, 0);
2092 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2094 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2095 dst_addr_0, pktlen);
2097 burst_size = 20 * test_params->bonded_slave_count;
2099 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2100 "Burst size specified is greater than supported.");
2102 /* Generate a burst of packets to transmit */
2103 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2104 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2105 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2106 burst_size, "failed to generate burst correctly");
2108 /* Send burst on bonded port */
2109 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2110 burst_size), burst_size, "tx burst failed");
2112 /* Verify bonded port tx stats */
2113 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2114 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2115 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2116 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2119 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2121 /* Verify slave ports tx stats */
2122 for (i = 0; i < test_params->bonded_slave_count; i++) {
2123 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2124 if (test_params->slave_port_ids[i] == primary_port) {
2125 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2126 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2127 test_params->bonded_port_id,
2128 (unsigned int)port_stats.opackets,
2129 burst_size / test_params->bonded_slave_count);
2131 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2132 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2133 test_params->bonded_port_id,
2134 (unsigned int)port_stats.opackets, 0);
2138 /* Put all slaves down and try and transmit */
2139 for (i = 0; i < test_params->bonded_slave_count; i++) {
2140 virtual_ethdev_simulate_link_status_interrupt(
2141 test_params->slave_port_ids[i], 0);
2144 /* Send burst on bonded port */
2145 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2146 pkts_burst, burst_size), 0, "Sending empty burst failed");
2148 /* Clean up and remove slaves from bonded device */
2149 return remove_slaves_and_stop_bonded_device();
2152 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2155 test_activebackup_rx_burst(void)
2157 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2158 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2160 struct rte_eth_stats port_stats;
2164 int i, j, burst_size = 17;
2166 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2167 BONDING_MODE_ACTIVE_BACKUP, 0,
2168 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2169 "Failed to initialize bonded device with slaves");
2171 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2172 TEST_ASSERT(primary_port >= 0,
2173 "failed to get primary slave for bonded port (%d)",
2174 test_params->bonded_port_id);
2176 for (i = 0; i < test_params->bonded_slave_count; i++) {
2177 /* Generate test bursts of packets to transmit */
2178 TEST_ASSERT_EQUAL(generate_test_burst(
2179 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2180 burst_size, "burst generation failed");
2182 /* Add rx data to slave */
2183 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2184 &gen_pkt_burst[0], burst_size);
2186 /* Call rx burst on bonded device */
2187 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2188 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2189 "rte_eth_rx_burst failed");
2191 if (test_params->slave_port_ids[i] == primary_port) {
2192 /* Verify bonded device rx count */
2193 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2194 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2195 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2196 test_params->bonded_port_id,
2197 (unsigned int)port_stats.ipackets, burst_size);
2199 /* Verify bonded slave devices rx count */
2200 for (j = 0; j < test_params->bonded_slave_count; j++) {
2201 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2203 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2204 "Slave Port (%d) ipackets value (%u) not as "
2205 "expected (%d)", test_params->slave_port_ids[i],
2206 (unsigned int)port_stats.ipackets, burst_size);
2208 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2209 "Slave Port (%d) ipackets value (%u) not as "
2210 "expected (%d)\n", test_params->slave_port_ids[i],
2211 (unsigned int)port_stats.ipackets, 0);
2215 for (j = 0; j < test_params->bonded_slave_count; j++) {
2216 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2217 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2218 "Slave Port (%d) ipackets value (%u) not as expected "
2219 "(%d)", test_params->slave_port_ids[i],
2220 (unsigned int)port_stats.ipackets, 0);
2225 for (i = 0; i < MAX_PKT_BURST; i++) {
2226 if (rx_pkt_burst[i] != NULL) {
2227 rte_pktmbuf_free(rx_pkt_burst[i]);
2228 rx_pkt_burst[i] = NULL;
2232 /* reset bonded device stats */
2233 rte_eth_stats_reset(test_params->bonded_port_id);
2236 /* Clean up and remove slaves from bonded device */
2237 return remove_slaves_and_stop_bonded_device();
2241 test_activebackup_verify_promiscuous_enable_disable(void)
2243 int i, primary_port, promiscuous_en;
2245 /* Initialize bonded device with 4 slaves in round robin mode */
2246 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2247 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2248 "Failed to initialize bonded device with slaves");
2250 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2251 TEST_ASSERT(primary_port >= 0,
2252 "failed to get primary slave for bonded port (%d)",
2253 test_params->bonded_port_id);
2255 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2257 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2258 "Port (%d) promiscuous mode not enabled",
2259 test_params->bonded_port_id);
2261 for (i = 0; i < test_params->bonded_slave_count; i++) {
2262 promiscuous_en = rte_eth_promiscuous_get(
2263 test_params->slave_port_ids[i]);
2264 if (primary_port == test_params->slave_port_ids[i]) {
2265 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2266 "slave port (%d) promiscuous mode not enabled",
2267 test_params->slave_port_ids[i]);
2269 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2270 "slave port (%d) promiscuous mode enabled",
2271 test_params->slave_port_ids[i]);
2276 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2278 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2279 "Port (%d) promiscuous mode not disabled\n",
2280 test_params->bonded_port_id);
2282 for (i = 0; i < test_params->bonded_slave_count; i++) {
2283 promiscuous_en = rte_eth_promiscuous_get(
2284 test_params->slave_port_ids[i]);
2285 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2286 "slave port (%d) promiscuous mode not disabled\n",
2287 test_params->slave_port_ids[i]);
2290 /* Clean up and remove slaves from bonded device */
2291 return remove_slaves_and_stop_bonded_device();
2295 test_activebackup_verify_mac_assignment(void)
2297 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2299 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2300 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2302 /* Initialize bonded device with 2 slaves in active backup mode */
2303 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2304 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2305 "Failed to initialize bonded device with slaves");
2307 /* Verify that bonded MACs is that of first slave and that the other slave
2308 * MAC hasn't been changed */
2309 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2311 sizeof(read_mac_addr)),
2312 "bonded port (%d) mac address not set to that of primary port",
2313 test_params->bonded_port_id);
2315 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2317 sizeof(read_mac_addr)),
2318 "slave port (%d) mac address not set to that of primary port",
2319 test_params->slave_port_ids[0]);
2321 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2323 sizeof(read_mac_addr)),
2324 "slave port (%d) mac address not as expected",
2325 test_params->slave_port_ids[1]);
2327 /* change primary and verify that MAC addresses haven't changed */
2328 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2329 test_params->slave_port_ids[1]), 0,
2330 "Failed to set bonded port (%d) primary port to (%d)",
2331 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2333 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2335 sizeof(read_mac_addr)),
2336 "bonded port (%d) mac address not set to that of primary port",
2337 test_params->bonded_port_id);
2339 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2340 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2341 sizeof(read_mac_addr)),
2342 "slave port (%d) mac address not set to that of primary port",
2343 test_params->slave_port_ids[0]);
2345 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2347 sizeof(read_mac_addr)),
2348 "slave port (%d) mac address not as expected",
2349 test_params->slave_port_ids[1]);
2351 /* stop / start bonded device and verify that primary MAC address is
2352 * propagated to bonded device and slaves */
2354 rte_eth_dev_stop(test_params->bonded_port_id);
2356 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2357 "Failed to start device");
2359 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2361 sizeof(read_mac_addr)),
2362 "bonded port (%d) mac address not set to that of primary port",
2363 test_params->bonded_port_id);
2365 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2367 sizeof(read_mac_addr)),
2368 "slave port (%d) mac address not as expected",
2369 test_params->slave_port_ids[0]);
2371 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2372 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2373 sizeof(read_mac_addr)),
2374 "slave port (%d) mac address not set to that of primary port",
2375 test_params->slave_port_ids[1]);
2377 /* Set explicit MAC address */
2378 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2379 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2380 "failed to set MAC address");
2382 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2383 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2384 sizeof(read_mac_addr)),
2385 "bonded port (%d) mac address not set to that of bonded port",
2386 test_params->bonded_port_id);
2388 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2389 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2390 sizeof(read_mac_addr)),
2391 "slave port (%d) mac address not as expected",
2392 test_params->slave_port_ids[0]);
2394 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2395 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2396 sizeof(read_mac_addr)),
2397 "slave port (%d) mac address not set to that of bonded port",
2398 test_params->slave_port_ids[1]);
2400 /* Clean up and remove slaves from bonded device */
2401 return remove_slaves_and_stop_bonded_device();
2405 test_activebackup_verify_slave_link_status_change_failover(void)
2407 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2408 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2409 struct rte_eth_stats port_stats;
2411 uint8_t slaves[RTE_MAX_ETHPORTS];
2413 int i, j, burst_size, slave_count, primary_port;
2417 memset(pkt_burst, 0, sizeof(pkt_burst));
2419 /* Generate packet burst for testing */
2420 TEST_ASSERT_EQUAL(generate_test_burst(
2421 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2422 "generate_test_burst failed");
2424 /* Initialize bonded device with 4 slaves in round robin mode */
2425 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2426 BONDING_MODE_ACTIVE_BACKUP, 0,
2427 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2428 "Failed to initialize bonded device with slaves");
2430 /* Verify Current Slaves Count /Active Slave Count is */
2431 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2433 TEST_ASSERT_EQUAL(slave_count, 4,
2434 "Number of slaves (%d) is not as expected (%d).",
2437 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2438 slaves, RTE_MAX_ETHPORTS);
2439 TEST_ASSERT_EQUAL(slave_count, 4,
2440 "Number of active slaves (%d) is not as expected (%d).",
2443 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2444 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2445 "Primary port not as expected");
2447 /* Bring 2 slaves down and verify active slave count */
2448 virtual_ethdev_simulate_link_status_interrupt(
2449 test_params->slave_port_ids[1], 0);
2450 virtual_ethdev_simulate_link_status_interrupt(
2451 test_params->slave_port_ids[3], 0);
2453 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2454 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2455 "Number of active slaves (%d) is not as expected (%d).",
2458 virtual_ethdev_simulate_link_status_interrupt(
2459 test_params->slave_port_ids[1], 1);
2460 virtual_ethdev_simulate_link_status_interrupt(
2461 test_params->slave_port_ids[3], 1);
2464 /* Bring primary port down, verify that active slave count is 3 and primary
2466 virtual_ethdev_simulate_link_status_interrupt(
2467 test_params->slave_port_ids[0], 0);
2469 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2470 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2472 "Number of active slaves (%d) is not as expected (%d).",
2475 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2476 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2477 "Primary port not as expected");
2479 /* Verify that pkts are sent on new primary slave */
2481 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2482 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2483 burst_size), burst_size, "rte_eth_tx_burst failed");
2485 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2486 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2487 "(%d) port_stats.opackets not as expected",
2488 test_params->slave_port_ids[2]);
2490 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2491 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2492 "(%d) port_stats.opackets not as expected\n",
2493 test_params->slave_port_ids[0]);
2495 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2496 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2497 "(%d) port_stats.opackets not as expected\n",
2498 test_params->slave_port_ids[1]);
2500 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2501 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2502 "(%d) port_stats.opackets not as expected\n",
2503 test_params->slave_port_ids[3]);
2505 /* Generate packet burst for testing */
2507 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2508 TEST_ASSERT_EQUAL(generate_test_burst(
2509 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2510 "generate_test_burst failed");
2512 virtual_ethdev_add_mbufs_to_rx_queue(
2513 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2516 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2517 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2518 burst_size, "rte_eth_rx_burst\n");
2520 /* Verify bonded device rx count */
2521 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2522 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2523 "(%d) port_stats.ipackets not as expected",
2524 test_params->bonded_port_id);
2526 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2527 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2528 "(%d) port_stats.opackets not as expected",
2529 test_params->slave_port_ids[2]);
2531 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2532 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2533 "(%d) port_stats.opackets not as expected",
2534 test_params->slave_port_ids[0]);
2536 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2537 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2538 "(%d) port_stats.opackets not as expected",
2539 test_params->slave_port_ids[1]);
2541 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2542 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2543 "(%d) port_stats.opackets not as expected",
2544 test_params->slave_port_ids[3]);
2547 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2548 for (j = 0; j < MAX_PKT_BURST; j++) {
2549 if (pkt_burst[i][j] != NULL) {
2550 rte_pktmbuf_free(pkt_burst[i][j]);
2551 pkt_burst[i][j] = NULL;
2556 /* Clean up and remove slaves from bonded device */
2557 return remove_slaves_and_stop_bonded_device();
2560 /** Balance Mode Tests */
2563 test_balance_xmit_policy_configuration(void)
2565 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2566 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2567 "Failed to initialize_bonded_device_with_slaves.");
2569 /* Invalid port id */
2570 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2571 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2572 "Expected call to failed as invalid port specified.");
2574 /* Set xmit policy on non bonded device */
2575 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2576 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2577 "Expected call to failed as invalid port specified.");
2580 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2581 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2582 "Failed to set balance xmit policy.");
2584 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2585 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2588 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2589 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2590 "Failed to set balance xmit policy.");
2592 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2593 BALANCE_XMIT_POLICY_LAYER23,
2594 "balance xmit policy not as expected.");
2597 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2598 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2599 "Failed to set balance xmit policy.");
2601 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2602 BALANCE_XMIT_POLICY_LAYER34,
2603 "balance xmit policy not as expected.");
2605 /* Invalid port id */
2606 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2607 "Expected call to failed as invalid port specified.");
2609 /* Clean up and remove slaves from bonded device */
2610 return remove_slaves_and_stop_bonded_device();
2613 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2616 test_balance_l2_tx_burst(void)
2618 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2619 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2623 struct rte_eth_stats port_stats;
2625 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2626 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2627 "Failed to initialize_bonded_device_with_slaves.");
2629 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2630 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2631 "Failed to set balance xmit policy.");
2633 initialize_eth_header(test_params->pkt_eth_hdr,
2634 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2635 ETHER_TYPE_IPv4, 0, 0);
2636 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2638 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2639 dst_addr_0, pktlen);
2641 /* Generate a burst 1 of packets to transmit */
2642 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2643 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2644 test_params->pkt_udp_hdr, burst_size[0],
2645 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2646 "failed to generate packet burst");
2648 initialize_eth_header(test_params->pkt_eth_hdr,
2649 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2650 ETHER_TYPE_IPv4, 0, 0);
2652 /* Generate a burst 2 of packets to transmit */
2653 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2654 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2655 test_params->pkt_udp_hdr, burst_size[1],
2656 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2657 "failed to generate packet burst");
2659 /* Send burst 1 on bonded port */
2660 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2661 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2662 &pkts_burst[i][0], burst_size[i]),
2663 burst_size[i], "Failed to transmit packet burst");
2666 /* Verify bonded port tx stats */
2667 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2668 TEST_ASSERT_EQUAL(port_stats.opackets,
2669 (uint64_t)(burst_size[0] + burst_size[1]),
2670 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2671 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2672 burst_size[0] + burst_size[1]);
2675 /* Verify slave ports tx stats */
2676 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2677 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2678 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2679 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2682 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2683 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2684 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2685 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2688 /* Put all slaves down and try and transmit */
2689 for (i = 0; i < test_params->bonded_slave_count; i++) {
2691 virtual_ethdev_simulate_link_status_interrupt(
2692 test_params->slave_port_ids[i], 0);
2695 /* Send burst on bonded port */
2696 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2697 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2698 0, "Expected zero packet");
2700 /* Clean up and remove slaves from bonded device */
2701 return remove_slaves_and_stop_bonded_device();
2705 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2706 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2708 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2710 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2711 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2713 struct rte_eth_stats port_stats;
2715 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2716 BONDING_MODE_BALANCE, 0, 2, 1),
2717 "Failed to initialize_bonded_device_with_slaves.");
2719 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2720 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2721 "Failed to set balance xmit policy.");
2726 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2727 "Burst size specified is greater than supported.");
2729 /* Generate test bursts of packets to transmit */
2730 TEST_ASSERT_EQUAL(generate_test_burst(
2731 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2732 burst_size_1, "failed to generate packet burst");
2734 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2735 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2736 "failed to generate packet burst");
2738 /* Send burst 1 on bonded port */
2739 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2741 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2743 /* Send burst 2 on bonded port */
2744 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2746 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2748 /* Verify bonded port tx stats */
2749 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2750 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2751 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2752 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2755 /* Verify slave ports tx stats */
2756 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2757 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2758 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2759 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2762 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2763 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2764 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2765 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2768 /* Put all slaves down and try and transmit */
2769 for (i = 0; i < test_params->bonded_slave_count; i++) {
2771 virtual_ethdev_simulate_link_status_interrupt(
2772 test_params->slave_port_ids[i], 0);
2775 /* Send burst on bonded port */
2776 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2777 test_params->bonded_port_id, 0, pkts_burst_1,
2778 burst_size_1), 0, "Expected zero packet");
2781 /* Clean up and remove slaves from bonded device */
2782 return remove_slaves_and_stop_bonded_device();
2786 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2788 return balance_l23_tx_burst(0, 1, 1, 0);
2792 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2794 return balance_l23_tx_burst(1, 1, 0, 1);
2798 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2800 return balance_l23_tx_burst(0, 0, 0, 1);
2804 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2806 return balance_l23_tx_burst(1, 0, 0, 1);
2810 test_balance_l23_tx_burst_toggle_mac_addr(void)
2812 return balance_l23_tx_burst(0, 0, 1, 0);
2816 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2817 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2818 uint8_t toggle_udp_port)
2820 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2822 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2823 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2825 struct rte_eth_stats port_stats;
2827 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2828 BONDING_MODE_BALANCE, 0, 2, 1),
2829 "Failed to initialize_bonded_device_with_slaves.");
2831 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2832 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2833 "Failed to set balance xmit policy.");
2838 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2839 "Burst size specified is greater than supported.");
2841 /* Generate test bursts of packets to transmit */
2842 TEST_ASSERT_EQUAL(generate_test_burst(
2843 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2844 burst_size_1, "failed to generate burst");
2846 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2847 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2848 toggle_udp_port), burst_size_2, "failed to generate burst");
2850 /* Send burst 1 on bonded port */
2851 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2853 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2855 /* Send burst 2 on bonded port */
2856 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2858 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2861 /* Verify bonded port tx stats */
2862 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2863 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2864 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2865 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2868 /* Verify slave ports tx stats */
2869 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2870 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2871 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2872 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2875 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2876 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2877 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2878 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2881 /* Put all slaves down and try and transmit */
2882 for (i = 0; i < test_params->bonded_slave_count; i++) {
2884 virtual_ethdev_simulate_link_status_interrupt(
2885 test_params->slave_port_ids[i], 0);
2888 /* Send burst on bonded port */
2889 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2890 test_params->bonded_port_id, 0, pkts_burst_1,
2891 burst_size_1), 0, "Expected zero packet");
2893 /* Clean up and remove slaves from bonded device */
2894 return remove_slaves_and_stop_bonded_device();
2898 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2900 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2904 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2906 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2910 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2912 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2916 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2918 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2922 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2924 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2928 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2930 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2933 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2934 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2935 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2936 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2937 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2940 test_balance_tx_burst_slave_tx_fail(void)
2942 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2943 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2945 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2947 struct rte_eth_stats port_stats;
2949 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2951 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2952 BONDING_MODE_BALANCE, 0,
2953 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2954 "Failed to intialise bonded device");
2956 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2957 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2958 "Failed to set balance xmit policy.");
2961 /* Generate test bursts for transmission */
2962 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2963 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2964 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2965 "Failed to generate test packet burst 1");
2967 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2968 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2970 /* copy mbuf referneces for expected transmission failures */
2971 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2972 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2974 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2975 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2976 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2977 "Failed to generate test packet burst 2");
2980 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2981 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2982 virtual_ethdev_tx_burst_fn_set_success(
2983 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2986 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2987 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2988 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2991 /* Transmit burst 1 */
2992 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2993 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2995 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2996 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2997 "Transmitted (%d) packets, expected to transmit (%d) packets",
2998 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2999 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3001 /* Verify that failed packet are expected failed packets */
3002 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3003 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3004 "expected mbuf (%d) pointer %p not expected pointer %p",
3005 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3008 /* Transmit burst 2 */
3009 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3010 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3012 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3013 "Transmitted (%d) packets, expected to transmit (%d) packets",
3014 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3017 /* Verify bonded port tx stats */
3018 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3020 TEST_ASSERT_EQUAL(port_stats.opackets,
3021 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3022 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3023 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3024 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3025 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3026 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3027 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3028 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3030 /* Verify slave ports tx stats */
3032 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3034 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3035 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3036 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3037 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3038 test_params->slave_port_ids[0],
3039 (unsigned int)port_stats.opackets,
3040 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3041 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3046 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3048 TEST_ASSERT_EQUAL(port_stats.opackets,
3049 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3050 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3051 test_params->slave_port_ids[1],
3052 (unsigned int)port_stats.opackets,
3053 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3055 /* Verify that all mbufs have a ref value of zero */
3056 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3057 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3058 "mbufs refcnts not as expected");
3060 free_mbufs(&pkts_burst_1[tx_count_1],
3061 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3063 /* Clean up and remove slaves from bonded device */
3064 return remove_slaves_and_stop_bonded_device();
3067 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3070 test_balance_rx_burst(void)
3072 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3074 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3075 struct rte_eth_stats port_stats;
3077 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3080 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3082 /* Initialize bonded device with 4 slaves in round robin mode */
3083 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3084 BONDING_MODE_BALANCE, 0, 3, 1),
3085 "Failed to intialise bonded device");
3087 /* Generate test bursts of packets to transmit */
3088 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3089 TEST_ASSERT_EQUAL(generate_test_burst(
3090 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3091 0, 0), burst_size[i],
3092 "failed to generate packet burst");
3095 /* Add rx data to slaves */
3096 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3097 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3098 &gen_pkt_burst[i][0], burst_size[i]);
3101 /* Call rx burst on bonded device */
3102 /* Send burst on bonded port */
3103 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3104 rx_pkt_burst, MAX_PKT_BURST),
3105 burst_size[0] + burst_size[1] + burst_size[2],
3106 "balance rx burst failed\n");
3108 /* Verify bonded device rx count */
3109 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3110 TEST_ASSERT_EQUAL(port_stats.ipackets,
3111 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3112 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3113 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3114 burst_size[0] + burst_size[1] + burst_size[2]);
3117 /* Verify bonded slave devices rx counts */
3118 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3119 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3120 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3121 test_params->slave_port_ids[0],
3122 (unsigned int)port_stats.ipackets, burst_size[0]);
3124 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3125 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3126 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3127 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3130 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3131 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3132 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3133 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3136 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3137 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3138 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3139 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3143 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3144 for (j = 0; j < MAX_PKT_BURST; j++) {
3145 if (gen_pkt_burst[i][j] != NULL) {
3146 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3147 gen_pkt_burst[i][j] = NULL;
3152 /* Clean up and remove slaves from bonded device */
3153 return remove_slaves_and_stop_bonded_device();
3157 test_balance_verify_promiscuous_enable_disable(void)
3161 /* Initialize bonded device with 4 slaves in round robin mode */
3162 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3163 BONDING_MODE_BALANCE, 0, 4, 1),
3164 "Failed to intialise bonded device");
3166 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3168 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3169 "Port (%d) promiscuous mode not enabled",
3170 test_params->bonded_port_id);
3172 for (i = 0; i < test_params->bonded_slave_count; i++) {
3173 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3174 test_params->slave_port_ids[i]), 1,
3175 "Port (%d) promiscuous mode not enabled",
3176 test_params->slave_port_ids[i]);
3179 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3181 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3182 "Port (%d) promiscuous mode not disabled",
3183 test_params->bonded_port_id);
3185 for (i = 0; i < test_params->bonded_slave_count; i++) {
3186 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3187 test_params->slave_port_ids[i]), 0,
3188 "Port (%d) promiscuous mode not disabled",
3189 test_params->slave_port_ids[i]);
3192 /* Clean up and remove slaves from bonded device */
3193 return remove_slaves_and_stop_bonded_device();
3197 test_balance_verify_mac_assignment(void)
3199 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3201 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3202 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3204 /* Initialize bonded device with 2 slaves in active backup mode */
3205 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3206 BONDING_MODE_BALANCE, 0, 2, 1),
3207 "Failed to intialise bonded device");
3209 /* Verify that bonded MACs is that of first slave and that the other slave
3210 * MAC hasn't been changed */
3211 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3212 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3213 sizeof(read_mac_addr)),
3214 "bonded port (%d) mac address not set to that of primary port",
3215 test_params->bonded_port_id);
3217 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3218 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3219 sizeof(read_mac_addr)),
3220 "slave port (%d) mac address not set to that of primary port",
3221 test_params->slave_port_ids[0]);
3223 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3224 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3225 sizeof(read_mac_addr)),
3226 "slave port (%d) mac address not set to that of primary port",
3227 test_params->slave_port_ids[1]);
3229 /* change primary and verify that MAC addresses haven't changed */
3230 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3231 test_params->slave_port_ids[1]),
3232 "Failed to set bonded port (%d) primary port to (%d)\n",
3233 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3235 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3236 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3237 sizeof(read_mac_addr)),
3238 "bonded port (%d) mac address not set to that of primary port",
3239 test_params->bonded_port_id);
3241 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3242 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3243 sizeof(read_mac_addr)),
3244 "slave port (%d) mac address not set to that of primary port",
3245 test_params->slave_port_ids[0]);
3247 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3248 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3249 sizeof(read_mac_addr)),
3250 "slave port (%d) mac address not set to that of primary port",
3251 test_params->slave_port_ids[1]);
3253 /* stop / start bonded device and verify that primary MAC address is
3254 * propagated to bonded device and slaves */
3256 rte_eth_dev_stop(test_params->bonded_port_id);
3258 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3259 "Failed to start bonded device");
3261 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3262 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3263 sizeof(read_mac_addr)),
3264 "bonded port (%d) mac address not set to that of primary port",
3265 test_params->bonded_port_id);
3267 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3268 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3269 sizeof(read_mac_addr)),
3270 "slave port (%d) mac address not set to that of primary port",
3271 test_params->slave_port_ids[0]);
3273 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3274 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3275 sizeof(read_mac_addr)),
3276 "slave port (%d) mac address not set to that of primary port",
3277 test_params->slave_port_ids[1]);
3279 /* Set explicit MAC address */
3280 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3281 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3282 "failed to set MAC");
3284 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3285 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3286 sizeof(read_mac_addr)),
3287 "bonded port (%d) mac address not set to that of bonded port",
3288 test_params->bonded_port_id);
3290 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3291 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3292 sizeof(read_mac_addr)),
3293 "slave port (%d) mac address not as expected\n",
3294 test_params->slave_port_ids[0]);
3296 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3297 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3298 sizeof(read_mac_addr)),
3299 "slave port (%d) mac address not set to that of bonded port",
3300 test_params->slave_port_ids[1]);
3302 /* Clean up and remove slaves from bonded device */
3303 return remove_slaves_and_stop_bonded_device();
3306 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3309 test_balance_verify_slave_link_status_change_behaviour(void)
3311 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3312 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3313 struct rte_eth_stats port_stats;
3315 uint8_t slaves[RTE_MAX_ETHPORTS];
3317 int i, j, burst_size, slave_count;
3319 memset(pkt_burst, 0, sizeof(pkt_burst));
3321 /* Initialize bonded device with 4 slaves in round robin mode */
3322 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3323 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3324 "Failed to intialise bonded device");
3326 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3327 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3328 "Failed to set balance xmit policy.");
3331 /* Verify Current Slaves Count /Active Slave Count is */
3332 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3334 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3335 "Number of slaves (%d) is not as expected (%d).",
3336 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3338 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3339 slaves, RTE_MAX_ETHPORTS);
3340 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3341 "Number of active slaves (%d) is not as expected (%d).",
3342 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3344 /* Set 2 slaves link status to down */
3345 virtual_ethdev_simulate_link_status_interrupt(
3346 test_params->slave_port_ids[1], 0);
3347 virtual_ethdev_simulate_link_status_interrupt(
3348 test_params->slave_port_ids[3], 0);
3350 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3351 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3352 "Number of active slaves (%d) is not as expected (%d).",
3355 /* Send to sets of packet burst and verify that they are balanced across
3359 TEST_ASSERT_EQUAL(generate_test_burst(
3360 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3361 "generate_test_burst failed");
3363 TEST_ASSERT_EQUAL(generate_test_burst(
3364 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3365 "generate_test_burst failed");
3367 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3368 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3369 burst_size, "rte_eth_tx_burst failed");
3371 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3372 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3373 burst_size, "rte_eth_tx_burst failed");
3376 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3377 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3378 "(%d) port_stats.opackets (%d) not as expected (%d).",
3379 test_params->bonded_port_id, (int)port_stats.opackets,
3380 burst_size + burst_size);
3382 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3383 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3384 "(%d) port_stats.opackets (%d) not as expected (%d).",
3385 test_params->slave_port_ids[0], (int)port_stats.opackets,
3388 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3389 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3390 "(%d) port_stats.opackets (%d) not as expected (%d).",
3391 test_params->slave_port_ids[2], (int)port_stats.opackets,
3394 /* verify that all packets get send on primary slave when no other slaves
3396 virtual_ethdev_simulate_link_status_interrupt(
3397 test_params->slave_port_ids[2], 0);
3399 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3400 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3401 "Number of active slaves (%d) is not as expected (%d).",
3404 TEST_ASSERT_EQUAL(generate_test_burst(
3405 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3406 "generate_test_burst failed");
3408 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3409 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3410 burst_size, "rte_eth_tx_burst failed");
3412 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3413 TEST_ASSERT_EQUAL(port_stats.opackets,
3414 (uint64_t)(burst_size + burst_size + burst_size),
3415 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3416 test_params->bonded_port_id, (int)port_stats.opackets,
3417 burst_size + burst_size + burst_size);
3419 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3420 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3421 "(%d) port_stats.opackets (%d) not as expected (%d).",
3422 test_params->slave_port_ids[0], (int)port_stats.opackets,
3423 burst_size + burst_size);
3425 virtual_ethdev_simulate_link_status_interrupt(
3426 test_params->slave_port_ids[0], 0);
3427 virtual_ethdev_simulate_link_status_interrupt(
3428 test_params->slave_port_ids[1], 1);
3429 virtual_ethdev_simulate_link_status_interrupt(
3430 test_params->slave_port_ids[2], 1);
3431 virtual_ethdev_simulate_link_status_interrupt(
3432 test_params->slave_port_ids[3], 1);
3434 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3435 TEST_ASSERT_EQUAL(generate_test_burst(
3436 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3437 "Failed to generate packet burst");
3439 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3440 &pkt_burst[i][0], burst_size);
3443 /* Verify that pkts are not received on slaves with link status down */
3445 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3448 /* Verify bonded device rx count */
3449 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3450 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3451 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3452 test_params->bonded_port_id, (int)port_stats.ipackets,
3455 /* free mbufs allocate for rx testing */
3456 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3457 for (j = 0; j < MAX_PKT_BURST; j++) {
3458 if (pkt_burst[i][j] != NULL) {
3459 rte_pktmbuf_free(pkt_burst[i][j]);
3460 pkt_burst[i][j] = NULL;
3465 /* Clean up and remove slaves from bonded device */
3466 return remove_slaves_and_stop_bonded_device();
3470 test_broadcast_tx_burst(void)
3472 int i, pktlen, burst_size;
3473 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3475 struct rte_eth_stats port_stats;
3477 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3478 BONDING_MODE_BROADCAST, 0, 2, 1),
3479 "Failed to intialise bonded device");
3481 initialize_eth_header(test_params->pkt_eth_hdr,
3482 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3483 ETHER_TYPE_IPv4, 0, 0);
3485 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3487 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3488 dst_addr_0, pktlen);
3490 burst_size = 20 * test_params->bonded_slave_count;
3492 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3493 "Burst size specified is greater than supported.");
3495 /* Generate a burst of packets to transmit */
3496 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3497 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3498 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3499 1), burst_size, "Failed to generate packet burst");
3501 /* Send burst on bonded port */
3502 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3503 pkts_burst, burst_size), burst_size,
3504 "Bonded Port (%d) rx burst failed, packets transmitted value "
3505 "not as expected (%d)",
3506 test_params->bonded_port_id, burst_size);
3508 /* Verify bonded port tx stats */
3509 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3510 TEST_ASSERT_EQUAL(port_stats.opackets,
3511 (uint64_t)burst_size * test_params->bonded_slave_count,
3512 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3513 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3516 /* Verify slave ports tx stats */
3517 for (i = 0; i < test_params->bonded_slave_count; i++) {
3518 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3519 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3520 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3521 test_params->bonded_port_id,
3522 (unsigned int)port_stats.opackets, burst_size);
3525 /* Put all slaves down and try and transmit */
3526 for (i = 0; i < test_params->bonded_slave_count; i++) {
3528 virtual_ethdev_simulate_link_status_interrupt(
3529 test_params->slave_port_ids[i], 0);
3532 /* Send burst on bonded port */
3533 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3534 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3535 "transmitted an unexpected number of packets");
3537 /* Clean up and remove slaves from bonded device */
3538 return remove_slaves_and_stop_bonded_device();
3542 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3543 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3544 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3545 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3548 test_broadcast_tx_burst_slave_tx_fail(void)
3550 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3551 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3553 struct rte_eth_stats port_stats;
3557 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3558 BONDING_MODE_BROADCAST, 0,
3559 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3560 "Failed to intialise bonded device");
3562 /* Generate test bursts for transmission */
3563 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3564 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3565 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3566 "Failed to generate test packet burst");
3568 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3569 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3570 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3573 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3574 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3575 virtual_ethdev_tx_burst_fn_set_success(
3576 test_params->slave_port_ids[0],
3578 virtual_ethdev_tx_burst_fn_set_success(
3579 test_params->slave_port_ids[1],
3581 virtual_ethdev_tx_burst_fn_set_success(
3582 test_params->slave_port_ids[2],
3585 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3586 test_params->slave_port_ids[0],
3587 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3589 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3590 test_params->slave_port_ids[1],
3591 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3593 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3594 test_params->slave_port_ids[2],
3595 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3597 /* Transmit burst */
3598 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3599 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3601 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3602 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3603 "Transmitted (%d) packets, expected to transmit (%d) packets",
3604 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3605 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3607 /* Verify that failed packet are expected failed packets */
3608 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3609 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3610 "expected mbuf (%d) pointer %p not expected pointer %p",
3611 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3614 /* Verify slave ports tx stats */
3616 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3618 TEST_ASSERT_EQUAL(port_stats.opackets,
3619 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3620 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3621 "Port (%d) opackets value (%u) not as expected (%d)",
3622 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3623 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3624 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3627 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3629 TEST_ASSERT_EQUAL(port_stats.opackets,
3630 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3631 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3632 "Port (%d) opackets value (%u) not as expected (%d)",
3633 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3634 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3635 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3637 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3639 TEST_ASSERT_EQUAL(port_stats.opackets,
3640 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3641 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3642 "Port (%d) opackets value (%u) not as expected (%d)",
3643 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3644 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3645 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3648 /* Verify that all mbufs who transmission failed have a ref value of one */
3649 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3650 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3651 "mbufs refcnts not as expected");
3653 free_mbufs(&pkts_burst[tx_count],
3654 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3656 /* Clean up and remove slaves from bonded device */
3657 return remove_slaves_and_stop_bonded_device();
3660 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3663 test_broadcast_rx_burst(void)
3665 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3667 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3668 struct rte_eth_stats port_stats;
3670 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3673 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3675 /* Initialize bonded device with 4 slaves in round robin mode */
3676 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3677 BONDING_MODE_BROADCAST, 0, 3, 1),
3678 "Failed to intialise bonded device");
3680 /* Generate test bursts of packets to transmit */
3681 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3682 TEST_ASSERT_EQUAL(generate_test_burst(
3683 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3684 burst_size[i], "failed to generate packet burst");
3687 /* Add rx data to slave 0 */
3688 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3689 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3690 &gen_pkt_burst[i][0], burst_size[i]);
3694 /* Call rx burst on bonded device */
3695 /* Send burst on bonded port */
3696 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3697 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3698 burst_size[0] + burst_size[1] + burst_size[2],
3701 /* Verify bonded device rx count */
3702 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3703 TEST_ASSERT_EQUAL(port_stats.ipackets,
3704 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3705 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3706 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3707 burst_size[0] + burst_size[1] + burst_size[2]);
3710 /* Verify bonded slave devices rx counts */
3711 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3712 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3713 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3714 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3717 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3718 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3719 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3720 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3723 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3724 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3725 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3726 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3729 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3730 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3731 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3732 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3735 /* free mbufs allocate for rx testing */
3736 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3737 for (j = 0; j < MAX_PKT_BURST; j++) {
3738 if (gen_pkt_burst[i][j] != NULL) {
3739 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3740 gen_pkt_burst[i][j] = NULL;
3745 /* Clean up and remove slaves from bonded device */
3746 return remove_slaves_and_stop_bonded_device();
3750 test_broadcast_verify_promiscuous_enable_disable(void)
3754 /* Initialize bonded device with 4 slaves in round robin mode */
3755 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3756 BONDING_MODE_BROADCAST, 0, 4, 1),
3757 "Failed to intialise bonded device");
3759 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3762 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3763 "Port (%d) promiscuous mode not enabled",
3764 test_params->bonded_port_id);
3766 for (i = 0; i < test_params->bonded_slave_count; i++) {
3767 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3768 test_params->slave_port_ids[i]), 1,
3769 "Port (%d) promiscuous mode not enabled",
3770 test_params->slave_port_ids[i]);
3773 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3775 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3776 "Port (%d) promiscuous mode not disabled",
3777 test_params->bonded_port_id);
3779 for (i = 0; i < test_params->bonded_slave_count; i++) {
3780 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3781 test_params->slave_port_ids[i]), 0,
3782 "Port (%d) promiscuous mode not disabled",
3783 test_params->slave_port_ids[i]);
3786 /* Clean up and remove slaves from bonded device */
3787 return remove_slaves_and_stop_bonded_device();
3791 test_broadcast_verify_mac_assignment(void)
3793 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3797 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3798 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3800 /* Initialize bonded device with 4 slaves in round robin mode */
3801 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3802 BONDING_MODE_BROADCAST, 0, 4, 1),
3803 "Failed to intialise bonded device");
3805 /* Verify that all MACs are the same as first slave added to bonded
3807 for (i = 0; i < test_params->bonded_slave_count; i++) {
3808 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3809 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3810 sizeof(read_mac_addr)),
3811 "slave port (%d) mac address not set to that of primary port",
3812 test_params->slave_port_ids[i]);
3815 /* change primary and verify that MAC addresses haven't changed */
3816 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3817 test_params->slave_port_ids[2]),
3818 "Failed to set bonded port (%d) primary port to (%d)",
3819 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3821 for (i = 0; i < test_params->bonded_slave_count; i++) {
3822 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3823 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3824 sizeof(read_mac_addr)),
3825 "slave port (%d) mac address has changed to that of primary "
3826 "port without stop/start toggle of bonded device",
3827 test_params->slave_port_ids[i]);
3830 /* stop / start bonded device and verify that primary MAC address is
3831 * propagated to bonded device and slaves */
3833 rte_eth_dev_stop(test_params->bonded_port_id);
3835 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3836 "Failed to start bonded device");
3838 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3839 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3840 sizeof(read_mac_addr)),
3841 "bonded port (%d) mac address not set to that of new primary port",
3842 test_params->slave_port_ids[i]);
3844 for (i = 0; i < test_params->bonded_slave_count; i++) {
3845 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3846 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3847 sizeof(read_mac_addr)),
3848 "slave port (%d) mac address not set to that of new primary "
3849 "port", test_params->slave_port_ids[i]);
3852 /* Set explicit MAC address */
3853 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3854 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3855 "Failed to set MAC address");
3857 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3858 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3859 sizeof(read_mac_addr)),
3860 "bonded port (%d) mac address not set to that of new primary port",
3861 test_params->slave_port_ids[i]);
3864 for (i = 0; i < test_params->bonded_slave_count; i++) {
3865 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3866 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3867 sizeof(read_mac_addr)),
3868 "slave port (%d) mac address not set to that of new primary "
3869 "port", test_params->slave_port_ids[i]);
3872 /* Clean up and remove slaves from bonded device */
3873 return remove_slaves_and_stop_bonded_device();
3876 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3878 test_broadcast_verify_slave_link_status_change_behaviour(void)
3880 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3881 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3882 struct rte_eth_stats port_stats;
3884 uint8_t slaves[RTE_MAX_ETHPORTS];
3886 int i, j, burst_size, slave_count;
3888 memset(pkt_burst, 0, sizeof(pkt_burst));
3890 /* Initialize bonded device with 4 slaves in round robin mode */
3891 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3892 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3893 1), "Failed to intialise bonded device");
3895 /* Verify Current Slaves Count /Active Slave Count is */
3896 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3898 TEST_ASSERT_EQUAL(slave_count, 4,
3899 "Number of slaves (%d) is not as expected (%d).",
3902 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3903 slaves, RTE_MAX_ETHPORTS);
3904 TEST_ASSERT_EQUAL(slave_count, 4,
3905 "Number of active slaves (%d) is not as expected (%d).",
3908 /* Set 2 slaves link status to down */
3909 virtual_ethdev_simulate_link_status_interrupt(
3910 test_params->slave_port_ids[1], 0);
3911 virtual_ethdev_simulate_link_status_interrupt(
3912 test_params->slave_port_ids[3], 0);
3914 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3915 slaves, RTE_MAX_ETHPORTS);
3916 TEST_ASSERT_EQUAL(slave_count, 2,
3917 "Number of active slaves (%d) is not as expected (%d).",
3920 for (i = 0; i < test_params->bonded_slave_count; i++)
3921 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3923 /* Verify that pkts are not sent on slaves with link status down */
3926 TEST_ASSERT_EQUAL(generate_test_burst(
3927 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3928 "generate_test_burst failed");
3930 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3931 &pkt_burst[0][0], burst_size), burst_size,
3932 "rte_eth_tx_burst failed\n");
3934 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3935 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3936 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3937 test_params->bonded_port_id, (int)port_stats.opackets,
3938 burst_size * slave_count);
3940 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3941 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3942 "(%d) port_stats.opackets not as expected",
3943 test_params->slave_port_ids[0]);
3945 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3946 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3947 "(%d) port_stats.opackets not as expected",
3948 test_params->slave_port_ids[1]);
3950 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3951 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3952 "(%d) port_stats.opackets not as expected",
3953 test_params->slave_port_ids[2]);
3956 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3957 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3958 "(%d) port_stats.opackets not as expected",
3959 test_params->slave_port_ids[3]);
3962 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3963 TEST_ASSERT_EQUAL(generate_test_burst(
3964 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3965 burst_size, "failed to generate packet burst");
3967 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3968 &pkt_burst[i][0], burst_size);
3971 /* Verify that pkts are not received on slaves with link status down */
3972 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3973 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3974 burst_size + burst_size, "rte_eth_rx_burst failed");
3977 /* Verify bonded device rx count */
3978 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3979 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3980 "(%d) port_stats.ipackets not as expected\n",
3981 test_params->bonded_port_id);
3983 /* free mbufs allocate for rx testing */
3984 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3985 for (j = 0; j < MAX_PKT_BURST; j++) {
3986 if (pkt_burst[i][j] != NULL) {
3987 rte_pktmbuf_free(pkt_burst[i][j]);
3988 pkt_burst[i][j] = NULL;
3993 /* Clean up and remove slaves from bonded device */
3994 return remove_slaves_and_stop_bonded_device();
3998 test_reconfigure_bonded_device(void)
4000 test_params->nb_rx_q = 4;
4001 test_params->nb_tx_q = 4;
4003 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4004 "failed to reconfigure bonded device");
4006 test_params->nb_rx_q = 2;
4007 test_params->nb_tx_q = 2;
4009 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4010 "failed to reconfigure bonded device with less rx/tx queues");
4017 test_close_bonded_device(void)
4019 rte_eth_dev_close(test_params->bonded_port_id);
4024 testsuite_teardown(void)
4026 free(test_params->pkt_eth_hdr);
4027 test_params->pkt_eth_hdr = NULL;
4029 /* Clean up and remove slaves from bonded device */
4030 remove_slaves_and_stop_bonded_device();
4034 free_virtualpmd_tx_queue(void)
4036 int i, slave_port, to_free_cnt;
4037 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4039 /* Free tx queue of virtual pmd */
4040 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4042 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4043 test_params->slave_port_ids[slave_port],
4044 pkts_to_free, MAX_PKT_BURST);
4045 for (i = 0; i < to_free_cnt; i++)
4046 rte_pktmbuf_free(pkts_to_free[i]);
4051 test_tlb_tx_burst(void)
4053 int i, burst_size, nb_tx;
4054 uint64_t nb_tx2 = 0;
4055 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4056 struct rte_eth_stats port_stats[32];
4057 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4060 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4061 (BONDING_MODE_TLB, 1, 3, 1),
4062 "Failed to initialise bonded device");
4064 burst_size = 20 * test_params->bonded_slave_count;
4066 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4067 "Burst size specified is greater than supported.\n");
4070 /* Generate bursts of packets */
4071 for (i = 0; i < 400000; i++) {
4072 /*test two types of mac src own(bonding) and others */
4074 initialize_eth_header(test_params->pkt_eth_hdr,
4075 (struct ether_addr *)src_mac,
4076 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4078 initialize_eth_header(test_params->pkt_eth_hdr,
4079 (struct ether_addr *)test_params->default_slave_mac,
4080 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4082 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4084 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4085 dst_addr_0, pktlen);
4086 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4087 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4088 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4089 /* Send burst on bonded port */
4090 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4094 free_virtualpmd_tx_queue();
4096 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4097 "number of packet not equal burst size");
4103 /* Verify bonded port tx stats */
4104 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4106 all_bond_opackets = port_stats[0].opackets;
4107 all_bond_obytes = port_stats[0].obytes;
4109 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4110 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4111 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4115 /* Verify slave ports tx stats */
4116 for (i = 0; i < test_params->bonded_slave_count; i++) {
4117 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4118 sum_ports_opackets += port_stats[i].opackets;
4121 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4122 "Total packets sent by slaves is not equal to packets sent by bond interface");
4124 /* checking if distribution of packets is balanced over slaves */
4125 for (i = 0; i < test_params->bonded_slave_count; i++) {
4126 TEST_ASSERT(port_stats[i].obytes > 0 &&
4127 port_stats[i].obytes < all_bond_obytes,
4128 "Packets are not balanced over slaves");
4131 /* Put all slaves down and try and transmit */
4132 for (i = 0; i < test_params->bonded_slave_count; i++) {
4133 virtual_ethdev_simulate_link_status_interrupt(
4134 test_params->slave_port_ids[i], 0);
4137 /* Send burst on bonded port */
4138 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4140 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4142 /* Clean ugit checkout masterp and remove slaves from bonded device */
4143 return remove_slaves_and_stop_bonded_device();
4146 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4149 test_tlb_rx_burst(void)
4151 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4152 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4154 struct rte_eth_stats port_stats;
4158 uint16_t i, j, nb_rx, burst_size = 17;
4160 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4161 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4163 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4164 "Failed to initialize bonded device");
4167 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4168 TEST_ASSERT(primary_port >= 0,
4169 "failed to get primary slave for bonded port (%d)",
4170 test_params->bonded_port_id);
4172 for (i = 0; i < test_params->bonded_slave_count; i++) {
4173 /* Generate test bursts of packets to transmit */
4174 TEST_ASSERT_EQUAL(generate_test_burst(
4175 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4176 "burst generation failed");
4178 /* Add rx data to slave */
4179 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4180 &gen_pkt_burst[0], burst_size);
4182 /* Call rx burst on bonded device */
4183 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4184 &rx_pkt_burst[0], MAX_PKT_BURST);
4186 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4188 if (test_params->slave_port_ids[i] == primary_port) {
4189 /* Verify bonded device rx count */
4190 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4191 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4192 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4193 test_params->bonded_port_id,
4194 (unsigned int)port_stats.ipackets, burst_size);
4196 /* Verify bonded slave devices rx count */
4197 for (j = 0; j < test_params->bonded_slave_count; j++) {
4198 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4200 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4201 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4202 test_params->slave_port_ids[i],
4203 (unsigned int)port_stats.ipackets, burst_size);
4205 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4206 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4207 test_params->slave_port_ids[i],
4208 (unsigned int)port_stats.ipackets, 0);
4212 for (j = 0; j < test_params->bonded_slave_count; j++) {
4213 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4214 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4215 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4216 test_params->slave_port_ids[i],
4217 (unsigned int)port_stats.ipackets, 0);
4222 for (i = 0; i < burst_size; i++)
4223 rte_pktmbuf_free(rx_pkt_burst[i]);
4225 /* reset bonded device stats */
4226 rte_eth_stats_reset(test_params->bonded_port_id);
4229 /* Clean up and remove slaves from bonded device */
4230 return remove_slaves_and_stop_bonded_device();
4234 test_tlb_verify_promiscuous_enable_disable(void)
4236 int i, primary_port, promiscuous_en;
4238 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4239 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4240 BONDING_MODE_TLB, 0, 4, 1),
4241 "Failed to initialize bonded device");
4243 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4244 TEST_ASSERT(primary_port >= 0,
4245 "failed to get primary slave for bonded port (%d)",
4246 test_params->bonded_port_id);
4248 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4250 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4251 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4252 "Port (%d) promiscuous mode not enabled\n",
4253 test_params->bonded_port_id);
4254 for (i = 0; i < test_params->bonded_slave_count; i++) {
4255 promiscuous_en = rte_eth_promiscuous_get(
4256 test_params->slave_port_ids[i]);
4257 if (primary_port == test_params->slave_port_ids[i]) {
4258 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4259 "Port (%d) promiscuous mode not enabled\n",
4260 test_params->bonded_port_id);
4262 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4263 "Port (%d) promiscuous mode enabled\n",
4264 test_params->bonded_port_id);
4269 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4271 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4272 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4273 "Port (%d) promiscuous mode not disabled\n",
4274 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 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4280 "slave port (%d) promiscuous mode not disabled\n",
4281 test_params->slave_port_ids[i]);
4284 /* Clean up and remove slaves from bonded device */
4285 return remove_slaves_and_stop_bonded_device();
4289 test_tlb_verify_mac_assignment(void)
4291 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4293 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4294 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4296 /* Initialize bonded device with 2 slaves in active backup mode */
4297 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4298 BONDING_MODE_TLB, 0, 2, 1),
4299 "Failed to initialize bonded device");
4301 /* Verify that bonded MACs is that of first slave and that the other slave
4302 * MAC hasn't been changed */
4303 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4304 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4305 sizeof(read_mac_addr)),
4306 "bonded port (%d) mac address not set to that of primary port",
4307 test_params->bonded_port_id);
4309 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4311 sizeof(read_mac_addr)),
4312 "slave port (%d) mac address not set to that of primary port",
4313 test_params->slave_port_ids[0]);
4315 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4317 sizeof(read_mac_addr)),
4318 "slave port (%d) mac address not as expected",
4319 test_params->slave_port_ids[1]);
4321 /* change primary and verify that MAC addresses haven't changed */
4322 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4323 test_params->slave_port_ids[1]), 0,
4324 "Failed to set bonded port (%d) primary port to (%d)",
4325 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4327 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4328 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4329 sizeof(read_mac_addr)),
4330 "bonded port (%d) mac address not set to that of primary port",
4331 test_params->bonded_port_id);
4333 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4335 sizeof(read_mac_addr)),
4336 "slave port (%d) mac address not set to that of primary port",
4337 test_params->slave_port_ids[0]);
4339 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4340 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4341 sizeof(read_mac_addr)),
4342 "slave port (%d) mac address not as expected",
4343 test_params->slave_port_ids[1]);
4345 /* stop / start bonded device and verify that primary MAC address is
4346 * propagated to bonded device and slaves */
4348 rte_eth_dev_stop(test_params->bonded_port_id);
4350 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4351 "Failed to start device");
4353 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4354 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4355 sizeof(read_mac_addr)),
4356 "bonded port (%d) mac address not set to that of primary port",
4357 test_params->bonded_port_id);
4359 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4361 sizeof(read_mac_addr)),
4362 "slave port (%d) mac address not as expected",
4363 test_params->slave_port_ids[0]);
4365 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4367 sizeof(read_mac_addr)),
4368 "slave port (%d) mac address not set to that of primary port",
4369 test_params->slave_port_ids[1]);
4372 /* Set explicit MAC address */
4373 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4374 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4375 "failed to set MAC addres");
4377 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4378 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4379 sizeof(read_mac_addr)),
4380 "bonded port (%d) mac address not set to that of bonded port",
4381 test_params->bonded_port_id);
4383 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4384 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4385 sizeof(read_mac_addr)),
4386 "slave port (%d) mac address not as expected",
4387 test_params->slave_port_ids[0]);
4389 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4390 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4391 sizeof(read_mac_addr)),
4392 "slave port (%d) mac address not set to that of bonded port",
4393 test_params->slave_port_ids[1]);
4395 /* Clean up and remove slaves from bonded device */
4396 return remove_slaves_and_stop_bonded_device();
4400 test_tlb_verify_slave_link_status_change_failover(void)
4402 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4403 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4404 struct rte_eth_stats port_stats;
4406 uint8_t slaves[RTE_MAX_ETHPORTS];
4408 int i, j, burst_size, slave_count, primary_port;
4412 memset(pkt_burst, 0, sizeof(pkt_burst));
4416 /* Initialize bonded device with 4 slaves in round robin mode */
4417 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4418 BONDING_MODE_TLB, 0,
4419 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4420 "Failed to initialize bonded device with slaves");
4422 /* Verify Current Slaves Count /Active Slave Count is */
4423 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4425 TEST_ASSERT_EQUAL(slave_count, 4,
4426 "Number of slaves (%d) is not as expected (%d).\n",
4429 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4430 slaves, RTE_MAX_ETHPORTS);
4431 TEST_ASSERT_EQUAL(slave_count, (int)4,
4432 "Number of slaves (%d) is not as expected (%d).\n",
4435 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4436 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4437 "Primary port not as expected");
4439 /* Bring 2 slaves down and verify active slave count */
4440 virtual_ethdev_simulate_link_status_interrupt(
4441 test_params->slave_port_ids[1], 0);
4442 virtual_ethdev_simulate_link_status_interrupt(
4443 test_params->slave_port_ids[3], 0);
4445 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4446 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4447 "Number of active slaves (%d) is not as expected (%d).",
4450 virtual_ethdev_simulate_link_status_interrupt(
4451 test_params->slave_port_ids[1], 1);
4452 virtual_ethdev_simulate_link_status_interrupt(
4453 test_params->slave_port_ids[3], 1);
4456 /* Bring primary port down, verify that active slave count is 3 and primary
4458 virtual_ethdev_simulate_link_status_interrupt(
4459 test_params->slave_port_ids[0], 0);
4461 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4462 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4463 "Number of active slaves (%d) is not as expected (%d).",
4466 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4467 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4468 "Primary port not as expected");
4469 rte_delay_us(500000);
4470 /* Verify that pkts are sent on new primary slave */
4471 for (i = 0; i < 4; i++) {
4472 TEST_ASSERT_EQUAL(generate_test_burst(
4473 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4474 "generate_test_burst failed\n");
4475 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4476 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4477 "rte_eth_tx_burst failed\n");
4478 rte_delay_us(11000);
4481 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4482 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4483 "(%d) port_stats.opackets not as expected\n",
4484 test_params->slave_port_ids[0]);
4486 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4487 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4488 "(%d) port_stats.opackets not as expected\n",
4489 test_params->slave_port_ids[1]);
4491 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4492 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4493 "(%d) port_stats.opackets not as expected\n",
4494 test_params->slave_port_ids[2]);
4496 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4497 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4498 "(%d) port_stats.opackets not as expected\n",
4499 test_params->slave_port_ids[3]);
4502 /* Generate packet burst for testing */
4504 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4505 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4509 virtual_ethdev_add_mbufs_to_rx_queue(
4510 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4513 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4514 MAX_PKT_BURST) != burst_size) {
4515 printf("rte_eth_rx_burst\n");
4520 /* Verify bonded device rx count */
4521 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4522 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4523 "(%d) port_stats.ipackets not as expected\n",
4524 test_params->bonded_port_id);
4528 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4529 for (j = 0; j < MAX_PKT_BURST; j++) {
4530 if (pkt_burst[i][j] != NULL) {
4531 rte_pktmbuf_free(pkt_burst[i][j]);
4532 pkt_burst[i][j] = NULL;
4538 /* Clean up and remove slaves from bonded device */
4539 return remove_slaves_and_stop_bonded_device();
4542 #define TEST_ALB_SLAVE_COUNT 2
4544 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4545 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4546 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4547 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4549 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4550 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4551 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4552 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4553 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4556 test_alb_change_mac_in_reply_sent(void)
4558 struct rte_mbuf *pkt;
4559 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4561 struct ether_hdr *eth_pkt;
4562 struct arp_hdr *arp_pkt;
4564 int slave_idx, nb_pkts, pkt_idx;
4567 struct ether_addr bond_mac, client_mac;
4568 struct ether_addr *slave_mac1, *slave_mac2;
4570 TEST_ASSERT_SUCCESS(
4571 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4572 0, TEST_ALB_SLAVE_COUNT, 1),
4573 "Failed to initialize_bonded_device_with_slaves.");
4575 /* Flush tx queue */
4576 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4577 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4579 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4580 test_params->slave_port_ids[slave_idx], pkts_sent,
4585 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4589 * Generating four packets with different mac and ip addresses and sending
4590 * them through the bonding port.
4592 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4593 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4594 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4595 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4597 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4598 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4600 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4602 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4603 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4604 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4605 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4607 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4608 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4610 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4612 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4613 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4614 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4615 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4617 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4618 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4620 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4622 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4623 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4624 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4625 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4627 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4628 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4630 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4633 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4635 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4638 * Checking if packets are properly distributed on bonding ports. Packets
4639 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4641 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4642 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4643 test_params->slave_port_ids[slave_idx], pkts_sent,
4646 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4647 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4648 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4650 if (slave_idx%2 == 0) {
4651 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4656 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4665 retval += remove_slaves_and_stop_bonded_device();
4670 test_alb_reply_from_client(void)
4672 struct ether_hdr *eth_pkt;
4673 struct arp_hdr *arp_pkt;
4675 struct rte_mbuf *pkt;
4676 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4678 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4681 struct ether_addr bond_mac, client_mac;
4682 struct ether_addr *slave_mac1, *slave_mac2;
4684 TEST_ASSERT_SUCCESS(
4685 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4686 0, TEST_ALB_SLAVE_COUNT, 1),
4687 "Failed to initialize_bonded_device_with_slaves.");
4689 /* Flush tx queue */
4690 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4691 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4692 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4693 test_params->slave_port_ids[slave_idx], pkts_sent,
4698 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4702 * Generating four packets with different mac and ip addresses and placing
4703 * them in the rx queue to be received by the bonding driver on rx_burst.
4705 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4706 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4707 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4708 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4710 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4711 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4713 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4716 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4717 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4718 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4719 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4721 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4722 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4724 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4727 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4728 memcpy(client_mac.addr_bytes, mac_client3, 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_client3, 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_client4, 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_client4, ip_host,
4746 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4750 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4751 * packets to every client in alb table.
4753 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4754 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4756 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4757 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4760 * Checking if update ARP packets were properly send on slave ports.
4762 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4763 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4764 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4765 nb_pkts_sum += nb_pkts;
4767 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4768 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4769 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4771 if (slave_idx%2 == 0) {
4772 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4777 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4785 /* Check if proper number of packets was send */
4786 if (nb_pkts_sum < 4) {
4792 retval += remove_slaves_and_stop_bonded_device();
4797 test_alb_receive_vlan_reply(void)
4799 struct ether_hdr *eth_pkt;
4800 struct vlan_hdr *vlan_pkt;
4801 struct arp_hdr *arp_pkt;
4803 struct rte_mbuf *pkt;
4804 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4806 int slave_idx, nb_pkts, pkt_idx;
4809 struct ether_addr bond_mac, client_mac;
4811 TEST_ASSERT_SUCCESS(
4812 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4813 0, TEST_ALB_SLAVE_COUNT, 1),
4814 "Failed to initialize_bonded_device_with_slaves.");
4816 /* Flush tx queue */
4817 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4818 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4819 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4820 test_params->slave_port_ids[slave_idx], pkts_sent,
4825 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4829 * Generating packet with double VLAN header and placing it in the rx queue.
4831 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4832 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4833 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4834 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4836 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4837 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4838 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4839 vlan_pkt = vlan_pkt+1;
4840 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4841 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4842 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4843 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4845 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4848 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4849 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4852 * Checking if VLAN headers in generated ARP Update packet are correct.
4854 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4855 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4856 test_params->slave_port_ids[slave_idx], pkts_sent,
4859 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4860 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4861 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4862 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4866 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4870 vlan_pkt = vlan_pkt+1;
4871 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4875 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4883 retval += remove_slaves_and_stop_bonded_device();
4888 test_alb_ipv4_tx(void)
4890 int burst_size, retval, pkts_send;
4891 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4895 TEST_ASSERT_SUCCESS(
4896 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4897 0, TEST_ALB_SLAVE_COUNT, 1),
4898 "Failed to initialize_bonded_device_with_slaves.");
4902 /* Generate test bursts of packets to transmit */
4903 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4909 * Checking if ipv4 traffic is transmitted via TLB policy.
4911 pkts_send = rte_eth_tx_burst(
4912 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4913 if (pkts_send != burst_size) {
4919 retval += remove_slaves_and_stop_bonded_device();
4923 static struct unit_test_suite link_bonding_test_suite = {
4924 .suite_name = "Link Bonding Unit Test Suite",
4925 .setup = test_setup,
4926 .teardown = testsuite_teardown,
4927 .unit_test_cases = {
4928 TEST_CASE(test_create_bonded_device),
4929 TEST_CASE(test_create_bonded_device_with_invalid_params),
4930 TEST_CASE(test_add_slave_to_bonded_device),
4931 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4932 TEST_CASE(test_remove_slave_from_bonded_device),
4933 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4934 TEST_CASE(test_get_slaves_from_bonded_device),
4935 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4936 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4937 TEST_CASE(test_start_bonded_device),
4938 TEST_CASE(test_stop_bonded_device),
4939 TEST_CASE(test_set_bonding_mode),
4940 TEST_CASE(test_set_primary_slave),
4941 TEST_CASE(test_set_explicit_bonded_mac),
4942 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4943 TEST_CASE(test_status_interrupt),
4944 TEST_CASE(test_adding_slave_after_bonded_device_started),
4945 TEST_CASE(test_roundrobin_tx_burst),
4946 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4947 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4948 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4949 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4950 TEST_CASE(test_roundrobin_verify_mac_assignment),
4951 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4952 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4953 TEST_CASE(test_activebackup_tx_burst),
4954 TEST_CASE(test_activebackup_rx_burst),
4955 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4956 TEST_CASE(test_activebackup_verify_mac_assignment),
4957 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4958 TEST_CASE(test_balance_xmit_policy_configuration),
4959 TEST_CASE(test_balance_l2_tx_burst),
4960 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4961 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4962 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4963 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4964 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4965 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4966 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4967 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4968 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4969 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4970 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4971 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4972 TEST_CASE(test_balance_rx_burst),
4973 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4974 TEST_CASE(test_balance_verify_mac_assignment),
4975 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4976 TEST_CASE(test_tlb_tx_burst),
4977 TEST_CASE(test_tlb_rx_burst),
4978 TEST_CASE(test_tlb_verify_mac_assignment),
4979 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4980 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4981 TEST_CASE(test_alb_change_mac_in_reply_sent),
4982 TEST_CASE(test_alb_reply_from_client),
4983 TEST_CASE(test_alb_receive_vlan_reply),
4984 TEST_CASE(test_alb_ipv4_tx),
4985 TEST_CASE(test_broadcast_tx_burst),
4986 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4987 TEST_CASE(test_broadcast_rx_burst),
4988 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4989 TEST_CASE(test_broadcast_verify_mac_assignment),
4990 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4991 TEST_CASE(test_reconfigure_bonded_device),
4992 TEST_CASE(test_close_bonded_device),
4994 TEST_CASES_END() /**< NULL terminate unit test array */
5000 test_link_bonding(void)
5002 return unit_test_suite_runner(&link_bonding_test_suite);
5005 static struct test_command link_bonding_cmd = {
5006 .command = "link_bonding_autotest",
5007 .callback = test_link_bonding,
5009 REGISTER_TEST_COMMAND(link_bonding_cmd);