4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/queue.h>
44 #include <rte_cycles.h>
45 #include <rte_byteorder.h>
46 #include <rte_common.h>
47 #include <rte_debug.h>
48 #include <rte_ethdev.h>
50 #include <rte_lcore.h>
51 #include <rte_memory.h>
52 #include <rte_string_fns.h>
53 #include <rte_eth_bond.h>
55 #include "virtual_pmd.h"
56 #include "packet_burst_generator.h"
60 #define TEST_MAX_NUMBER_OF_PORTS (6)
62 #define RX_RING_SIZE 128
63 #define RX_FREE_THRESH 32
68 #define TX_RING_SIZE 512
69 #define TX_FREE_THRESH 32
73 #define TX_RSBIT_THRESH 32
74 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
75 ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
76 ETH_TXQ_FLAGS_NOXSUMTCP)
78 #define MBUF_PAYLOAD_SIZE (2048)
79 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
80 #define MBUF_CACHE_SIZE (250)
81 #define BURST_SIZE (32)
83 #define DEFAULT_MBUF_DATA_SIZE (2048)
84 #define RTE_TEST_RX_DESC_MAX (2048)
85 #define RTE_TEST_TX_DESC_MAX (2048)
86 #define MAX_PKT_BURST (512)
87 #define DEF_PKT_BURST (16)
89 #define BONDED_DEV_NAME ("unit_test_bonded_device")
91 #define INVALID_SOCKET_ID (-1)
92 #define INVALID_PORT_ID (-1)
93 #define INVALID_BONDING_MODE (-1)
96 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
97 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
99 struct link_bonding_unittest_params {
100 int8_t bonded_port_id;
101 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
102 uint8_t bonded_slave_count;
103 uint8_t bonding_mode;
108 struct rte_mempool *mbuf_pool;
110 struct ether_addr *default_slave_mac;
111 struct ether_addr *default_bonded_mac;
114 struct ether_hdr *pkt_eth_hdr;
115 struct ipv4_hdr *pkt_ipv4_hdr;
116 struct ipv6_hdr *pkt_ipv6_hdr;
117 struct udp_hdr *pkt_udp_hdr;
121 static struct ipv4_hdr pkt_ipv4_hdr;
122 static struct ipv6_hdr pkt_ipv6_hdr;
123 static struct udp_hdr pkt_udp_hdr;
125 static struct link_bonding_unittest_params default_params = {
126 .bonded_port_id = -1,
127 .slave_port_ids = { -1 },
128 .bonded_slave_count = 0,
129 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
136 .default_slave_mac = (struct ether_addr *)slave_mac,
137 .default_bonded_mac = (struct ether_addr *)bonded_mac,
140 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
141 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
142 .pkt_udp_hdr = &pkt_udp_hdr
146 static struct link_bonding_unittest_params *test_params = &default_params;
148 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
150 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
152 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
154 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
156 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
157 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
158 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
159 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
160 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
161 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
163 static uint16_t src_port = 1024;
164 static uint16_t dst_port_0 = 1024;
165 static uint16_t dst_port_1 = 2024;
167 static uint16_t vlan_id = 0x100;
169 struct rte_eth_rxmode rx_mode = {
170 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
172 .header_split = 0, /**< Header Split disabled. */
173 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
174 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
175 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
176 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
177 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
178 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
181 struct rte_fdir_conf fdir_conf = {
182 .mode = RTE_FDIR_MODE_NONE,
183 .pballoc = RTE_FDIR_PBALLOC_64K,
184 .status = RTE_FDIR_REPORT_STATUS,
188 static struct rte_eth_conf default_pmd_conf = {
190 .mq_mode = ETH_MQ_RX_NONE,
191 .max_rx_pkt_len = ETHER_MAX_LEN,
193 .header_split = 0, /**< Header Split disabled */
194 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
195 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
196 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
197 .hw_strip_crc = 0, /**< CRC stripped by hardware */
200 .mq_mode = ETH_MQ_TX_NONE,
205 static const struct rte_eth_rxconf rx_conf_default = {
207 .pthresh = RX_PTHRESH,
208 .hthresh = RX_HTHRESH,
209 .wthresh = RX_WTHRESH,
211 .rx_free_thresh = RX_FREE_THRESH,
215 static struct rte_eth_txconf tx_conf_default = {
217 .pthresh = TX_PTHRESH,
218 .hthresh = TX_HTHRESH,
219 .wthresh = TX_WTHRESH,
221 .tx_free_thresh = TX_FREE_THRESH,
222 .tx_rs_thresh = TX_RSBIT_THRESH,
223 .txq_flags = TX_Q_FLAGS
228 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
233 default_pmd_conf.intr_conf.lsc = 1;
235 default_pmd_conf.intr_conf.lsc = 0;
237 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
238 test_params->nb_tx_q, &default_pmd_conf),
239 "rte_eth_dev_configure for port %d failed", port_id);
241 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
242 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
243 rte_eth_dev_socket_id(port_id), &rx_conf_default,
244 test_params->mbuf_pool) ,
245 "rte_eth_rx_queue_setup for port %d failed", port_id);
247 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
248 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
249 rte_eth_dev_socket_id(port_id), &tx_conf_default),
250 "rte_eth_tx_queue_setup for port %d failed", port_id);
253 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
254 "rte_eth_dev_start for port %d failed", port_id);
259 static int slaves_initialized;
261 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
262 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
268 int i, nb_mbuf_per_pool;
269 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
271 /* Allocate ethernet packet header with space for VLAN header */
272 if (test_params->pkt_eth_hdr == NULL) {
273 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
274 sizeof(struct vlan_hdr));
276 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
277 "Ethernet header struct allocation failed!");
280 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
281 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
282 if (test_params->mbuf_pool == NULL) {
283 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
284 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
285 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
287 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
288 "rte_mempool_create failed");
291 /* Create / Initialize virtual eth devs */
292 if (!slaves_initialized) {
293 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
294 char pmd_name[RTE_ETH_NAME_MAX_LEN];
296 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
298 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
300 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
301 mac_addr, rte_socket_id(), 1);
302 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
303 "Failed to create virtual virtual ethdev %s", pmd_name);
305 TEST_ASSERT_SUCCESS(configure_ethdev(
306 test_params->slave_port_ids[i], 1, 0),
307 "Failed to configure virtual ethdev %s", pmd_name);
309 slaves_initialized = 1;
316 test_create_bonded_device(void)
318 int current_slave_count;
320 uint8_t slaves[RTE_MAX_ETHPORTS];
322 /* Don't try to recreate bonded device if re-running test suite*/
323 if (test_params->bonded_port_id == -1) {
324 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
325 test_params->bonding_mode, rte_socket_id());
327 TEST_ASSERT(test_params->bonded_port_id >= 0,
328 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
330 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
331 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
334 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
335 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
336 test_params->bonded_port_id, test_params->bonding_mode);
338 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
339 slaves, RTE_MAX_ETHPORTS);
341 TEST_ASSERT_EQUAL(current_slave_count, 0,
342 "Number of slaves %d is great than expected %d.",
343 current_slave_count, 0);
345 current_slave_count = rte_eth_bond_active_slaves_get(
346 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
348 TEST_ASSERT_EQUAL(current_slave_count, 0,
349 "Number of active slaves %d is great than expected %d.",
350 current_slave_count, 0);
357 test_create_bonded_device_with_invalid_params(void)
361 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
364 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
366 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
368 test_params->bonding_mode = INVALID_BONDING_MODE;
370 /* Invalid bonding mode */
371 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
373 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
375 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
377 /* Invalid socket id */
378 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
380 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
386 test_add_slave_to_bonded_device(void)
388 int current_slave_count;
390 uint8_t slaves[RTE_MAX_ETHPORTS];
392 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
393 test_params->slave_port_ids[test_params->bonded_slave_count]),
394 "Failed to add slave (%d) to bonded port (%d).",
395 test_params->slave_port_ids[test_params->bonded_slave_count],
396 test_params->bonded_port_id);
398 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
399 slaves, RTE_MAX_ETHPORTS);
400 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
401 "Number of slaves (%d) is greater than expected (%d).",
402 current_slave_count, test_params->bonded_slave_count + 1);
404 current_slave_count = rte_eth_bond_active_slaves_get(
405 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
406 TEST_ASSERT_EQUAL(current_slave_count, 0,
407 "Number of active slaves (%d) is not as expected (%d).\n",
408 current_slave_count, 0);
410 test_params->bonded_slave_count++;
416 test_add_slave_to_invalid_bonded_device(void)
418 /* Invalid port ID */
419 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
420 test_params->slave_port_ids[test_params->bonded_slave_count]),
421 "Expected call to failed as invalid port specified.");
423 /* Non bonded device */
424 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
425 test_params->slave_port_ids[test_params->bonded_slave_count]),
426 "Expected call to failed as invalid port specified.");
433 test_remove_slave_from_bonded_device(void)
435 int current_slave_count;
436 struct ether_addr read_mac_addr, *mac_addr;
437 uint8_t slaves[RTE_MAX_ETHPORTS];
439 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
440 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
441 "Failed to remove slave %d from bonded port (%d).",
442 test_params->slave_port_ids[test_params->bonded_slave_count-1],
443 test_params->bonded_port_id);
446 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
447 slaves, RTE_MAX_ETHPORTS);
449 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
450 "Number of slaves (%d) is great than expected (%d).\n",
451 current_slave_count, test_params->bonded_slave_count - 1);
454 mac_addr = (struct ether_addr *)slave_mac;
455 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
456 test_params->bonded_slave_count-1;
459 test_params->slave_port_ids[test_params->bonded_slave_count-1],
461 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
462 "bonded port mac address not set to that of primary port\n");
465 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
467 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
470 test_params->bonded_slave_count--;
476 test_remove_slave_from_invalid_bonded_device(void)
478 /* Invalid port ID */
479 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
480 test_params->bonded_port_id + 5,
481 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
482 "Expected call to failed as invalid port specified.");
484 /* Non bonded device */
485 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
486 test_params->slave_port_ids[0],
487 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
488 "Expected call to failed as invalid port specified.");
493 static int bonded_id = 2;
496 test_add_already_bonded_slave_to_bonded_device(void)
498 int port_id, current_slave_count;
499 uint8_t slaves[RTE_MAX_ETHPORTS];
500 char pmd_name[RTE_ETH_NAME_MAX_LEN];
502 test_add_slave_to_bonded_device();
504 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
505 slaves, RTE_MAX_ETHPORTS);
506 TEST_ASSERT_EQUAL(current_slave_count, 1,
507 "Number of slaves (%d) is not that expected (%d).",
508 current_slave_count, 1);
510 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
512 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
514 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
516 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
517 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
519 "Added slave (%d) to bonded port (%d) unexpectedly.",
520 test_params->slave_port_ids[test_params->bonded_slave_count-1],
523 return test_remove_slave_from_bonded_device();
528 test_get_slaves_from_bonded_device(void)
530 int current_slave_count;
531 uint8_t slaves[RTE_MAX_ETHPORTS];
533 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
534 "Failed to add slave to bonded device");
536 /* Invalid port id */
537 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
539 TEST_ASSERT(current_slave_count < 0,
540 "Invalid port id unexpectedly succeeded");
542 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
543 slaves, RTE_MAX_ETHPORTS);
544 TEST_ASSERT(current_slave_count < 0,
545 "Invalid port id unexpectedly succeeded");
547 /* Invalid slaves pointer */
548 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
549 NULL, RTE_MAX_ETHPORTS);
550 TEST_ASSERT(current_slave_count < 0,
551 "Invalid slave array unexpectedly succeeded");
553 current_slave_count = rte_eth_bond_active_slaves_get(
554 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
555 TEST_ASSERT(current_slave_count < 0,
556 "Invalid slave array unexpectedly succeeded");
558 /* non bonded device*/
559 current_slave_count = rte_eth_bond_slaves_get(
560 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
561 TEST_ASSERT(current_slave_count < 0,
562 "Invalid port id unexpectedly succeeded");
564 current_slave_count = rte_eth_bond_active_slaves_get(
565 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
566 TEST_ASSERT(current_slave_count < 0,
567 "Invalid port id unexpectedly succeeded");
569 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
570 "Failed to remove slaves from bonded device");
577 test_add_remove_multiple_slaves_to_from_bonded_device(void)
581 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
582 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
583 "Failed to add slave to bonded device");
585 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
586 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
587 "Failed to remove slaves from bonded device");
593 enable_bonded_slaves(void)
597 for (i = 0; i < test_params->bonded_slave_count; i++) {
598 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
601 virtual_ethdev_simulate_link_status_interrupt(
602 test_params->slave_port_ids[i], 1);
607 test_start_bonded_device(void)
609 struct rte_eth_link link_status;
611 int current_slave_count, current_bonding_mode, primary_port;
612 uint8_t slaves[RTE_MAX_ETHPORTS];
614 /* Add slave to bonded device*/
615 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
616 "Failed to add slave to bonded device");
618 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
619 "Failed to start bonded pmd eth device %d.",
620 test_params->bonded_port_id);
622 /* Change link status of virtual pmd so it will be added to the active
623 * slave list of the bonded device*/
624 virtual_ethdev_simulate_link_status_interrupt(
625 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
627 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
628 slaves, RTE_MAX_ETHPORTS);
629 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
630 "Number of slaves (%d) is not expected value (%d).",
631 current_slave_count, test_params->bonded_slave_count);
633 current_slave_count = rte_eth_bond_active_slaves_get(
634 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
635 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
636 "Number of active slaves (%d) is not expected value (%d).",
637 current_slave_count, test_params->bonded_slave_count);
639 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
640 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
641 "Bonded device mode (%d) is not expected value (%d).\n",
642 current_bonding_mode, test_params->bonding_mode);
644 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
645 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
646 "Primary port (%d) is not expected value (%d).",
647 primary_port, test_params->slave_port_ids[0]);
649 rte_eth_link_get(test_params->bonded_port_id, &link_status);
650 TEST_ASSERT_EQUAL(link_status.link_status, 1,
651 "Bonded port (%d) status (%d) is not expected value (%d).\n",
652 test_params->bonded_port_id, link_status.link_status, 1);
658 test_stop_bonded_device(void)
660 int current_slave_count;
661 uint8_t slaves[RTE_MAX_ETHPORTS];
663 struct rte_eth_link link_status;
665 rte_eth_dev_stop(test_params->bonded_port_id);
667 rte_eth_link_get(test_params->bonded_port_id, &link_status);
668 TEST_ASSERT_EQUAL(link_status.link_status, 0,
669 "Bonded port (%d) status (%d) is not expected value (%d).",
670 test_params->bonded_port_id, link_status.link_status, 0);
672 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
673 slaves, RTE_MAX_ETHPORTS);
674 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
675 "Number of slaves (%d) is not expected value (%d).",
676 current_slave_count, test_params->bonded_slave_count);
678 current_slave_count = rte_eth_bond_active_slaves_get(
679 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
680 TEST_ASSERT_EQUAL(current_slave_count, 0,
681 "Number of active slaves (%d) is not expected value (%d).",
682 current_slave_count, 0);
688 remove_slaves_and_stop_bonded_device(void)
690 /* Clean up and remove slaves from bonded device */
691 while (test_params->bonded_slave_count > 0)
692 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
693 "test_remove_slave_from_bonded_device failed");
695 rte_eth_dev_stop(test_params->bonded_port_id);
696 rte_eth_stats_reset(test_params->bonded_port_id);
697 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
703 test_set_bonding_mode(void)
707 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
708 BONDING_MODE_ACTIVE_BACKUP,
709 BONDING_MODE_BALANCE,
710 BONDING_MODE_BROADCAST
713 /* Test supported link bonding modes */
714 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
715 /* Invalid port ID */
716 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
718 "Expected call to failed as invalid port (%d) specified.",
721 /* Non bonded device */
722 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
724 "Expected call to failed as invalid port (%d) specified.",
725 test_params->slave_port_ids[0]);
727 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
729 "Failed to set link bonding mode on port (%d) to (%d).",
730 test_params->bonded_port_id, bonding_modes[i]);
732 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
733 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
734 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
735 bonding_mode, test_params->bonded_port_id,
738 /* Invalid port ID */
739 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
740 TEST_ASSERT(bonding_mode < 0,
741 "Expected call to failed as invalid port (%d) specified.",
744 /* Non bonded device */
745 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
746 TEST_ASSERT(bonding_mode < 0,
747 "Expected call to failed as invalid port (%d) specified.",
748 test_params->slave_port_ids[0]);
751 return remove_slaves_and_stop_bonded_device();
755 test_set_primary_slave(void)
758 struct ether_addr read_mac_addr;
759 struct ether_addr *expected_mac_addr;
761 /* Add 4 slaves to bonded device */
762 for (i = test_params->bonded_slave_count; i < 4; i++)
763 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
764 "Failed to add slave to bonded device.");
766 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
767 BONDING_MODE_ROUND_ROBIN),
768 "Failed to set link bonding mode on port (%d) to (%d).",
769 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
771 /* Invalid port ID */
772 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
773 test_params->slave_port_ids[i]),
774 "Expected call to failed as invalid port specified.");
776 /* Non bonded device */
777 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
778 test_params->slave_port_ids[i]),
779 "Expected call to failed as invalid port specified.");
781 /* Set slave as primary
782 * Verify slave it is now primary slave
783 * Verify that MAC address of bonded device is that of primary slave
784 * Verify that MAC address of all bonded slaves are that of primary slave
786 for (i = 0; i < 4; i++) {
787 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
788 test_params->slave_port_ids[i]),
789 "Failed to set bonded port (%d) primary port to (%d)",
790 test_params->bonded_port_id, test_params->slave_port_ids[i]);
792 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
793 TEST_ASSERT(retval >= 0,
794 "Failed to read primary port from bonded port (%d)\n",
795 test_params->bonded_port_id);
797 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
798 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
799 test_params->bonded_port_id, retval,
800 test_params->slave_port_ids[i]);
802 /* stop/start bonded eth dev to apply new MAC */
803 rte_eth_dev_stop(test_params->bonded_port_id);
805 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
806 "Failed to start bonded port %d",
807 test_params->bonded_port_id);
809 expected_mac_addr = (struct ether_addr *)&slave_mac;
810 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
812 /* Check primary slave MAC */
813 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
814 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
815 sizeof(read_mac_addr)),
816 "bonded port mac address not set to that of primary port\n");
818 /* Check bonded MAC */
819 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
820 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
821 sizeof(read_mac_addr)),
822 "bonded port mac address not set to that of primary port\n");
824 /* Check other slaves MACs */
825 for (j = 0; j < 4; j++) {
827 rte_eth_macaddr_get(test_params->slave_port_ids[j],
829 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
830 sizeof(read_mac_addr)),
831 "slave port mac address not set to that of primary "
838 /* Test with none existent port */
839 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
840 "read primary port from expectedly");
842 /* Test with slave port */
843 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
844 "read primary port from expectedly\n");
846 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
847 "Failed to stop and remove slaves from bonded device");
850 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
851 "read primary port from expectedly\n");
857 test_set_explicit_bonded_mac(void)
860 struct ether_addr read_mac_addr;
861 struct ether_addr *mac_addr;
863 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
865 mac_addr = (struct ether_addr *)explicit_bonded_mac;
867 /* Invalid port ID */
868 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
869 "Expected call to failed as invalid port specified.");
871 /* Non bonded device */
872 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
873 test_params->slave_port_ids[0], mac_addr),
874 "Expected call to failed as invalid port specified.");
876 /* NULL MAC address */
877 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
878 test_params->bonded_port_id, NULL),
879 "Expected call to failed as NULL MAC specified");
881 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
882 test_params->bonded_port_id, mac_addr),
883 "Failed to set MAC address on bonded port (%d)",
884 test_params->bonded_port_id);
886 /* Add 4 slaves to bonded device */
887 for (i = test_params->bonded_slave_count; i < 4; i++) {
888 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
889 "Failed to add slave to bonded device.\n");
892 /* Check bonded MAC */
893 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
894 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
895 "bonded port mac address not set to that of primary port");
897 /* Check other slaves MACs */
898 for (i = 0; i < 4; i++) {
899 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
900 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
901 sizeof(read_mac_addr)),
902 "slave port mac address not set to that of primary port");
905 /* test resetting mac address on bonded device */
907 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
908 "Failed to reset MAC address on bonded port (%d)",
909 test_params->bonded_port_id);
912 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
913 "Reset MAC address on bonded port (%d) unexpectedly",
914 test_params->slave_port_ids[1]);
916 /* test resetting mac address on bonded device with no slaves */
917 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
918 "Failed to remove slaves and stop bonded device");
920 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
921 "Failed to reset MAC address on bonded port (%d)",
922 test_params->bonded_port_id);
927 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
930 test_set_bonded_port_initialization_mac_assignment(void)
932 int i, slave_count, bonded_port_id;
934 uint8_t slaves[RTE_MAX_ETHPORTS];
935 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
937 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
939 /* Initialize default values for MAC addresses */
940 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
941 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
944 * 1. a - Create / configure bonded / slave ethdevs
946 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
947 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
948 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
950 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
951 "Failed to configure bonded ethdev");
953 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
954 char pmd_name[RTE_ETH_NAME_MAX_LEN];
956 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
958 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
960 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
961 &slave_mac_addr, rte_socket_id(), 1);
963 TEST_ASSERT(slave_port_ids[i] >= 0,
964 "Failed to create slave ethdev %s", pmd_name);
966 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
967 "Failed to configure virtual ethdev %s",
973 * 2. Add slave ethdevs to bonded device
975 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
976 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
978 "Failed to add slave (%d) to bonded port (%d).",
979 slave_port_ids[i], bonded_port_id);
982 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
984 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
985 "Number of slaves (%d) is not as expected (%d)",
986 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
990 * 3. Set explicit MAC address on bonded ethdev
992 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
993 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
995 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
996 bonded_port_id, &bonded_mac_addr),
997 "Failed to set MAC address on bonded port (%d)",
1001 /* 4. a - Start bonded ethdev
1002 * b - Enable slave devices
1003 * c - Verify bonded/slaves ethdev MAC addresses
1005 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1006 "Failed to start bonded pmd eth device %d.",
1009 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1010 virtual_ethdev_simulate_link_status_interrupt(
1011 slave_port_ids[i], 1);
1014 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1015 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1016 sizeof(read_mac_addr)),
1017 "bonded port mac address not as expected");
1019 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1020 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1021 sizeof(read_mac_addr)),
1022 "slave port 0 mac address not as expected");
1024 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1025 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1026 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1027 sizeof(read_mac_addr)),
1028 "slave port 1 mac address not as expected");
1030 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1031 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1032 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1033 sizeof(read_mac_addr)),
1034 "slave port 2 mac address not as expected");
1037 /* 7. a - Change primary port
1038 * b - Stop / Start bonded port
1039 * d - Verify slave ethdev MAC addresses
1041 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1043 "failed to set primary port on bonded device.");
1045 rte_eth_dev_stop(bonded_port_id);
1046 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1047 "Failed to start bonded pmd eth device %d.",
1050 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1051 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1052 sizeof(read_mac_addr)),
1053 "bonded port mac address not as expected");
1055 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1056 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1057 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1058 sizeof(read_mac_addr)),
1059 "slave port 0 mac address not as expected");
1061 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1062 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1063 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1064 sizeof(read_mac_addr)),
1065 "slave port 1 mac address not as expected");
1067 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1068 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1069 sizeof(read_mac_addr)),
1070 "slave port 2 mac address not as expected");
1072 /* 6. a - Stop bonded ethdev
1073 * b - remove slave ethdevs
1074 * c - Verify slave ethdevs MACs are restored
1076 rte_eth_dev_stop(bonded_port_id);
1078 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1079 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1081 "Failed to remove slave %d from bonded port (%d).",
1082 slave_port_ids[i], bonded_port_id);
1085 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1088 TEST_ASSERT_EQUAL(slave_count, 0,
1089 "Number of slaves (%d) is great than expected (%d).",
1092 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1093 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1094 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1095 sizeof(read_mac_addr)),
1096 "slave port 0 mac address not as expected");
1098 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1099 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1100 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1101 sizeof(read_mac_addr)),
1102 "slave port 1 mac address not as expected");
1104 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1105 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1106 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1107 sizeof(read_mac_addr)),
1108 "slave port 2 mac address not as expected");
1115 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1116 uint8_t number_of_slaves, uint8_t enable_slave)
1118 /* Configure bonded device */
1119 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1120 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1121 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1124 /* Add slaves to bonded device */
1125 while (number_of_slaves > test_params->bonded_slave_count)
1126 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1127 "Failed to add slave (%d to bonding port (%d).",
1128 test_params->bonded_slave_count - 1,
1129 test_params->bonded_port_id);
1131 /* Set link bonding mode */
1132 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1134 "Failed to set link bonding mode on port (%d) to (%d).",
1135 test_params->bonded_port_id, bonding_mode);
1137 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1138 "Failed to start bonded pmd eth device %d.",
1139 test_params->bonded_port_id);
1142 enable_bonded_slaves();
1148 test_adding_slave_after_bonded_device_started(void)
1152 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1153 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1154 "Failed to add slaves to bonded device");
1156 /* Enabled slave devices */
1157 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1158 virtual_ethdev_simulate_link_status_interrupt(
1159 test_params->slave_port_ids[i], 1);
1162 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1163 test_params->slave_port_ids[test_params->bonded_slave_count]),
1164 "Failed to add slave to bonded port.\n");
1166 rte_eth_stats_reset(
1167 test_params->slave_port_ids[test_params->bonded_slave_count]);
1169 test_params->bonded_slave_count++;
1171 return remove_slaves_and_stop_bonded_device();
1174 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1175 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1177 int test_lsc_interrupt_count;
1181 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1182 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1184 pthread_mutex_lock(&mutex);
1185 test_lsc_interrupt_count++;
1187 pthread_cond_signal(&cvar);
1188 pthread_mutex_unlock(&mutex);
1192 lsc_timeout(int wait_us)
1199 gettimeofday(&tp, NULL);
1201 /* Convert from timeval to timespec */
1202 ts.tv_sec = tp.tv_sec;
1203 ts.tv_nsec = tp.tv_usec * 1000;
1204 ts.tv_nsec += wait_us * 1000;
1206 pthread_mutex_lock(&mutex);
1207 if (test_lsc_interrupt_count < 1)
1208 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1210 pthread_mutex_unlock(&mutex);
1212 if (retval == 0 && test_lsc_interrupt_count < 1)
1219 test_status_interrupt(void)
1222 uint8_t slaves[RTE_MAX_ETHPORTS];
1224 /* initialized bonding device with T slaves */
1225 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1226 BONDING_MODE_ROUND_ROBIN, 1,
1227 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1228 "Failed to initialise bonded device");
1230 test_lsc_interrupt_count = 0;
1232 /* register link status change interrupt callback */
1233 rte_eth_dev_callback_register(test_params->bonded_port_id,
1234 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1235 &test_params->bonded_port_id);
1237 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1238 slaves, RTE_MAX_ETHPORTS);
1240 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1241 "Number of active slaves (%d) is not as expected (%d)",
1242 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1244 /* Bring all 4 slaves link status to down and test that we have received a
1246 virtual_ethdev_simulate_link_status_interrupt(
1247 test_params->slave_port_ids[0], 0);
1248 virtual_ethdev_simulate_link_status_interrupt(
1249 test_params->slave_port_ids[1], 0);
1250 virtual_ethdev_simulate_link_status_interrupt(
1251 test_params->slave_port_ids[2], 0);
1253 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1254 "Received a link status change interrupt unexpectedly");
1256 virtual_ethdev_simulate_link_status_interrupt(
1257 test_params->slave_port_ids[3], 0);
1259 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1260 "timed out waiting for interrupt");
1262 TEST_ASSERT(test_lsc_interrupt_count > 0,
1263 "Did not receive link status change interrupt");
1265 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1266 slaves, RTE_MAX_ETHPORTS);
1268 TEST_ASSERT_EQUAL(slave_count, 0,
1269 "Number of active slaves (%d) is not as expected (%d)",
1272 /* bring one slave port up so link status will change */
1273 test_lsc_interrupt_count = 0;
1275 virtual_ethdev_simulate_link_status_interrupt(
1276 test_params->slave_port_ids[0], 1);
1278 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1279 "timed out waiting for interrupt");
1281 /* test that we have received another lsc interrupt */
1282 TEST_ASSERT(test_lsc_interrupt_count > 0,
1283 "Did not receive link status change interrupt");
1285 /* Verify that calling the same slave lsc interrupt doesn't cause another
1286 * lsc interrupt from bonded device */
1287 test_lsc_interrupt_count = 0;
1289 virtual_ethdev_simulate_link_status_interrupt(
1290 test_params->slave_port_ids[0], 1);
1292 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1293 "received unexpected interrupt");
1295 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1296 "Did not receive link status change interrupt");
1299 /* unregister lsc callback before exiting */
1300 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1301 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1302 &test_params->bonded_port_id);
1304 /* Clean up and remove slaves from bonded device */
1305 return remove_slaves_and_stop_bonded_device();
1309 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1310 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1311 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1313 uint16_t pktlen, generated_burst_size, ether_type;
1317 ether_type = ETHER_TYPE_IPv4;
1319 ether_type = ETHER_TYPE_IPv6;
1322 initialize_eth_header(test_params->pkt_eth_hdr,
1323 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1324 ether_type, vlan, vlan_id);
1326 initialize_eth_header(test_params->pkt_eth_hdr,
1327 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1328 ether_type, vlan, vlan_id);
1331 if (toggle_udp_port)
1332 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1335 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1340 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1341 dst_addr_1, pktlen);
1343 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1344 dst_addr_0, pktlen);
1346 ip_hdr = test_params->pkt_ipv4_hdr;
1349 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1350 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1353 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1354 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1357 ip_hdr = test_params->pkt_ipv6_hdr;
1360 /* Generate burst of packets to transmit */
1361 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1362 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1363 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1365 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1366 "Failed to generate packet burst");
1368 return generated_burst_size;
1371 /** Round Robin Mode Tests */
1374 test_roundrobin_tx_burst(void)
1377 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1378 struct rte_eth_stats port_stats;
1380 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1381 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1382 "Failed to intialise bonded device");
1384 burst_size = 20 * test_params->bonded_slave_count;
1386 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1387 "Burst size specified is greater than supported.");
1389 /* Generate test bursts of packets to transmit */
1390 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1391 burst_size, "failed to generate test burst");
1393 /* Send burst on bonded port */
1394 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1395 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1398 /* Verify bonded port tx stats */
1399 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1400 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1401 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1402 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1405 /* Verify slave ports tx stats */
1406 for (i = 0; i < test_params->bonded_slave_count; i++) {
1407 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1408 TEST_ASSERT_EQUAL(port_stats.opackets,
1409 (uint64_t)burst_size / test_params->bonded_slave_count,
1410 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1411 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1412 burst_size / test_params->bonded_slave_count);
1415 /* Put all slaves down and try and transmit */
1416 for (i = 0; i < test_params->bonded_slave_count; i++) {
1417 virtual_ethdev_simulate_link_status_interrupt(
1418 test_params->slave_port_ids[i], 0);
1421 /* Send burst on bonded port */
1422 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1423 pkt_burst, burst_size), 0,
1424 "tx burst return unexpected value");
1426 /* Clean up and remove slaves from bonded device */
1427 return remove_slaves_and_stop_bonded_device();
1431 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1435 for (i = 0; i < nb_mbufs; i++) {
1436 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1437 TEST_ASSERT_EQUAL(refcnt, val,
1438 "mbuf ref count (%d)is not the expected value (%d)",
1445 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1449 for (i = 0; i < nb_mbufs; i++)
1450 rte_pktmbuf_free(mbufs[i]);
1453 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1454 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1455 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1456 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1459 test_roundrobin_tx_burst_slave_tx_fail(void)
1461 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1462 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1464 struct rte_eth_stats port_stats;
1466 int i, first_fail_idx, tx_count;
1468 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1469 BONDING_MODE_ROUND_ROBIN, 0,
1470 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1471 "Failed to intialise bonded device");
1473 /* Generate test bursts of packets to transmit */
1474 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1475 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1476 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1477 "Failed to generate test packet burst");
1479 /* Copy references to packets which we expect not to be transmitted */
1480 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1481 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1482 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1483 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1485 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1486 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1487 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1490 /* Set virtual slave to only fail transmission of
1491 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1492 virtual_ethdev_tx_burst_fn_set_success(
1493 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1496 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1497 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1498 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1500 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1501 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1503 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1504 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1505 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1506 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1507 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1509 /* Verify that failed packet are expected failed packets */
1510 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1511 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1512 "expected mbuf (%d) pointer %p not expected pointer %p",
1513 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1516 /* Verify bonded port tx stats */
1517 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1519 TEST_ASSERT_EQUAL(port_stats.opackets,
1520 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1521 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1522 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1523 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1524 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1525 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1527 /* Verify slave ports tx stats */
1528 for (i = 0; i < test_params->bonded_slave_count; i++) {
1529 int slave_expected_tx_count;
1531 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1533 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1534 test_params->bonded_slave_count;
1536 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1537 slave_expected_tx_count = slave_expected_tx_count -
1538 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1540 TEST_ASSERT_EQUAL(port_stats.opackets,
1541 (uint64_t)slave_expected_tx_count,
1542 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1543 test_params->slave_port_ids[i],
1544 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1547 /* Verify that all mbufs have a ref value of zero */
1548 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1549 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1550 "mbufs refcnts not as expected");
1551 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1553 /* Clean up and remove slaves from bonded device */
1554 return remove_slaves_and_stop_bonded_device();
1558 test_roundrobin_rx_burst_on_single_slave(void)
1560 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1561 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1563 struct rte_eth_stats port_stats;
1565 int i, j, burst_size = 25;
1567 /* Initialize bonded device with 4 slaves in round robin mode */
1568 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1569 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1570 "Failed to initialize bonded device with slaves");
1572 /* Generate test bursts of packets to transmit */
1573 TEST_ASSERT_EQUAL(generate_test_burst(
1574 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1575 "burst generation failed");
1577 for (i = 0; i < test_params->bonded_slave_count; i++) {
1578 /* Add rx data to slave */
1579 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1580 &gen_pkt_burst[0], burst_size);
1582 /* Call rx burst on bonded device */
1583 /* Send burst on bonded port */
1584 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1585 test_params->bonded_port_id, 0, rx_pkt_burst,
1586 MAX_PKT_BURST), burst_size,
1587 "round-robin rx burst failed");
1589 /* Verify bonded device rx count */
1590 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1591 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1592 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1593 test_params->bonded_port_id,
1594 (unsigned int)port_stats.ipackets, burst_size);
1598 /* Verify bonded slave devices rx count */
1599 /* Verify slave ports tx stats */
1600 for (j = 0; j < test_params->bonded_slave_count; j++) {
1601 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1604 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1605 "Slave Port (%d) ipackets value (%u) not as expected"
1606 " (%d)", test_params->slave_port_ids[i],
1607 (unsigned int)port_stats.ipackets, burst_size);
1609 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1610 "Slave Port (%d) ipackets value (%u) not as expected"
1611 " (%d)", test_params->slave_port_ids[i],
1612 (unsigned int)port_stats.ipackets, 0);
1615 /* Reset bonded slaves stats */
1616 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1618 /* reset bonded device stats */
1619 rte_eth_stats_reset(test_params->bonded_port_id);
1623 for (i = 0; i < MAX_PKT_BURST; i++) {
1624 if (gen_pkt_burst[i] != NULL)
1625 rte_pktmbuf_free(gen_pkt_burst[i]);
1627 if (rx_pkt_burst[i] != NULL)
1628 rte_pktmbuf_free(rx_pkt_burst[i]);
1632 /* Clean up and remove slaves from bonded device */
1633 return remove_slaves_and_stop_bonded_device();
1636 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1639 test_roundrobin_rx_burst_on_multiple_slaves(void)
1641 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1643 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1644 struct rte_eth_stats port_stats;
1646 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1649 /* Initialize bonded device with 4 slaves in round robin mode */
1650 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1651 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1652 "Failed to initialize bonded device with slaves");
1654 /* Generate test bursts of packets to transmit */
1655 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1656 TEST_ASSERT_EQUAL(generate_test_burst(
1657 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1658 burst_size[i], "burst generation failed");
1661 /* Add rx data to slaves */
1662 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1663 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1664 &gen_pkt_burst[i][0], burst_size[i]);
1667 /* Call rx burst on bonded device */
1668 /* Send burst on bonded port */
1669 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1671 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1672 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1673 burst_size[0] + burst_size[1] + burst_size[2]);
1675 /* Verify bonded device rx count */
1676 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1677 TEST_ASSERT_EQUAL(port_stats.ipackets,
1678 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1679 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1680 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1681 burst_size[0] + burst_size[1] + burst_size[2]);
1683 /* Verify bonded slave devices rx counts */
1684 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1685 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1686 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1687 test_params->slave_port_ids[0],
1688 (unsigned int)port_stats.ipackets, burst_size[0]);
1690 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1691 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1692 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1693 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1696 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1697 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1698 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1699 test_params->slave_port_ids[2],
1700 (unsigned int)port_stats.ipackets, burst_size[2]);
1702 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1703 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1704 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1705 test_params->slave_port_ids[3],
1706 (unsigned int)port_stats.ipackets, 0);
1709 for (i = 0; i < MAX_PKT_BURST; i++) {
1710 if (rx_pkt_burst[i] != NULL)
1711 rte_pktmbuf_free(rx_pkt_burst[i]);
1714 /* Clean up and remove slaves from bonded device */
1715 return remove_slaves_and_stop_bonded_device();
1719 test_roundrobin_verify_mac_assignment(void)
1721 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1725 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1726 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1728 /* Initialize bonded device with 4 slaves in round robin mode */
1729 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1730 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1731 "Failed to initialize bonded device with slaves");
1733 /* Verify that all MACs are the same as first slave added to bonded dev */
1734 for (i = 0; i < test_params->bonded_slave_count; i++) {
1735 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1736 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1737 sizeof(read_mac_addr)),
1738 "slave port (%d) mac address not set to that of primary port",
1739 test_params->slave_port_ids[i]);
1742 /* change primary and verify that MAC addresses haven't changed */
1743 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1744 test_params->slave_port_ids[2]),
1745 "Failed to set bonded port (%d) primary port to (%d)",
1746 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1748 for (i = 0; i < test_params->bonded_slave_count; i++) {
1749 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1750 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1751 sizeof(read_mac_addr)),
1752 "slave port (%d) mac address has changed to that of primary"
1753 " port without stop/start toggle of bonded device",
1754 test_params->slave_port_ids[i]);
1757 /* stop / start bonded device and verify that primary MAC address is
1758 * propagate to bonded device and slaves */
1759 rte_eth_dev_stop(test_params->bonded_port_id);
1761 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1762 "Failed to start bonded device");
1764 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1765 TEST_ASSERT_SUCCESS(
1766 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1767 "bonded port (%d) mac address not set to that of new primary port",
1768 test_params->slave_port_ids[i]);
1770 for (i = 0; i < test_params->bonded_slave_count; i++) {
1771 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1772 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1773 sizeof(read_mac_addr)),
1774 "slave port (%d) mac address not set to that of new primary"
1775 " port", test_params->slave_port_ids[i]);
1778 /* Set explicit MAC address */
1779 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1780 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1781 "Failed to set MAC");
1783 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1784 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1785 sizeof(read_mac_addr)),
1786 "bonded port (%d) mac address not set to that of new primary port",
1787 test_params->slave_port_ids[i]);
1789 for (i = 0; i < test_params->bonded_slave_count; i++) {
1790 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1791 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1792 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1793 " that of new primary port\n", test_params->slave_port_ids[i]);
1796 /* Clean up and remove slaves from bonded device */
1797 return remove_slaves_and_stop_bonded_device();
1801 test_roundrobin_verify_promiscuous_enable_disable(void)
1803 int i, promiscuous_en;
1805 /* Initialize bonded device with 4 slaves in round robin mode */
1806 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1807 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1808 "Failed to initialize bonded device with slaves");
1810 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1812 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1813 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1814 "Port (%d) promiscuous mode not enabled",
1815 test_params->bonded_port_id);
1817 for (i = 0; i < test_params->bonded_slave_count; i++) {
1818 promiscuous_en = rte_eth_promiscuous_get(
1819 test_params->slave_port_ids[i]);
1820 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1821 "slave port (%d) promiscuous mode not enabled",
1822 test_params->slave_port_ids[i]);
1825 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1827 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1828 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1829 "Port (%d) promiscuous mode not disabled\n",
1830 test_params->bonded_port_id);
1832 for (i = 0; i < test_params->bonded_slave_count; i++) {
1833 promiscuous_en = rte_eth_promiscuous_get(
1834 test_params->slave_port_ids[i]);
1835 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1836 "Port (%d) promiscuous mode not disabled\n",
1837 test_params->slave_port_ids[i]);
1840 /* Clean up and remove slaves from bonded device */
1841 return remove_slaves_and_stop_bonded_device();
1844 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1845 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1848 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1850 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1851 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1852 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1854 struct rte_eth_stats port_stats;
1855 uint8_t slaves[RTE_MAX_ETHPORTS];
1857 int i, burst_size, slave_count;
1859 /* NULL all pointers in array to simplify cleanup */
1860 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1862 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1863 * in round robin mode */
1864 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1865 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1866 "Failed to initialize bonded device with slaves");
1868 /* Verify Current Slaves Count /Active Slave Count is */
1869 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1871 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1872 "Number of slaves (%d) is not as expected (%d).",
1873 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1875 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1876 slaves, RTE_MAX_ETHPORTS);
1877 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1878 "Number of active slaves (%d) is not as expected (%d).",
1879 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1881 /* Set 2 slaves eth_devs link status to down */
1882 virtual_ethdev_simulate_link_status_interrupt(
1883 test_params->slave_port_ids[1], 0);
1884 virtual_ethdev_simulate_link_status_interrupt(
1885 test_params->slave_port_ids[3], 0);
1887 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1888 slaves, RTE_MAX_ETHPORTS);
1889 TEST_ASSERT_EQUAL(slave_count,
1890 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1891 "Number of active slaves (%d) is not as expected (%d).\n",
1892 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1896 /* Verify that pkts are not sent on slaves with link status down:
1898 * 1. Generate test burst of traffic
1899 * 2. Transmit burst on bonded eth_dev
1900 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1901 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1904 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1905 burst_size, "generate_test_burst failed");
1907 rte_eth_stats_reset(test_params->bonded_port_id);
1911 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1912 burst_size), burst_size, "rte_eth_tx_burst failed");
1914 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1915 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1916 "Port (%d) opackets stats (%d) not expected (%d) value",
1917 test_params->bonded_port_id, (int)port_stats.opackets,
1920 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1921 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1922 "Port (%d) opackets stats (%d) not expected (%d) value",
1923 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1925 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1926 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1927 "Port (%d) opackets stats (%d) not expected (%d) value",
1928 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1930 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1931 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1932 "Port (%d) opackets stats (%d) not expected (%d) value",
1933 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1935 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1936 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1937 "Port (%d) opackets stats (%d) not expected (%d) value",
1938 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1940 /* Verify that pkts are not sent on slaves with link status down:
1942 * 1. Generate test bursts of traffic
1943 * 2. Add bursts on to virtual eth_devs
1944 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1945 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1946 * 4. Verify stats for bonded eth_dev
1947 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1949 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1950 TEST_ASSERT_EQUAL(generate_test_burst(
1951 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1952 burst_size, "failed to generate packet burst");
1954 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1955 &gen_pkt_burst[i][0], burst_size);
1958 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1959 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1960 burst_size + burst_size,
1961 "rte_eth_rx_burst failed");
1963 /* Verify bonded device rx count */
1964 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1965 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1966 "(%d) port_stats.ipackets not as expected\n",
1967 test_params->bonded_port_id);
1970 for (i = 0; i < MAX_PKT_BURST; i++) {
1971 if (rx_pkt_burst[i] != NULL)
1972 rte_pktmbuf_free(rx_pkt_burst[i]);
1974 if (gen_pkt_burst[1][i] != NULL)
1975 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1977 if (gen_pkt_burst[3][i] != NULL)
1978 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1981 /* Clean up and remove slaves from bonded device */
1982 return remove_slaves_and_stop_bonded_device();
1985 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1987 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1990 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1993 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1995 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1996 char slave_name[RTE_ETH_NAME_MAX_LEN];
2000 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2001 /* Generate slave name / MAC address */
2002 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2003 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2005 /* Create slave devices with no ISR Support */
2006 if (polling_test_slaves[i] == -1) {
2007 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2008 rte_socket_id(), 0);
2009 TEST_ASSERT(polling_test_slaves[i] >= 0,
2010 "Failed to create virtual virtual ethdev %s\n", slave_name);
2012 /* Configure slave */
2013 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2014 "Failed to configure virtual ethdev %s(%d)", slave_name,
2015 polling_test_slaves[i]);
2018 /* Add slave to bonded device */
2019 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2020 polling_test_slaves[i]),
2021 "Failed to add slave %s(%d) to bonded device %d",
2022 slave_name, polling_test_slaves[i],
2023 test_params->bonded_port_id);
2026 /* Initialize bonded device */
2027 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2028 "Failed to configure bonded device %d",
2029 test_params->bonded_port_id);
2032 /* Register link status change interrupt callback */
2033 rte_eth_dev_callback_register(test_params->bonded_port_id,
2034 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2035 &test_params->bonded_port_id);
2037 /* link status change callback for first slave link up */
2038 test_lsc_interrupt_count = 0;
2040 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2042 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2045 /* no link status change callback for second slave link up */
2046 test_lsc_interrupt_count = 0;
2048 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2050 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2052 /* link status change callback for both slave links down */
2053 test_lsc_interrupt_count = 0;
2055 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2056 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2058 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2060 /* Un-Register link status change interrupt callback */
2061 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2062 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2063 &test_params->bonded_port_id);
2066 /* Clean up and remove slaves from bonded device */
2067 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2069 TEST_ASSERT_SUCCESS(
2070 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2071 polling_test_slaves[i]),
2072 "Failed to remove slave %d from bonded port (%d)",
2073 polling_test_slaves[i], test_params->bonded_port_id);
2076 return remove_slaves_and_stop_bonded_device();
2080 /** Active Backup Mode Tests */
2083 test_activebackup_tx_burst(void)
2085 int i, pktlen, primary_port, burst_size;
2086 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2087 struct rte_eth_stats port_stats;
2089 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2090 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2091 "Failed to initialize bonded device with slaves");
2093 initialize_eth_header(test_params->pkt_eth_hdr,
2094 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2095 ETHER_TYPE_IPv4, 0, 0);
2096 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2098 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2099 dst_addr_0, pktlen);
2101 burst_size = 20 * test_params->bonded_slave_count;
2103 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2104 "Burst size specified is greater than supported.");
2106 /* Generate a burst of packets to transmit */
2107 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2108 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2109 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2110 burst_size, "failed to generate burst correctly");
2112 /* Send burst on bonded port */
2113 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2114 burst_size), burst_size, "tx burst failed");
2116 /* Verify bonded port tx stats */
2117 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2118 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2119 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2120 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2123 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2125 /* Verify slave ports tx stats */
2126 for (i = 0; i < test_params->bonded_slave_count; i++) {
2127 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2128 if (test_params->slave_port_ids[i] == primary_port) {
2129 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2130 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2131 test_params->bonded_port_id,
2132 (unsigned int)port_stats.opackets,
2133 burst_size / test_params->bonded_slave_count);
2135 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2136 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2137 test_params->bonded_port_id,
2138 (unsigned int)port_stats.opackets, 0);
2142 /* Put all slaves down and try and transmit */
2143 for (i = 0; i < test_params->bonded_slave_count; i++) {
2144 virtual_ethdev_simulate_link_status_interrupt(
2145 test_params->slave_port_ids[i], 0);
2148 /* Send burst on bonded port */
2149 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2150 pkts_burst, burst_size), 0, "Sending empty burst failed");
2152 /* Clean up and remove slaves from bonded device */
2153 return remove_slaves_and_stop_bonded_device();
2156 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2159 test_activebackup_rx_burst(void)
2161 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2162 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2164 struct rte_eth_stats port_stats;
2168 int i, j, burst_size = 17;
2170 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2171 BONDING_MODE_ACTIVE_BACKUP, 0,
2172 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2173 "Failed to initialize bonded device with slaves");
2175 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2176 TEST_ASSERT(primary_port >= 0,
2177 "failed to get primary slave for bonded port (%d)",
2178 test_params->bonded_port_id);
2180 for (i = 0; i < test_params->bonded_slave_count; i++) {
2181 /* Generate test bursts of packets to transmit */
2182 TEST_ASSERT_EQUAL(generate_test_burst(
2183 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2184 burst_size, "burst generation failed");
2186 /* Add rx data to slave */
2187 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2188 &gen_pkt_burst[0], burst_size);
2190 /* Call rx burst on bonded device */
2191 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2192 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2193 "rte_eth_rx_burst failed");
2195 if (test_params->slave_port_ids[i] == primary_port) {
2196 /* Verify bonded device rx count */
2197 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2198 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2199 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2200 test_params->bonded_port_id,
2201 (unsigned int)port_stats.ipackets, burst_size);
2203 /* Verify bonded slave devices rx count */
2204 for (j = 0; j < test_params->bonded_slave_count; j++) {
2205 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2207 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2208 "Slave Port (%d) ipackets value (%u) not as "
2209 "expected (%d)", test_params->slave_port_ids[i],
2210 (unsigned int)port_stats.ipackets, burst_size);
2212 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2213 "Slave Port (%d) ipackets value (%u) not as "
2214 "expected (%d)\n", test_params->slave_port_ids[i],
2215 (unsigned int)port_stats.ipackets, 0);
2219 for (j = 0; j < test_params->bonded_slave_count; j++) {
2220 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2221 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2222 "Slave Port (%d) ipackets value (%u) not as expected "
2223 "(%d)", test_params->slave_port_ids[i],
2224 (unsigned int)port_stats.ipackets, 0);
2229 for (i = 0; i < MAX_PKT_BURST; i++) {
2230 if (rx_pkt_burst[i] != NULL) {
2231 rte_pktmbuf_free(rx_pkt_burst[i]);
2232 rx_pkt_burst[i] = NULL;
2236 /* reset bonded device stats */
2237 rte_eth_stats_reset(test_params->bonded_port_id);
2240 /* Clean up and remove slaves from bonded device */
2241 return remove_slaves_and_stop_bonded_device();
2245 test_activebackup_verify_promiscuous_enable_disable(void)
2247 int i, primary_port, promiscuous_en;
2249 /* Initialize bonded device with 4 slaves in round robin mode */
2250 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2251 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2252 "Failed to initialize bonded device with slaves");
2254 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2255 TEST_ASSERT(primary_port >= 0,
2256 "failed to get primary slave for bonded port (%d)",
2257 test_params->bonded_port_id);
2259 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2261 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2262 "Port (%d) promiscuous mode not enabled",
2263 test_params->bonded_port_id);
2265 for (i = 0; i < test_params->bonded_slave_count; i++) {
2266 promiscuous_en = rte_eth_promiscuous_get(
2267 test_params->slave_port_ids[i]);
2268 if (primary_port == test_params->slave_port_ids[i]) {
2269 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2270 "slave port (%d) promiscuous mode not enabled",
2271 test_params->slave_port_ids[i]);
2273 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2274 "slave port (%d) promiscuous mode enabled",
2275 test_params->slave_port_ids[i]);
2280 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2282 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2283 "Port (%d) promiscuous mode not disabled\n",
2284 test_params->bonded_port_id);
2286 for (i = 0; i < test_params->bonded_slave_count; i++) {
2287 promiscuous_en = rte_eth_promiscuous_get(
2288 test_params->slave_port_ids[i]);
2289 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2290 "slave port (%d) promiscuous mode not disabled\n",
2291 test_params->slave_port_ids[i]);
2294 /* Clean up and remove slaves from bonded device */
2295 return remove_slaves_and_stop_bonded_device();
2299 test_activebackup_verify_mac_assignment(void)
2301 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2303 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2304 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2306 /* Initialize bonded device with 2 slaves in active backup mode */
2307 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2308 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2309 "Failed to initialize bonded device with slaves");
2311 /* Verify that bonded MACs is that of first slave and that the other slave
2312 * MAC hasn't been changed */
2313 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2314 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2315 sizeof(read_mac_addr)),
2316 "bonded port (%d) mac address not set to that of primary port",
2317 test_params->bonded_port_id);
2319 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2320 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2321 sizeof(read_mac_addr)),
2322 "slave port (%d) mac address not set to that of primary port",
2323 test_params->slave_port_ids[0]);
2325 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2326 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2327 sizeof(read_mac_addr)),
2328 "slave port (%d) mac address not as expected",
2329 test_params->slave_port_ids[1]);
2331 /* change primary and verify that MAC addresses haven't changed */
2332 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2333 test_params->slave_port_ids[1]), 0,
2334 "Failed to set bonded port (%d) primary port to (%d)",
2335 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2337 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2338 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2339 sizeof(read_mac_addr)),
2340 "bonded port (%d) mac address not set to that of primary port",
2341 test_params->bonded_port_id);
2343 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2344 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2345 sizeof(read_mac_addr)),
2346 "slave port (%d) mac address not set to that of primary port",
2347 test_params->slave_port_ids[0]);
2349 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2350 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2351 sizeof(read_mac_addr)),
2352 "slave port (%d) mac address not as expected",
2353 test_params->slave_port_ids[1]);
2355 /* stop / start bonded device and verify that primary MAC address is
2356 * propagated to bonded device and slaves */
2358 rte_eth_dev_stop(test_params->bonded_port_id);
2360 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2361 "Failed to start device");
2363 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2364 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2365 sizeof(read_mac_addr)),
2366 "bonded port (%d) mac address not set to that of primary port",
2367 test_params->bonded_port_id);
2369 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2370 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2371 sizeof(read_mac_addr)),
2372 "slave port (%d) mac address not as expected",
2373 test_params->slave_port_ids[0]);
2375 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2376 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2377 sizeof(read_mac_addr)),
2378 "slave port (%d) mac address not set to that of primary port",
2379 test_params->slave_port_ids[1]);
2381 /* Set explicit MAC address */
2382 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2383 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2384 "failed to set MAC address");
2386 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2387 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2388 sizeof(read_mac_addr)),
2389 "bonded port (%d) mac address not set to that of bonded port",
2390 test_params->bonded_port_id);
2392 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2393 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2394 sizeof(read_mac_addr)),
2395 "slave port (%d) mac address not as expected",
2396 test_params->slave_port_ids[0]);
2398 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2399 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2400 sizeof(read_mac_addr)),
2401 "slave port (%d) mac address not set to that of bonded port",
2402 test_params->slave_port_ids[1]);
2404 /* Clean up and remove slaves from bonded device */
2405 return remove_slaves_and_stop_bonded_device();
2409 test_activebackup_verify_slave_link_status_change_failover(void)
2411 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2412 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2413 struct rte_eth_stats port_stats;
2415 uint8_t slaves[RTE_MAX_ETHPORTS];
2417 int i, j, burst_size, slave_count, primary_port;
2421 memset(pkt_burst, 0, sizeof(pkt_burst));
2423 /* Generate packet burst for testing */
2424 TEST_ASSERT_EQUAL(generate_test_burst(
2425 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2426 "generate_test_burst failed");
2428 /* Initialize bonded device with 4 slaves in round robin mode */
2429 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2430 BONDING_MODE_ACTIVE_BACKUP, 0,
2431 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2432 "Failed to initialize bonded device with slaves");
2434 /* Verify Current Slaves Count /Active Slave Count is */
2435 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2437 TEST_ASSERT_EQUAL(slave_count, 4,
2438 "Number of slaves (%d) is not as expected (%d).",
2441 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2442 slaves, RTE_MAX_ETHPORTS);
2443 TEST_ASSERT_EQUAL(slave_count, 4,
2444 "Number of active slaves (%d) is not as expected (%d).",
2447 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2448 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2449 "Primary port not as expected");
2451 /* Bring 2 slaves down and verify active slave count */
2452 virtual_ethdev_simulate_link_status_interrupt(
2453 test_params->slave_port_ids[1], 0);
2454 virtual_ethdev_simulate_link_status_interrupt(
2455 test_params->slave_port_ids[3], 0);
2457 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2458 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2459 "Number of active slaves (%d) is not as expected (%d).",
2462 virtual_ethdev_simulate_link_status_interrupt(
2463 test_params->slave_port_ids[1], 1);
2464 virtual_ethdev_simulate_link_status_interrupt(
2465 test_params->slave_port_ids[3], 1);
2468 /* Bring primary port down, verify that active slave count is 3 and primary
2470 virtual_ethdev_simulate_link_status_interrupt(
2471 test_params->slave_port_ids[0], 0);
2473 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2474 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2476 "Number of active slaves (%d) is not as expected (%d).",
2479 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2480 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2481 "Primary port not as expected");
2483 /* Verify that pkts are sent on new primary slave */
2485 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2486 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2487 burst_size), burst_size, "rte_eth_tx_burst failed");
2489 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2490 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2491 "(%d) port_stats.opackets not as expected",
2492 test_params->slave_port_ids[2]);
2494 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2495 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2496 "(%d) port_stats.opackets not as expected\n",
2497 test_params->slave_port_ids[0]);
2499 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2500 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2501 "(%d) port_stats.opackets not as expected\n",
2502 test_params->slave_port_ids[1]);
2504 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2505 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2506 "(%d) port_stats.opackets not as expected\n",
2507 test_params->slave_port_ids[3]);
2509 /* Generate packet burst for testing */
2511 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2512 TEST_ASSERT_EQUAL(generate_test_burst(
2513 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2514 "generate_test_burst failed");
2516 virtual_ethdev_add_mbufs_to_rx_queue(
2517 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2520 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2521 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2522 burst_size, "rte_eth_rx_burst\n");
2524 /* Verify bonded device rx count */
2525 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2526 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2527 "(%d) port_stats.ipackets not as expected",
2528 test_params->bonded_port_id);
2530 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2531 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2532 "(%d) port_stats.opackets not as expected",
2533 test_params->slave_port_ids[2]);
2535 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2536 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2537 "(%d) port_stats.opackets not as expected",
2538 test_params->slave_port_ids[0]);
2540 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2541 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2542 "(%d) port_stats.opackets not as expected",
2543 test_params->slave_port_ids[1]);
2545 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2546 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2547 "(%d) port_stats.opackets not as expected",
2548 test_params->slave_port_ids[3]);
2551 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2552 for (j = 0; j < MAX_PKT_BURST; j++) {
2553 if (pkt_burst[i][j] != NULL) {
2554 rte_pktmbuf_free(pkt_burst[i][j]);
2555 pkt_burst[i][j] = NULL;
2560 /* Clean up and remove slaves from bonded device */
2561 return remove_slaves_and_stop_bonded_device();
2564 /** Balance Mode Tests */
2567 test_balance_xmit_policy_configuration(void)
2569 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2570 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2571 "Failed to initialize_bonded_device_with_slaves.");
2573 /* Invalid port id */
2574 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2575 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2576 "Expected call to failed as invalid port specified.");
2578 /* Set xmit policy on non bonded device */
2579 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2580 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2581 "Expected call to failed as invalid port specified.");
2584 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2585 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2586 "Failed to set balance xmit policy.");
2588 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2589 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2592 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2593 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2594 "Failed to set balance xmit policy.");
2596 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2597 BALANCE_XMIT_POLICY_LAYER23,
2598 "balance xmit policy not as expected.");
2601 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2602 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2603 "Failed to set balance xmit policy.");
2605 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2606 BALANCE_XMIT_POLICY_LAYER34,
2607 "balance xmit policy not as expected.");
2609 /* Invalid port id */
2610 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2611 "Expected call to failed as invalid port specified.");
2613 /* Clean up and remove slaves from bonded device */
2614 return remove_slaves_and_stop_bonded_device();
2617 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2620 test_balance_l2_tx_burst(void)
2622 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2623 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2627 struct rte_eth_stats port_stats;
2629 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2630 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2631 "Failed to initialize_bonded_device_with_slaves.");
2633 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2634 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2635 "Failed to set balance xmit policy.");
2637 initialize_eth_header(test_params->pkt_eth_hdr,
2638 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2639 ETHER_TYPE_IPv4, 0, 0);
2640 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2642 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2643 dst_addr_0, pktlen);
2645 /* Generate a burst 1 of packets to transmit */
2646 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2647 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2648 test_params->pkt_udp_hdr, burst_size[0],
2649 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2650 "failed to generate packet burst");
2652 initialize_eth_header(test_params->pkt_eth_hdr,
2653 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2654 ETHER_TYPE_IPv4, 0, 0);
2656 /* Generate a burst 2 of packets to transmit */
2657 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2658 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2659 test_params->pkt_udp_hdr, burst_size[1],
2660 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2661 "failed to generate packet burst");
2663 /* Send burst 1 on bonded port */
2664 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2665 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2666 &pkts_burst[i][0], burst_size[i]),
2667 burst_size[i], "Failed to transmit packet burst");
2670 /* Verify bonded port tx stats */
2671 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2672 TEST_ASSERT_EQUAL(port_stats.opackets,
2673 (uint64_t)(burst_size[0] + burst_size[1]),
2674 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2675 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2676 burst_size[0] + burst_size[1]);
2679 /* Verify slave ports tx stats */
2680 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2681 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2682 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2683 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2686 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2687 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2688 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2689 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2692 /* Put all slaves down and try and transmit */
2693 for (i = 0; i < test_params->bonded_slave_count; i++) {
2695 virtual_ethdev_simulate_link_status_interrupt(
2696 test_params->slave_port_ids[i], 0);
2699 /* Send burst on bonded port */
2700 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2701 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2702 0, "Expected zero packet");
2704 /* Clean up and remove slaves from bonded device */
2705 return remove_slaves_and_stop_bonded_device();
2709 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2710 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2712 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2714 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2715 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2717 struct rte_eth_stats port_stats;
2719 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2720 BONDING_MODE_BALANCE, 0, 2, 1),
2721 "Failed to initialize_bonded_device_with_slaves.");
2723 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2724 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2725 "Failed to set balance xmit policy.");
2730 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2731 "Burst size specified is greater than supported.");
2733 /* Generate test bursts of packets to transmit */
2734 TEST_ASSERT_EQUAL(generate_test_burst(
2735 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2736 burst_size_1, "failed to generate packet burst");
2738 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2739 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2740 "failed to generate packet burst");
2742 /* Send burst 1 on bonded port */
2743 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2745 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2747 /* Send burst 2 on bonded port */
2748 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2750 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2752 /* Verify bonded port tx stats */
2753 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2754 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2755 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2756 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2759 /* Verify slave ports tx stats */
2760 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2761 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2762 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2763 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2766 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2767 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2768 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2769 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2772 /* Put all slaves down and try and transmit */
2773 for (i = 0; i < test_params->bonded_slave_count; i++) {
2775 virtual_ethdev_simulate_link_status_interrupt(
2776 test_params->slave_port_ids[i], 0);
2779 /* Send burst on bonded port */
2780 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2781 test_params->bonded_port_id, 0, pkts_burst_1,
2782 burst_size_1), 0, "Expected zero packet");
2785 /* Clean up and remove slaves from bonded device */
2786 return remove_slaves_and_stop_bonded_device();
2790 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2792 return balance_l23_tx_burst(0, 1, 1, 0);
2796 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2798 return balance_l23_tx_burst(1, 1, 0, 1);
2802 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2804 return balance_l23_tx_burst(0, 0, 0, 1);
2808 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2810 return balance_l23_tx_burst(1, 0, 0, 1);
2814 test_balance_l23_tx_burst_toggle_mac_addr(void)
2816 return balance_l23_tx_burst(0, 0, 1, 0);
2820 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2821 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2822 uint8_t toggle_udp_port)
2824 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2826 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2827 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2829 struct rte_eth_stats port_stats;
2831 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2832 BONDING_MODE_BALANCE, 0, 2, 1),
2833 "Failed to initialize_bonded_device_with_slaves.");
2835 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2836 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2837 "Failed to set balance xmit policy.");
2842 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2843 "Burst size specified is greater than supported.");
2845 /* Generate test bursts of packets to transmit */
2846 TEST_ASSERT_EQUAL(generate_test_burst(
2847 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2848 burst_size_1, "failed to generate burst");
2850 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2851 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2852 toggle_udp_port), burst_size_2, "failed to generate burst");
2854 /* Send burst 1 on bonded port */
2855 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2857 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2859 /* Send burst 2 on bonded port */
2860 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2862 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2865 /* Verify bonded port tx stats */
2866 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2867 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2868 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2869 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2872 /* Verify slave ports tx stats */
2873 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2874 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2875 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2876 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2879 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2880 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2881 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2882 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2885 /* Put all slaves down and try and transmit */
2886 for (i = 0; i < test_params->bonded_slave_count; i++) {
2888 virtual_ethdev_simulate_link_status_interrupt(
2889 test_params->slave_port_ids[i], 0);
2892 /* Send burst on bonded port */
2893 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2894 test_params->bonded_port_id, 0, pkts_burst_1,
2895 burst_size_1), 0, "Expected zero packet");
2897 /* Clean up and remove slaves from bonded device */
2898 return remove_slaves_and_stop_bonded_device();
2902 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2904 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2908 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2910 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2914 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2916 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2920 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2922 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2926 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2928 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2932 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2934 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2937 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2938 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2939 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2940 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2941 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2944 test_balance_tx_burst_slave_tx_fail(void)
2946 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2947 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2949 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2951 struct rte_eth_stats port_stats;
2953 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2955 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2956 BONDING_MODE_BALANCE, 0,
2957 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2958 "Failed to intialise bonded device");
2960 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2961 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2962 "Failed to set balance xmit policy.");
2965 /* Generate test bursts for transmission */
2966 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2967 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2968 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2969 "Failed to generate test packet burst 1");
2971 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2972 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2974 /* copy mbuf referneces for expected transmission failures */
2975 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2976 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2978 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2979 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2980 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2981 "Failed to generate test packet burst 2");
2984 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2985 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2986 virtual_ethdev_tx_burst_fn_set_success(
2987 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2990 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2991 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2992 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2995 /* Transmit burst 1 */
2996 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2997 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2999 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3000 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3001 "Transmitted (%d) packets, expected to transmit (%d) packets",
3002 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3003 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3005 /* Verify that failed packet are expected failed packets */
3006 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3007 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3008 "expected mbuf (%d) pointer %p not expected pointer %p",
3009 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3012 /* Transmit burst 2 */
3013 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3014 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3016 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3017 "Transmitted (%d) packets, expected to transmit (%d) packets",
3018 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3021 /* Verify bonded port tx stats */
3022 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3024 TEST_ASSERT_EQUAL(port_stats.opackets,
3025 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3026 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3027 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3028 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3029 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3030 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3031 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3032 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3034 /* Verify slave ports tx stats */
3036 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3038 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3039 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3040 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3041 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3042 test_params->slave_port_ids[0],
3043 (unsigned int)port_stats.opackets,
3044 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3045 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3050 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3052 TEST_ASSERT_EQUAL(port_stats.opackets,
3053 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3054 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3055 test_params->slave_port_ids[1],
3056 (unsigned int)port_stats.opackets,
3057 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3059 /* Verify that all mbufs have a ref value of zero */
3060 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3061 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3062 "mbufs refcnts not as expected");
3064 free_mbufs(&pkts_burst_1[tx_count_1],
3065 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3067 /* Clean up and remove slaves from bonded device */
3068 return remove_slaves_and_stop_bonded_device();
3071 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3074 test_balance_rx_burst(void)
3076 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3078 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3079 struct rte_eth_stats port_stats;
3081 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3084 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3086 /* Initialize bonded device with 4 slaves in round robin mode */
3087 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3088 BONDING_MODE_BALANCE, 0, 3, 1),
3089 "Failed to intialise bonded device");
3091 /* Generate test bursts of packets to transmit */
3092 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3093 TEST_ASSERT_EQUAL(generate_test_burst(
3094 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3095 0, 0), burst_size[i],
3096 "failed to generate packet burst");
3099 /* Add rx data to slaves */
3100 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3101 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3102 &gen_pkt_burst[i][0], burst_size[i]);
3105 /* Call rx burst on bonded device */
3106 /* Send burst on bonded port */
3107 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3108 rx_pkt_burst, MAX_PKT_BURST),
3109 burst_size[0] + burst_size[1] + burst_size[2],
3110 "balance rx burst failed\n");
3112 /* Verify bonded device rx count */
3113 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3114 TEST_ASSERT_EQUAL(port_stats.ipackets,
3115 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3116 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3117 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3118 burst_size[0] + burst_size[1] + burst_size[2]);
3121 /* Verify bonded slave devices rx counts */
3122 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3123 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3124 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3125 test_params->slave_port_ids[0],
3126 (unsigned int)port_stats.ipackets, burst_size[0]);
3128 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3129 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3130 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3131 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3134 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3135 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3136 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3137 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3140 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3141 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3142 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3143 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3147 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3148 for (j = 0; j < MAX_PKT_BURST; j++) {
3149 if (gen_pkt_burst[i][j] != NULL) {
3150 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3151 gen_pkt_burst[i][j] = NULL;
3156 /* Clean up and remove slaves from bonded device */
3157 return remove_slaves_and_stop_bonded_device();
3161 test_balance_verify_promiscuous_enable_disable(void)
3165 /* Initialize bonded device with 4 slaves in round robin mode */
3166 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3167 BONDING_MODE_BALANCE, 0, 4, 1),
3168 "Failed to intialise bonded device");
3170 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3172 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3173 "Port (%d) promiscuous mode not enabled",
3174 test_params->bonded_port_id);
3176 for (i = 0; i < test_params->bonded_slave_count; i++) {
3177 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3178 test_params->slave_port_ids[i]), 1,
3179 "Port (%d) promiscuous mode not enabled",
3180 test_params->slave_port_ids[i]);
3183 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3185 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3186 "Port (%d) promiscuous mode not disabled",
3187 test_params->bonded_port_id);
3189 for (i = 0; i < test_params->bonded_slave_count; i++) {
3190 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3191 test_params->slave_port_ids[i]), 0,
3192 "Port (%d) promiscuous mode not disabled",
3193 test_params->slave_port_ids[i]);
3196 /* Clean up and remove slaves from bonded device */
3197 return remove_slaves_and_stop_bonded_device();
3201 test_balance_verify_mac_assignment(void)
3203 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3205 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3206 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3208 /* Initialize bonded device with 2 slaves in active backup mode */
3209 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3210 BONDING_MODE_BALANCE, 0, 2, 1),
3211 "Failed to intialise bonded device");
3213 /* Verify that bonded MACs is that of first slave and that the other slave
3214 * MAC hasn't been changed */
3215 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3216 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3217 sizeof(read_mac_addr)),
3218 "bonded port (%d) mac address not set to that of primary port",
3219 test_params->bonded_port_id);
3221 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3222 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3223 sizeof(read_mac_addr)),
3224 "slave port (%d) mac address not set to that of primary port",
3225 test_params->slave_port_ids[0]);
3227 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3228 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3229 sizeof(read_mac_addr)),
3230 "slave port (%d) mac address not set to that of primary port",
3231 test_params->slave_port_ids[1]);
3233 /* change primary and verify that MAC addresses haven't changed */
3234 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3235 test_params->slave_port_ids[1]),
3236 "Failed to set bonded port (%d) primary port to (%d)\n",
3237 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3239 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3240 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3241 sizeof(read_mac_addr)),
3242 "bonded port (%d) mac address not set to that of primary port",
3243 test_params->bonded_port_id);
3245 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3246 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3247 sizeof(read_mac_addr)),
3248 "slave port (%d) mac address not set to that of primary port",
3249 test_params->slave_port_ids[0]);
3251 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3252 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3253 sizeof(read_mac_addr)),
3254 "slave port (%d) mac address not set to that of primary port",
3255 test_params->slave_port_ids[1]);
3257 /* stop / start bonded device and verify that primary MAC address is
3258 * propagated to bonded device and slaves */
3260 rte_eth_dev_stop(test_params->bonded_port_id);
3262 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3263 "Failed to start bonded device");
3265 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3266 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3267 sizeof(read_mac_addr)),
3268 "bonded port (%d) mac address not set to that of primary port",
3269 test_params->bonded_port_id);
3271 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3272 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3273 sizeof(read_mac_addr)),
3274 "slave port (%d) mac address not set to that of primary port",
3275 test_params->slave_port_ids[0]);
3277 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3278 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3279 sizeof(read_mac_addr)),
3280 "slave port (%d) mac address not set to that of primary port",
3281 test_params->slave_port_ids[1]);
3283 /* Set explicit MAC address */
3284 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3285 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3286 "failed to set MAC");
3288 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3289 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3290 sizeof(read_mac_addr)),
3291 "bonded port (%d) mac address not set to that of bonded port",
3292 test_params->bonded_port_id);
3294 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3295 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3296 sizeof(read_mac_addr)),
3297 "slave port (%d) mac address not as expected\n",
3298 test_params->slave_port_ids[0]);
3300 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3301 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3302 sizeof(read_mac_addr)),
3303 "slave port (%d) mac address not set to that of bonded port",
3304 test_params->slave_port_ids[1]);
3306 /* Clean up and remove slaves from bonded device */
3307 return remove_slaves_and_stop_bonded_device();
3310 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3313 test_balance_verify_slave_link_status_change_behaviour(void)
3315 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3316 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3317 struct rte_eth_stats port_stats;
3319 uint8_t slaves[RTE_MAX_ETHPORTS];
3321 int i, j, burst_size, slave_count;
3323 memset(pkt_burst, 0, sizeof(pkt_burst));
3325 /* Initialize bonded device with 4 slaves in round robin mode */
3326 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3327 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3328 "Failed to intialise bonded device");
3330 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3331 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3332 "Failed to set balance xmit policy.");
3335 /* Verify Current Slaves Count /Active Slave Count is */
3336 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3338 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3339 "Number of slaves (%d) is not as expected (%d).",
3340 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3342 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3343 slaves, RTE_MAX_ETHPORTS);
3344 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3345 "Number of active slaves (%d) is not as expected (%d).",
3346 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3348 /* Set 2 slaves link status to down */
3349 virtual_ethdev_simulate_link_status_interrupt(
3350 test_params->slave_port_ids[1], 0);
3351 virtual_ethdev_simulate_link_status_interrupt(
3352 test_params->slave_port_ids[3], 0);
3354 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3355 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3356 "Number of active slaves (%d) is not as expected (%d).",
3359 /* Send to sets of packet burst and verify that they are balanced across
3363 TEST_ASSERT_EQUAL(generate_test_burst(
3364 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3365 "generate_test_burst failed");
3367 TEST_ASSERT_EQUAL(generate_test_burst(
3368 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3369 "generate_test_burst failed");
3371 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3372 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3373 burst_size, "rte_eth_tx_burst failed");
3375 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3376 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3377 burst_size, "rte_eth_tx_burst failed");
3380 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3381 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3382 "(%d) port_stats.opackets (%d) not as expected (%d).",
3383 test_params->bonded_port_id, (int)port_stats.opackets,
3384 burst_size + burst_size);
3386 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3387 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3388 "(%d) port_stats.opackets (%d) not as expected (%d).",
3389 test_params->slave_port_ids[0], (int)port_stats.opackets,
3392 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3393 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3394 "(%d) port_stats.opackets (%d) not as expected (%d).",
3395 test_params->slave_port_ids[2], (int)port_stats.opackets,
3398 /* verify that all packets get send on primary slave when no other slaves
3400 virtual_ethdev_simulate_link_status_interrupt(
3401 test_params->slave_port_ids[2], 0);
3403 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3404 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3405 "Number of active slaves (%d) is not as expected (%d).",
3408 TEST_ASSERT_EQUAL(generate_test_burst(
3409 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3410 "generate_test_burst failed");
3412 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3413 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3414 burst_size, "rte_eth_tx_burst failed");
3416 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3417 TEST_ASSERT_EQUAL(port_stats.opackets,
3418 (uint64_t)(burst_size + burst_size + burst_size),
3419 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3420 test_params->bonded_port_id, (int)port_stats.opackets,
3421 burst_size + burst_size + burst_size);
3423 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3424 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3425 "(%d) port_stats.opackets (%d) not as expected (%d).",
3426 test_params->slave_port_ids[0], (int)port_stats.opackets,
3427 burst_size + burst_size);
3429 virtual_ethdev_simulate_link_status_interrupt(
3430 test_params->slave_port_ids[0], 0);
3431 virtual_ethdev_simulate_link_status_interrupt(
3432 test_params->slave_port_ids[1], 1);
3433 virtual_ethdev_simulate_link_status_interrupt(
3434 test_params->slave_port_ids[2], 1);
3435 virtual_ethdev_simulate_link_status_interrupt(
3436 test_params->slave_port_ids[3], 1);
3438 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3439 TEST_ASSERT_EQUAL(generate_test_burst(
3440 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3441 "Failed to generate packet burst");
3443 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3444 &pkt_burst[i][0], burst_size);
3447 /* Verify that pkts are not received on slaves with link status down */
3449 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3452 /* Verify bonded device rx count */
3453 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3454 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3455 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3456 test_params->bonded_port_id, (int)port_stats.ipackets,
3459 /* free mbufs allocate for rx testing */
3460 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3461 for (j = 0; j < MAX_PKT_BURST; j++) {
3462 if (pkt_burst[i][j] != NULL) {
3463 rte_pktmbuf_free(pkt_burst[i][j]);
3464 pkt_burst[i][j] = NULL;
3469 /* Clean up and remove slaves from bonded device */
3470 return remove_slaves_and_stop_bonded_device();
3474 test_broadcast_tx_burst(void)
3476 int i, pktlen, burst_size;
3477 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3479 struct rte_eth_stats port_stats;
3481 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3482 BONDING_MODE_BROADCAST, 0, 2, 1),
3483 "Failed to intialise bonded device");
3485 initialize_eth_header(test_params->pkt_eth_hdr,
3486 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3487 ETHER_TYPE_IPv4, 0, 0);
3489 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3491 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3492 dst_addr_0, pktlen);
3494 burst_size = 20 * test_params->bonded_slave_count;
3496 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3497 "Burst size specified is greater than supported.");
3499 /* Generate a burst of packets to transmit */
3500 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3501 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3502 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3503 1), burst_size, "Failed to generate packet burst");
3505 /* Send burst on bonded port */
3506 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3507 pkts_burst, burst_size), burst_size,
3508 "Bonded Port (%d) rx burst failed, packets transmitted value "
3509 "not as expected (%d)",
3510 test_params->bonded_port_id, burst_size);
3512 /* Verify bonded port tx stats */
3513 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3514 TEST_ASSERT_EQUAL(port_stats.opackets,
3515 (uint64_t)burst_size * test_params->bonded_slave_count,
3516 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3517 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3520 /* Verify slave ports tx stats */
3521 for (i = 0; i < test_params->bonded_slave_count; i++) {
3522 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3523 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3524 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3525 test_params->bonded_port_id,
3526 (unsigned int)port_stats.opackets, burst_size);
3529 /* Put all slaves down and try and transmit */
3530 for (i = 0; i < test_params->bonded_slave_count; i++) {
3532 virtual_ethdev_simulate_link_status_interrupt(
3533 test_params->slave_port_ids[i], 0);
3536 /* Send burst on bonded port */
3537 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3538 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3539 "transmitted an unexpected number of packets");
3541 /* Clean up and remove slaves from bonded device */
3542 return remove_slaves_and_stop_bonded_device();
3546 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3547 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3548 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3549 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3552 test_broadcast_tx_burst_slave_tx_fail(void)
3554 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3555 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3557 struct rte_eth_stats port_stats;
3561 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3562 BONDING_MODE_BROADCAST, 0,
3563 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3564 "Failed to intialise bonded device");
3566 /* Generate test bursts for transmission */
3567 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3568 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3569 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3570 "Failed to generate test packet burst");
3572 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3573 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3574 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3577 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3578 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3579 virtual_ethdev_tx_burst_fn_set_success(
3580 test_params->slave_port_ids[0],
3582 virtual_ethdev_tx_burst_fn_set_success(
3583 test_params->slave_port_ids[1],
3585 virtual_ethdev_tx_burst_fn_set_success(
3586 test_params->slave_port_ids[2],
3589 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3590 test_params->slave_port_ids[0],
3591 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3593 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3594 test_params->slave_port_ids[1],
3595 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3597 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3598 test_params->slave_port_ids[2],
3599 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3601 /* Transmit burst */
3602 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3603 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3605 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3606 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3607 "Transmitted (%d) packets, expected to transmit (%d) packets",
3608 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3609 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3611 /* Verify that failed packet are expected failed packets */
3612 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3613 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3614 "expected mbuf (%d) pointer %p not expected pointer %p",
3615 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3618 /* Verify slave ports tx stats */
3620 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3622 TEST_ASSERT_EQUAL(port_stats.opackets,
3623 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3624 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3625 "Port (%d) opackets value (%u) not as expected (%d)",
3626 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3627 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3628 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3631 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3633 TEST_ASSERT_EQUAL(port_stats.opackets,
3634 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3635 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3636 "Port (%d) opackets value (%u) not as expected (%d)",
3637 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3638 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3639 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3641 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3643 TEST_ASSERT_EQUAL(port_stats.opackets,
3644 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3645 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3646 "Port (%d) opackets value (%u) not as expected (%d)",
3647 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3648 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3649 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3652 /* Verify that all mbufs who transmission failed have a ref value of one */
3653 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3654 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3655 "mbufs refcnts not as expected");
3657 free_mbufs(&pkts_burst[tx_count],
3658 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3660 /* Clean up and remove slaves from bonded device */
3661 return remove_slaves_and_stop_bonded_device();
3664 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3667 test_broadcast_rx_burst(void)
3669 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3671 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3672 struct rte_eth_stats port_stats;
3674 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3677 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3679 /* Initialize bonded device with 4 slaves in round robin mode */
3680 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3681 BONDING_MODE_BROADCAST, 0, 3, 1),
3682 "Failed to intialise bonded device");
3684 /* Generate test bursts of packets to transmit */
3685 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3686 TEST_ASSERT_EQUAL(generate_test_burst(
3687 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3688 burst_size[i], "failed to generate packet burst");
3691 /* Add rx data to slave 0 */
3692 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3693 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3694 &gen_pkt_burst[i][0], burst_size[i]);
3698 /* Call rx burst on bonded device */
3699 /* Send burst on bonded port */
3700 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3701 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3702 burst_size[0] + burst_size[1] + burst_size[2],
3705 /* Verify bonded device rx count */
3706 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3707 TEST_ASSERT_EQUAL(port_stats.ipackets,
3708 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3709 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3710 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3711 burst_size[0] + burst_size[1] + burst_size[2]);
3714 /* Verify bonded slave devices rx counts */
3715 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3716 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3717 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3718 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3721 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3722 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3723 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3724 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3727 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3728 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3729 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3730 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3733 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3734 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3735 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3736 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3739 /* free mbufs allocate for rx testing */
3740 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3741 for (j = 0; j < MAX_PKT_BURST; j++) {
3742 if (gen_pkt_burst[i][j] != NULL) {
3743 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3744 gen_pkt_burst[i][j] = NULL;
3749 /* Clean up and remove slaves from bonded device */
3750 return remove_slaves_and_stop_bonded_device();
3754 test_broadcast_verify_promiscuous_enable_disable(void)
3758 /* Initialize bonded device with 4 slaves in round robin mode */
3759 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3760 BONDING_MODE_BROADCAST, 0, 4, 1),
3761 "Failed to intialise bonded device");
3763 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3766 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3767 "Port (%d) promiscuous mode not enabled",
3768 test_params->bonded_port_id);
3770 for (i = 0; i < test_params->bonded_slave_count; i++) {
3771 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3772 test_params->slave_port_ids[i]), 1,
3773 "Port (%d) promiscuous mode not enabled",
3774 test_params->slave_port_ids[i]);
3777 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3779 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3780 "Port (%d) promiscuous mode not disabled",
3781 test_params->bonded_port_id);
3783 for (i = 0; i < test_params->bonded_slave_count; i++) {
3784 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3785 test_params->slave_port_ids[i]), 0,
3786 "Port (%d) promiscuous mode not disabled",
3787 test_params->slave_port_ids[i]);
3790 /* Clean up and remove slaves from bonded device */
3791 return remove_slaves_and_stop_bonded_device();
3795 test_broadcast_verify_mac_assignment(void)
3797 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3801 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3802 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3804 /* Initialize bonded device with 4 slaves in round robin mode */
3805 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3806 BONDING_MODE_BROADCAST, 0, 4, 1),
3807 "Failed to intialise bonded device");
3809 /* Verify that all MACs are the same as first slave added to bonded
3811 for (i = 0; i < test_params->bonded_slave_count; i++) {
3812 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3813 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3814 sizeof(read_mac_addr)),
3815 "slave port (%d) mac address not set to that of primary port",
3816 test_params->slave_port_ids[i]);
3819 /* change primary and verify that MAC addresses haven't changed */
3820 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3821 test_params->slave_port_ids[2]),
3822 "Failed to set bonded port (%d) primary port to (%d)",
3823 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3825 for (i = 0; i < test_params->bonded_slave_count; i++) {
3826 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3827 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3828 sizeof(read_mac_addr)),
3829 "slave port (%d) mac address has changed to that of primary "
3830 "port without stop/start toggle of bonded device",
3831 test_params->slave_port_ids[i]);
3834 /* stop / start bonded device and verify that primary MAC address is
3835 * propagated to bonded device and slaves */
3837 rte_eth_dev_stop(test_params->bonded_port_id);
3839 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3840 "Failed to start bonded device");
3842 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3843 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3844 sizeof(read_mac_addr)),
3845 "bonded port (%d) mac address not set to that of new primary port",
3846 test_params->slave_port_ids[i]);
3848 for (i = 0; i < test_params->bonded_slave_count; i++) {
3849 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3850 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3851 sizeof(read_mac_addr)),
3852 "slave port (%d) mac address not set to that of new primary "
3853 "port", test_params->slave_port_ids[i]);
3856 /* Set explicit MAC address */
3857 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3858 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3859 "Failed to set MAC address");
3861 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3862 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3863 sizeof(read_mac_addr)),
3864 "bonded port (%d) mac address not set to that of new primary port",
3865 test_params->slave_port_ids[i]);
3868 for (i = 0; i < test_params->bonded_slave_count; i++) {
3869 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3870 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3871 sizeof(read_mac_addr)),
3872 "slave port (%d) mac address not set to that of new primary "
3873 "port", test_params->slave_port_ids[i]);
3876 /* Clean up and remove slaves from bonded device */
3877 return remove_slaves_and_stop_bonded_device();
3880 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3882 test_broadcast_verify_slave_link_status_change_behaviour(void)
3884 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3885 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3886 struct rte_eth_stats port_stats;
3888 uint8_t slaves[RTE_MAX_ETHPORTS];
3890 int i, j, burst_size, slave_count;
3892 memset(pkt_burst, 0, sizeof(pkt_burst));
3894 /* Initialize bonded device with 4 slaves in round robin mode */
3895 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3896 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3897 1), "Failed to intialise bonded device");
3899 /* Verify Current Slaves Count /Active Slave Count is */
3900 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3902 TEST_ASSERT_EQUAL(slave_count, 4,
3903 "Number of slaves (%d) is not as expected (%d).",
3906 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3907 slaves, RTE_MAX_ETHPORTS);
3908 TEST_ASSERT_EQUAL(slave_count, 4,
3909 "Number of active slaves (%d) is not as expected (%d).",
3912 /* Set 2 slaves link status to down */
3913 virtual_ethdev_simulate_link_status_interrupt(
3914 test_params->slave_port_ids[1], 0);
3915 virtual_ethdev_simulate_link_status_interrupt(
3916 test_params->slave_port_ids[3], 0);
3918 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3919 slaves, RTE_MAX_ETHPORTS);
3920 TEST_ASSERT_EQUAL(slave_count, 2,
3921 "Number of active slaves (%d) is not as expected (%d).",
3924 for (i = 0; i < test_params->bonded_slave_count; i++)
3925 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3927 /* Verify that pkts are not sent on slaves with link status down */
3930 TEST_ASSERT_EQUAL(generate_test_burst(
3931 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3932 "generate_test_burst failed");
3934 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3935 &pkt_burst[0][0], burst_size), burst_size,
3936 "rte_eth_tx_burst failed\n");
3938 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3939 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3940 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3941 test_params->bonded_port_id, (int)port_stats.opackets,
3942 burst_size * slave_count);
3944 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3945 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3946 "(%d) port_stats.opackets not as expected",
3947 test_params->slave_port_ids[0]);
3949 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3950 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3951 "(%d) port_stats.opackets not as expected",
3952 test_params->slave_port_ids[1]);
3954 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3955 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3956 "(%d) port_stats.opackets not as expected",
3957 test_params->slave_port_ids[2]);
3960 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3961 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3962 "(%d) port_stats.opackets not as expected",
3963 test_params->slave_port_ids[3]);
3966 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3967 TEST_ASSERT_EQUAL(generate_test_burst(
3968 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3969 burst_size, "failed to generate packet burst");
3971 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3972 &pkt_burst[i][0], burst_size);
3975 /* Verify that pkts are not received on slaves with link status down */
3976 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3977 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3978 burst_size + burst_size, "rte_eth_rx_burst failed");
3981 /* Verify bonded device rx count */
3982 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3983 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3984 "(%d) port_stats.ipackets not as expected\n",
3985 test_params->bonded_port_id);
3987 /* free mbufs allocate for rx testing */
3988 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3989 for (j = 0; j < MAX_PKT_BURST; j++) {
3990 if (pkt_burst[i][j] != NULL) {
3991 rte_pktmbuf_free(pkt_burst[i][j]);
3992 pkt_burst[i][j] = NULL;
3997 /* Clean up and remove slaves from bonded device */
3998 return remove_slaves_and_stop_bonded_device();
4002 test_reconfigure_bonded_device(void)
4004 test_params->nb_rx_q = 4;
4005 test_params->nb_tx_q = 4;
4007 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4008 "failed to reconfigure bonded device");
4010 test_params->nb_rx_q = 2;
4011 test_params->nb_tx_q = 2;
4013 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4014 "failed to reconfigure bonded device with less rx/tx queues");
4021 test_close_bonded_device(void)
4023 rte_eth_dev_close(test_params->bonded_port_id);
4028 testsuite_teardown(void)
4030 if (test_params->pkt_eth_hdr != NULL) {
4031 free(test_params->pkt_eth_hdr);
4032 test_params->pkt_eth_hdr = NULL;
4035 /* Clean up and remove slaves from bonded device */
4036 return remove_slaves_and_stop_bonded_device();
4040 free_virtualpmd_tx_queue(void)
4042 int i, slave_port, to_free_cnt;
4043 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4045 /* Free tx queue of virtual pmd */
4046 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4048 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4049 test_params->slave_port_ids[slave_port],
4050 pkts_to_free, MAX_PKT_BURST);
4051 for (i = 0; i < to_free_cnt; i++)
4052 rte_pktmbuf_free(pkts_to_free[i]);
4057 test_tlb_tx_burst(void)
4059 int i, burst_size, nb_tx;
4060 uint64_t nb_tx2 = 0;
4061 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4062 struct rte_eth_stats port_stats[32];
4063 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4065 uint64_t floor_obytes = 0, ceiling_obytes = 0;
4067 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4068 (BONDING_MODE_TLB, 1, 3, 1),
4069 "Failed to initialise bonded device");
4071 burst_size = 20 * test_params->bonded_slave_count;
4073 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4074 "Burst size specified is greater than supported.\n");
4077 /* Generate 400000 test bursts in 2s of packets to transmit */
4078 for (i = 0; i < 400000; i++) {
4079 /*test two types of mac src own(bonding) and others */
4081 initialize_eth_header(test_params->pkt_eth_hdr,
4082 (struct ether_addr *)src_mac,
4083 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4085 initialize_eth_header(test_params->pkt_eth_hdr,
4086 (struct ether_addr *)test_params->default_slave_mac,
4087 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4089 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4091 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4092 dst_addr_0, pktlen);
4093 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4094 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4095 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4096 /* Send burst on bonded port */
4097 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4101 free_virtualpmd_tx_queue();
4103 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4104 "number of packet not equal burst size");
4110 /* Verify bonded port tx stats */
4111 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4113 all_bond_opackets = port_stats[0].opackets;
4114 all_bond_obytes = port_stats[0].obytes;
4116 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4117 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4118 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4122 /* Verify slave ports tx stats */
4123 for (i = 0; i < test_params->bonded_slave_count; i++) {
4124 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4125 sum_ports_opackets += port_stats[i].opackets;
4128 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4129 "Total packets sent by slaves is not equal to packets sent by bond interface");
4130 /* distribution of packets on each slave within +/- 10% of the expected value. */
4131 for (i = 0; i < test_params->bonded_slave_count; i++) {
4133 floor_obytes = (all_bond_obytes*90)/(test_params->bonded_slave_count*100);
4134 ceiling_obytes = (all_bond_obytes*110)/(test_params->bonded_slave_count*100);
4135 TEST_ASSERT(port_stats[i].obytes >= floor_obytes &&
4136 port_stats[i].obytes <= ceiling_obytes,
4137 "Distribution is not even");
4139 /* Put all slaves down and try and transmit */
4140 for (i = 0; i < test_params->bonded_slave_count; i++) {
4141 virtual_ethdev_simulate_link_status_interrupt(
4142 test_params->slave_port_ids[i], 0);
4145 /* Send burst on bonded port */
4146 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4148 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4150 /* Clean ugit checkout masterp and remove slaves from bonded device */
4151 return remove_slaves_and_stop_bonded_device();
4154 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4157 test_tlb_rx_burst(void)
4159 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4160 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4162 struct rte_eth_stats port_stats;
4166 uint16_t i, j, nb_rx, burst_size = 17;
4168 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4169 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4171 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4172 "Failed to initialize bonded device");
4175 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4176 TEST_ASSERT(primary_port >= 0,
4177 "failed to get primary slave for bonded port (%d)",
4178 test_params->bonded_port_id);
4180 for (i = 0; i < test_params->bonded_slave_count; i++) {
4181 /* Generate test bursts of packets to transmit */
4182 TEST_ASSERT_EQUAL(generate_test_burst(
4183 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4184 "burst generation failed");
4186 /* Add rx data to slave */
4187 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4188 &gen_pkt_burst[0], burst_size);
4190 /* Call rx burst on bonded device */
4191 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4192 &rx_pkt_burst[0], MAX_PKT_BURST);
4194 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4196 if (test_params->slave_port_ids[i] == primary_port) {
4197 /* Verify bonded device rx count */
4198 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4199 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4200 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4201 test_params->bonded_port_id,
4202 (unsigned int)port_stats.ipackets, burst_size);
4204 /* Verify bonded slave devices rx count */
4205 for (j = 0; j < test_params->bonded_slave_count; j++) {
4206 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4208 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4209 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4210 test_params->slave_port_ids[i],
4211 (unsigned int)port_stats.ipackets, burst_size);
4213 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4214 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4215 test_params->slave_port_ids[i],
4216 (unsigned int)port_stats.ipackets, 0);
4220 for (j = 0; j < test_params->bonded_slave_count; j++) {
4221 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4222 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4223 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4224 test_params->slave_port_ids[i],
4225 (unsigned int)port_stats.ipackets, 0);
4230 for (i = 0; i < burst_size; i++)
4231 rte_pktmbuf_free(rx_pkt_burst[i]);
4233 /* reset bonded device stats */
4234 rte_eth_stats_reset(test_params->bonded_port_id);
4237 /* Clean up and remove slaves from bonded device */
4238 return remove_slaves_and_stop_bonded_device();
4242 test_tlb_verify_promiscuous_enable_disable(void)
4244 int i, primary_port, promiscuous_en;
4246 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4247 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4248 BONDING_MODE_TLB, 0, 4, 1),
4249 "Failed to initialize bonded device");
4251 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4252 TEST_ASSERT(primary_port >= 0,
4253 "failed to get primary slave for bonded port (%d)",
4254 test_params->bonded_port_id);
4256 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4258 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4259 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4260 "Port (%d) promiscuous mode not enabled\n",
4261 test_params->bonded_port_id);
4262 for (i = 0; i < test_params->bonded_slave_count; i++) {
4263 promiscuous_en = rte_eth_promiscuous_get(
4264 test_params->slave_port_ids[i]);
4265 if (primary_port == test_params->slave_port_ids[i]) {
4266 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4267 "Port (%d) promiscuous mode not enabled\n",
4268 test_params->bonded_port_id);
4270 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4271 "Port (%d) promiscuous mode enabled\n",
4272 test_params->bonded_port_id);
4277 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4279 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4280 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4281 "Port (%d) promiscuous mode not disabled\n",
4282 test_params->bonded_port_id);
4284 for (i = 0; i < test_params->bonded_slave_count; i++) {
4285 promiscuous_en = rte_eth_promiscuous_get(
4286 test_params->slave_port_ids[i]);
4287 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4288 "slave port (%d) promiscuous mode not disabled\n",
4289 test_params->slave_port_ids[i]);
4292 /* Clean up and remove slaves from bonded device */
4293 return remove_slaves_and_stop_bonded_device();
4297 test_tlb_verify_mac_assignment(void)
4299 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4301 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4302 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4304 /* Initialize bonded device with 2 slaves in active backup mode */
4305 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4306 BONDING_MODE_TLB, 0, 2, 1),
4307 "Failed to initialize bonded device");
4309 /* Verify that bonded MACs is that of first slave and that the other slave
4310 * MAC hasn't been changed */
4311 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4312 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4313 sizeof(read_mac_addr)),
4314 "bonded port (%d) mac address not set to that of primary port",
4315 test_params->bonded_port_id);
4317 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4318 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4319 sizeof(read_mac_addr)),
4320 "slave port (%d) mac address not set to that of primary port",
4321 test_params->slave_port_ids[0]);
4323 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4324 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4325 sizeof(read_mac_addr)),
4326 "slave port (%d) mac address not as expected",
4327 test_params->slave_port_ids[1]);
4329 /* change primary and verify that MAC addresses haven't changed */
4330 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4331 test_params->slave_port_ids[1]), 0,
4332 "Failed to set bonded port (%d) primary port to (%d)",
4333 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4335 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4336 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4337 sizeof(read_mac_addr)),
4338 "bonded port (%d) mac address not set to that of primary port",
4339 test_params->bonded_port_id);
4341 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4342 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4343 sizeof(read_mac_addr)),
4344 "slave port (%d) mac address not set to that of primary port",
4345 test_params->slave_port_ids[0]);
4347 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4348 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4349 sizeof(read_mac_addr)),
4350 "slave port (%d) mac address not as expected",
4351 test_params->slave_port_ids[1]);
4353 /* stop / start bonded device and verify that primary MAC address is
4354 * propagated to bonded device and slaves */
4356 rte_eth_dev_stop(test_params->bonded_port_id);
4358 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4359 "Failed to start device");
4361 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4362 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4363 sizeof(read_mac_addr)),
4364 "bonded port (%d) mac address not set to that of primary port",
4365 test_params->bonded_port_id);
4367 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4368 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4369 sizeof(read_mac_addr)),
4370 "slave port (%d) mac address not as expected",
4371 test_params->slave_port_ids[0]);
4373 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4374 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4375 sizeof(read_mac_addr)),
4376 "slave port (%d) mac address not set to that of primary port",
4377 test_params->slave_port_ids[1]);
4380 /* Set explicit MAC address */
4381 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4382 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4383 "failed to set MAC addres");
4385 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4386 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4387 sizeof(read_mac_addr)),
4388 "bonded port (%d) mac address not set to that of bonded port",
4389 test_params->bonded_port_id);
4391 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4392 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4393 sizeof(read_mac_addr)),
4394 "slave port (%d) mac address not as expected",
4395 test_params->slave_port_ids[0]);
4397 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4398 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4399 sizeof(read_mac_addr)),
4400 "slave port (%d) mac address not set to that of bonded port",
4401 test_params->slave_port_ids[1]);
4403 /* Clean up and remove slaves from bonded device */
4404 return remove_slaves_and_stop_bonded_device();
4408 test_tlb_verify_slave_link_status_change_failover(void)
4410 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4411 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4412 struct rte_eth_stats port_stats;
4414 uint8_t slaves[RTE_MAX_ETHPORTS];
4416 int i, j, burst_size, slave_count, primary_port;
4420 memset(pkt_burst, 0, sizeof(pkt_burst));
4424 /* Initialize bonded device with 4 slaves in round robin mode */
4425 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4426 BONDING_MODE_TLB, 0,
4427 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4428 "Failed to initialize bonded device with slaves");
4430 /* Verify Current Slaves Count /Active Slave Count is */
4431 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4433 TEST_ASSERT_EQUAL(slave_count, 4,
4434 "Number of slaves (%d) is not as expected (%d).\n",
4437 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4438 slaves, RTE_MAX_ETHPORTS);
4439 TEST_ASSERT_EQUAL(slave_count, (int)4,
4440 "Number of slaves (%d) is not as expected (%d).\n",
4443 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4444 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4445 "Primary port not as expected");
4447 /* Bring 2 slaves down and verify active slave count */
4448 virtual_ethdev_simulate_link_status_interrupt(
4449 test_params->slave_port_ids[1], 0);
4450 virtual_ethdev_simulate_link_status_interrupt(
4451 test_params->slave_port_ids[3], 0);
4453 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4454 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4455 "Number of active slaves (%d) is not as expected (%d).",
4458 virtual_ethdev_simulate_link_status_interrupt(
4459 test_params->slave_port_ids[1], 1);
4460 virtual_ethdev_simulate_link_status_interrupt(
4461 test_params->slave_port_ids[3], 1);
4464 /* Bring primary port down, verify that active slave count is 3 and primary
4466 virtual_ethdev_simulate_link_status_interrupt(
4467 test_params->slave_port_ids[0], 0);
4469 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4470 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4471 "Number of active slaves (%d) is not as expected (%d).",
4474 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4475 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4476 "Primary port not as expected");
4477 rte_delay_us(500000);
4478 /* Verify that pkts are sent on new primary slave */
4479 for (i = 0; i < 4; i++) {
4480 TEST_ASSERT_EQUAL(generate_test_burst(
4481 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4482 "generate_test_burst failed\n");
4483 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4484 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4485 "rte_eth_tx_burst failed\n");
4486 rte_delay_us(11000);
4489 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4490 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4491 "(%d) port_stats.opackets not as expected\n",
4492 test_params->slave_port_ids[0]);
4494 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4495 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4496 "(%d) port_stats.opackets not as expected\n",
4497 test_params->slave_port_ids[1]);
4499 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4500 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4501 "(%d) port_stats.opackets not as expected\n",
4502 test_params->slave_port_ids[2]);
4504 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4505 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4506 "(%d) port_stats.opackets not as expected\n",
4507 test_params->slave_port_ids[3]);
4510 /* Generate packet burst for testing */
4512 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4513 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4517 virtual_ethdev_add_mbufs_to_rx_queue(
4518 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4521 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4522 MAX_PKT_BURST) != burst_size) {
4523 printf("rte_eth_rx_burst\n");
4528 /* Verify bonded device rx count */
4529 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4530 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4531 "(%d) port_stats.ipackets not as expected\n",
4532 test_params->bonded_port_id);
4536 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4537 for (j = 0; j < MAX_PKT_BURST; j++) {
4538 if (pkt_burst[i][j] != NULL) {
4539 rte_pktmbuf_free(pkt_burst[i][j]);
4540 pkt_burst[i][j] = NULL;
4546 /* Clean up and remove slaves from bonded device */
4547 return remove_slaves_and_stop_bonded_device();
4550 #define TEST_ALB_SLAVE_COUNT 2
4552 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4553 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4554 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4555 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4557 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4558 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4559 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4560 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4561 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4564 test_alb_change_mac_in_reply_sent(void)
4566 struct rte_mbuf *pkt;
4567 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4569 struct ether_hdr *eth_pkt;
4570 struct arp_hdr *arp_pkt;
4572 int slave_idx, nb_pkts, pkt_idx;
4575 struct ether_addr bond_mac, client_mac;
4576 struct ether_addr *slave_mac1, *slave_mac2;
4578 TEST_ASSERT_SUCCESS(
4579 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4580 0, TEST_ALB_SLAVE_COUNT, 1),
4581 "Failed to initialize_bonded_device_with_slaves.");
4583 /* Flush tx queue */
4584 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4585 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4587 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4588 test_params->slave_port_ids[slave_idx], pkts_sent,
4593 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4597 * Generating four packets with different mac and ip addresses and sending
4598 * them through the bonding port.
4600 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4601 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4602 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4603 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4605 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4606 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4608 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4610 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4611 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4612 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4613 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4615 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4616 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4618 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4620 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4621 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4622 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4623 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4625 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4626 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4628 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4630 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4631 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4632 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4633 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4635 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4636 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4638 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4641 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4643 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4646 * Checking if packets are properly distributed on bonding ports. Packets
4647 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4649 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4650 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4651 test_params->slave_port_ids[slave_idx], pkts_sent,
4654 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4655 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4656 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4658 if (slave_idx%2 == 0) {
4659 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4664 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4673 retval += remove_slaves_and_stop_bonded_device();
4678 test_alb_reply_from_client(void)
4680 struct ether_hdr *eth_pkt;
4681 struct arp_hdr *arp_pkt;
4683 struct rte_mbuf *pkt;
4684 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4686 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4689 struct ether_addr bond_mac, client_mac;
4690 struct ether_addr *slave_mac1, *slave_mac2;
4692 TEST_ASSERT_SUCCESS(
4693 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4694 0, TEST_ALB_SLAVE_COUNT, 1),
4695 "Failed to initialize_bonded_device_with_slaves.");
4697 /* Flush tx queue */
4698 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4699 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4700 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4701 test_params->slave_port_ids[slave_idx], pkts_sent,
4706 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4710 * Generating four packets with different mac and ip addresses and placing
4711 * them in the rx queue to be received by the bonding driver on rx_burst.
4713 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4714 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4715 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4716 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4718 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4719 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4721 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4724 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4725 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4726 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4727 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4729 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4730 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4732 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4735 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4736 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4737 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4738 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4740 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4741 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4743 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4746 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4747 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4748 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4749 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4751 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4752 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4754 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4758 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4759 * packets to every client in alb table.
4761 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4762 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4764 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4765 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4768 * Checking if update ARP packets were properly send on slave ports.
4770 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4771 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4772 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4773 nb_pkts_sum += nb_pkts;
4775 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4776 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4777 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4779 if (slave_idx%2 == 0) {
4780 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4785 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4793 /* Check if proper number of packets was send */
4794 if (nb_pkts_sum < 4) {
4800 retval += remove_slaves_and_stop_bonded_device();
4805 test_alb_receive_vlan_reply(void)
4807 struct ether_hdr *eth_pkt;
4808 struct vlan_hdr *vlan_pkt;
4809 struct arp_hdr *arp_pkt;
4811 struct rte_mbuf *pkt;
4812 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4814 int slave_idx, nb_pkts, pkt_idx;
4817 struct ether_addr bond_mac, client_mac;
4819 TEST_ASSERT_SUCCESS(
4820 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4821 0, TEST_ALB_SLAVE_COUNT, 1),
4822 "Failed to initialize_bonded_device_with_slaves.");
4824 /* Flush tx queue */
4825 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4826 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4827 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4828 test_params->slave_port_ids[slave_idx], pkts_sent,
4833 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4837 * Generating packet with double VLAN header and placing it in the rx queue.
4839 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4840 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4841 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4842 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4844 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4845 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4846 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4847 vlan_pkt = vlan_pkt+1;
4848 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4849 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4850 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4851 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4853 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4856 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4857 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4860 * Checking if VLAN headers in generated ARP Update packet are correct.
4862 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4863 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4864 test_params->slave_port_ids[slave_idx], pkts_sent,
4867 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4868 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4869 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4870 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4874 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4878 vlan_pkt = vlan_pkt+1;
4879 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4883 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4891 retval += remove_slaves_and_stop_bonded_device();
4896 test_alb_ipv4_tx(void)
4898 int burst_size, retval, pkts_send;
4899 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4903 TEST_ASSERT_SUCCESS(
4904 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4905 0, TEST_ALB_SLAVE_COUNT, 1),
4906 "Failed to initialize_bonded_device_with_slaves.");
4910 /* Generate test bursts of packets to transmit */
4911 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4917 * Checking if ipv4 traffic is transmitted via TLB policy.
4919 pkts_send = rte_eth_tx_burst(
4920 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4921 if (pkts_send != burst_size) {
4927 retval += remove_slaves_and_stop_bonded_device();
4931 static struct unit_test_suite link_bonding_test_suite = {
4932 .suite_name = "Link Bonding Unit Test Suite",
4933 .setup = test_setup,
4934 .teardown = testsuite_teardown,
4935 .unit_test_cases = {
4936 TEST_CASE(test_create_bonded_device),
4937 TEST_CASE(test_create_bonded_device_with_invalid_params),
4938 TEST_CASE(test_add_slave_to_bonded_device),
4939 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4940 TEST_CASE(test_remove_slave_from_bonded_device),
4941 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4942 TEST_CASE(test_get_slaves_from_bonded_device),
4943 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4944 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4945 TEST_CASE(test_start_bonded_device),
4946 TEST_CASE(test_stop_bonded_device),
4947 TEST_CASE(test_set_bonding_mode),
4948 TEST_CASE(test_set_primary_slave),
4949 TEST_CASE(test_set_explicit_bonded_mac),
4950 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4951 TEST_CASE(test_status_interrupt),
4952 TEST_CASE(test_adding_slave_after_bonded_device_started),
4953 TEST_CASE(test_roundrobin_tx_burst),
4954 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4955 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4956 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4957 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4958 TEST_CASE(test_roundrobin_verify_mac_assignment),
4959 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4960 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4961 TEST_CASE(test_activebackup_tx_burst),
4962 TEST_CASE(test_activebackup_rx_burst),
4963 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4964 TEST_CASE(test_activebackup_verify_mac_assignment),
4965 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4966 TEST_CASE(test_balance_xmit_policy_configuration),
4967 TEST_CASE(test_balance_l2_tx_burst),
4968 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4969 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4970 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4971 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4972 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4973 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4974 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4975 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4976 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4977 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4978 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4979 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4980 TEST_CASE(test_balance_rx_burst),
4981 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4982 TEST_CASE(test_balance_verify_mac_assignment),
4983 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4984 TEST_CASE(test_tlb_tx_burst),
4985 TEST_CASE(test_tlb_rx_burst),
4986 TEST_CASE(test_tlb_verify_mac_assignment),
4987 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4988 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4989 TEST_CASE(test_alb_change_mac_in_reply_sent),
4990 TEST_CASE(test_alb_reply_from_client),
4991 TEST_CASE(test_alb_receive_vlan_reply),
4992 TEST_CASE(test_alb_ipv4_tx),
4993 TEST_CASE(test_broadcast_tx_burst),
4994 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4995 TEST_CASE(test_broadcast_rx_burst),
4996 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4997 TEST_CASE(test_broadcast_verify_mac_assignment),
4998 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4999 TEST_CASE(test_reconfigure_bonded_device),
5000 TEST_CASE(test_close_bonded_device),
5002 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
5008 test_link_bonding(void)
5010 return unit_test_suite_runner(&link_bonding_test_suite);
5013 static struct test_command link_bonding_cmd = {
5014 .command = "link_bonding_autotest",
5015 .callback = test_link_bonding,
5017 REGISTER_TEST_COMMAND(link_bonding_cmd);