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 #ifdef RTE_MBUF_REFCNT
711 BONDING_MODE_BROADCAST
715 /* Test supported link bonding modes */
716 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
717 /* Invalid port ID */
718 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
720 "Expected call to failed as invalid port (%d) specified.",
723 /* Non bonded device */
724 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
726 "Expected call to failed as invalid port (%d) specified.",
727 test_params->slave_port_ids[0]);
729 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
731 "Failed to set link bonding mode on port (%d) to (%d).",
732 test_params->bonded_port_id, bonding_modes[i]);
734 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
735 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
736 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
737 bonding_mode, test_params->bonded_port_id,
740 /* Invalid port ID */
741 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
742 TEST_ASSERT(bonding_mode < 0,
743 "Expected call to failed as invalid port (%d) specified.",
746 /* Non bonded device */
747 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
748 TEST_ASSERT(bonding_mode < 0,
749 "Expected call to failed as invalid port (%d) specified.",
750 test_params->slave_port_ids[0]);
753 return remove_slaves_and_stop_bonded_device();
757 test_set_primary_slave(void)
760 struct ether_addr read_mac_addr;
761 struct ether_addr *expected_mac_addr;
763 /* Add 4 slaves to bonded device */
764 for (i = test_params->bonded_slave_count; i < 4; i++)
765 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
766 "Failed to add slave to bonded device.");
768 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
769 BONDING_MODE_ROUND_ROBIN),
770 "Failed to set link bonding mode on port (%d) to (%d).",
771 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
773 /* Invalid port ID */
774 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
775 test_params->slave_port_ids[i]),
776 "Expected call to failed as invalid port specified.");
778 /* Non bonded device */
779 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
780 test_params->slave_port_ids[i]),
781 "Expected call to failed as invalid port specified.");
783 /* Set slave as primary
784 * Verify slave it is now primary slave
785 * Verify that MAC address of bonded device is that of primary slave
786 * Verify that MAC address of all bonded slaves are that of primary slave
788 for (i = 0; i < 4; i++) {
789 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
790 test_params->slave_port_ids[i]),
791 "Failed to set bonded port (%d) primary port to (%d)",
792 test_params->bonded_port_id, test_params->slave_port_ids[i]);
794 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
795 TEST_ASSERT(retval >= 0,
796 "Failed to read primary port from bonded port (%d)\n",
797 test_params->bonded_port_id);
799 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
800 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
801 test_params->bonded_port_id, retval,
802 test_params->slave_port_ids[i]);
804 /* stop/start bonded eth dev to apply new MAC */
805 rte_eth_dev_stop(test_params->bonded_port_id);
807 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
808 "Failed to start bonded port %d",
809 test_params->bonded_port_id);
811 expected_mac_addr = (struct ether_addr *)&slave_mac;
812 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
814 /* Check primary slave MAC */
815 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
816 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
817 sizeof(read_mac_addr)),
818 "bonded port mac address not set to that of primary port\n");
820 /* Check bonded MAC */
821 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
822 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
823 sizeof(read_mac_addr)),
824 "bonded port mac address not set to that of primary port\n");
826 /* Check other slaves MACs */
827 for (j = 0; j < 4; j++) {
829 rte_eth_macaddr_get(test_params->slave_port_ids[j],
831 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
832 sizeof(read_mac_addr)),
833 "slave port mac address not set to that of primary "
840 /* Test with none existent port */
841 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
842 "read primary port from expectedly");
844 /* Test with slave port */
845 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
846 "read primary port from expectedly\n");
848 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
849 "Failed to stop and remove slaves from bonded device");
852 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
853 "read primary port from expectedly\n");
859 test_set_explicit_bonded_mac(void)
862 struct ether_addr read_mac_addr;
863 struct ether_addr *mac_addr;
865 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
867 mac_addr = (struct ether_addr *)explicit_bonded_mac;
869 /* Invalid port ID */
870 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
871 "Expected call to failed as invalid port specified.");
873 /* Non bonded device */
874 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
875 test_params->slave_port_ids[0], mac_addr),
876 "Expected call to failed as invalid port specified.");
878 /* NULL MAC address */
879 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
880 test_params->bonded_port_id, NULL),
881 "Expected call to failed as NULL MAC specified");
883 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
884 test_params->bonded_port_id, mac_addr),
885 "Failed to set MAC address on bonded port (%d)",
886 test_params->bonded_port_id);
888 /* Add 4 slaves to bonded device */
889 for (i = test_params->bonded_slave_count; i < 4; i++) {
890 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
891 "Failed to add slave to bonded device.\n");
894 /* Check bonded MAC */
895 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
896 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
897 "bonded port mac address not set to that of primary port");
899 /* Check other slaves MACs */
900 for (i = 0; i < 4; i++) {
901 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
902 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
903 sizeof(read_mac_addr)),
904 "slave port mac address not set to that of primary port");
907 /* test resetting mac address on bonded device */
909 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
910 "Failed to reset MAC address on bonded port (%d)",
911 test_params->bonded_port_id);
914 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
915 "Reset MAC address on bonded port (%d) unexpectedly",
916 test_params->slave_port_ids[1]);
918 /* test resetting mac address on bonded device with no slaves */
919 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
920 "Failed to remove slaves and stop bonded device");
922 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
923 "Failed to reset MAC address on bonded port (%d)",
924 test_params->bonded_port_id);
929 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
932 test_set_bonded_port_initialization_mac_assignment(void)
934 int i, slave_count, bonded_port_id;
936 uint8_t slaves[RTE_MAX_ETHPORTS];
937 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
939 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
941 /* Initialize default values for MAC addresses */
942 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
943 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
946 * 1. a - Create / configure bonded / slave ethdevs
948 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
949 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
950 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
952 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
953 "Failed to configure bonded ethdev");
955 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
956 char pmd_name[RTE_ETH_NAME_MAX_LEN];
958 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
960 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
962 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
963 &slave_mac_addr, rte_socket_id(), 1);
965 TEST_ASSERT(slave_port_ids[i] >= 0,
966 "Failed to create slave ethdev %s", pmd_name);
968 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
969 "Failed to configure virtual ethdev %s",
975 * 2. Add slave ethdevs to bonded device
977 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
978 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
980 "Failed to add slave (%d) to bonded port (%d).",
981 slave_port_ids[i], bonded_port_id);
984 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
986 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
987 "Number of slaves (%d) is not as expected (%d)",
988 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
992 * 3. Set explicit MAC address on bonded ethdev
994 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
995 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
997 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
998 bonded_port_id, &bonded_mac_addr),
999 "Failed to set MAC address on bonded port (%d)",
1003 /* 4. a - Start bonded ethdev
1004 * b - Enable slave devices
1005 * c - Verify bonded/slaves ethdev MAC addresses
1007 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1008 "Failed to start bonded pmd eth device %d.",
1011 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1012 virtual_ethdev_simulate_link_status_interrupt(
1013 slave_port_ids[i], 1);
1016 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1017 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1018 sizeof(read_mac_addr)),
1019 "bonded port mac address not as expected");
1021 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1022 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1023 sizeof(read_mac_addr)),
1024 "slave port 0 mac address not as expected");
1026 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1027 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1028 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1029 sizeof(read_mac_addr)),
1030 "slave port 1 mac address not as expected");
1032 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1033 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1034 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1035 sizeof(read_mac_addr)),
1036 "slave port 2 mac address not as expected");
1039 /* 7. a - Change primary port
1040 * b - Stop / Start bonded port
1041 * d - Verify slave ethdev MAC addresses
1043 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1045 "failed to set primary port on bonded device.");
1047 rte_eth_dev_stop(bonded_port_id);
1048 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1049 "Failed to start bonded pmd eth device %d.",
1052 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1053 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1054 sizeof(read_mac_addr)),
1055 "bonded port mac address not as expected");
1057 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1058 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1059 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1060 sizeof(read_mac_addr)),
1061 "slave port 0 mac address not as expected");
1063 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1064 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1065 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1066 sizeof(read_mac_addr)),
1067 "slave port 1 mac address not as expected");
1069 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1070 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1071 sizeof(read_mac_addr)),
1072 "slave port 2 mac address not as expected");
1074 /* 6. a - Stop bonded ethdev
1075 * b - remove slave ethdevs
1076 * c - Verify slave ethdevs MACs are restored
1078 rte_eth_dev_stop(bonded_port_id);
1080 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1081 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1083 "Failed to remove slave %d from bonded port (%d).",
1084 slave_port_ids[i], bonded_port_id);
1087 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1090 TEST_ASSERT_EQUAL(slave_count, 0,
1091 "Number of slaves (%d) is great than expected (%d).",
1094 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1095 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1096 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1097 sizeof(read_mac_addr)),
1098 "slave port 0 mac address not as expected");
1100 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1101 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1102 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1103 sizeof(read_mac_addr)),
1104 "slave port 1 mac address not as expected");
1106 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1107 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1108 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1109 sizeof(read_mac_addr)),
1110 "slave port 2 mac address not as expected");
1117 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1118 uint8_t number_of_slaves, uint8_t enable_slave)
1120 /* Configure bonded device */
1121 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1122 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1123 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1126 /* Add slaves to bonded device */
1127 while (number_of_slaves > test_params->bonded_slave_count)
1128 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1129 "Failed to add slave (%d to bonding port (%d).",
1130 test_params->bonded_slave_count - 1,
1131 test_params->bonded_port_id);
1133 /* Set link bonding mode */
1134 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1136 "Failed to set link bonding mode on port (%d) to (%d).",
1137 test_params->bonded_port_id, bonding_mode);
1139 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1140 "Failed to start bonded pmd eth device %d.",
1141 test_params->bonded_port_id);
1144 enable_bonded_slaves();
1150 test_adding_slave_after_bonded_device_started(void)
1154 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1155 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1156 "Failed to add slaves to bonded device");
1158 /* Enabled slave devices */
1159 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1160 virtual_ethdev_simulate_link_status_interrupt(
1161 test_params->slave_port_ids[i], 1);
1164 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1165 test_params->slave_port_ids[test_params->bonded_slave_count]),
1166 "Failed to add slave to bonded port.\n");
1168 rte_eth_stats_reset(
1169 test_params->slave_port_ids[test_params->bonded_slave_count]);
1171 test_params->bonded_slave_count++;
1173 return remove_slaves_and_stop_bonded_device();
1176 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1177 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1179 int test_lsc_interrupt_count;
1183 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1184 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1186 pthread_mutex_lock(&mutex);
1187 test_lsc_interrupt_count++;
1189 pthread_cond_signal(&cvar);
1190 pthread_mutex_unlock(&mutex);
1194 lsc_timeout(int wait_us)
1201 gettimeofday(&tp, NULL);
1203 /* Convert from timeval to timespec */
1204 ts.tv_sec = tp.tv_sec;
1205 ts.tv_nsec = tp.tv_usec * 1000;
1206 ts.tv_nsec += wait_us * 1000;
1208 pthread_mutex_lock(&mutex);
1209 if (test_lsc_interrupt_count < 1)
1210 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1212 pthread_mutex_unlock(&mutex);
1214 if (retval == 0 && test_lsc_interrupt_count < 1)
1221 test_status_interrupt(void)
1224 uint8_t slaves[RTE_MAX_ETHPORTS];
1226 /* initialized bonding device with T slaves */
1227 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1228 BONDING_MODE_ROUND_ROBIN, 1,
1229 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1230 "Failed to initialise bonded device");
1232 test_lsc_interrupt_count = 0;
1234 /* register link status change interrupt callback */
1235 rte_eth_dev_callback_register(test_params->bonded_port_id,
1236 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1237 &test_params->bonded_port_id);
1239 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1240 slaves, RTE_MAX_ETHPORTS);
1242 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1243 "Number of active slaves (%d) is not as expected (%d)",
1244 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1246 /* Bring all 4 slaves link status to down and test that we have received a
1248 virtual_ethdev_simulate_link_status_interrupt(
1249 test_params->slave_port_ids[0], 0);
1250 virtual_ethdev_simulate_link_status_interrupt(
1251 test_params->slave_port_ids[1], 0);
1252 virtual_ethdev_simulate_link_status_interrupt(
1253 test_params->slave_port_ids[2], 0);
1255 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1256 "Received a link status change interrupt unexpectedly");
1258 virtual_ethdev_simulate_link_status_interrupt(
1259 test_params->slave_port_ids[3], 0);
1261 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1262 "timed out waiting for interrupt");
1264 TEST_ASSERT(test_lsc_interrupt_count > 0,
1265 "Did not receive link status change interrupt");
1267 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1268 slaves, RTE_MAX_ETHPORTS);
1270 TEST_ASSERT_EQUAL(slave_count, 0,
1271 "Number of active slaves (%d) is not as expected (%d)",
1274 /* bring one slave port up so link status will change */
1275 test_lsc_interrupt_count = 0;
1277 virtual_ethdev_simulate_link_status_interrupt(
1278 test_params->slave_port_ids[0], 1);
1280 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1281 "timed out waiting for interrupt");
1283 /* test that we have received another lsc interrupt */
1284 TEST_ASSERT(test_lsc_interrupt_count > 0,
1285 "Did not receive link status change interrupt");
1287 /* Verify that calling the same slave lsc interrupt doesn't cause another
1288 * lsc interrupt from bonded device */
1289 test_lsc_interrupt_count = 0;
1291 virtual_ethdev_simulate_link_status_interrupt(
1292 test_params->slave_port_ids[0], 1);
1294 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1295 "received unexpected interrupt");
1297 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1298 "Did not receive link status change interrupt");
1301 /* unregister lsc callback before exiting */
1302 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1303 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1304 &test_params->bonded_port_id);
1306 /* Clean up and remove slaves from bonded device */
1307 return remove_slaves_and_stop_bonded_device();
1311 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1312 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1313 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1315 uint16_t pktlen, generated_burst_size, ether_type;
1319 ether_type = ETHER_TYPE_IPv4;
1321 ether_type = ETHER_TYPE_IPv6;
1324 initialize_eth_header(test_params->pkt_eth_hdr,
1325 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1326 ether_type, vlan, vlan_id);
1328 initialize_eth_header(test_params->pkt_eth_hdr,
1329 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1330 ether_type, vlan, vlan_id);
1333 if (toggle_udp_port)
1334 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1337 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1342 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1343 dst_addr_1, pktlen);
1345 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1346 dst_addr_0, pktlen);
1348 ip_hdr = test_params->pkt_ipv4_hdr;
1351 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1352 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1355 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1356 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1359 ip_hdr = test_params->pkt_ipv6_hdr;
1362 /* Generate burst of packets to transmit */
1363 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1364 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1365 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1367 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1368 "Failed to generate packet burst");
1370 return generated_burst_size;
1373 /** Round Robin Mode Tests */
1376 test_roundrobin_tx_burst(void)
1379 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1380 struct rte_eth_stats port_stats;
1382 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1383 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1384 "Failed to intialise bonded device");
1386 burst_size = 20 * test_params->bonded_slave_count;
1388 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1389 "Burst size specified is greater than supported.");
1391 /* Generate test bursts of packets to transmit */
1392 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1393 burst_size, "failed to generate test burst");
1395 /* Send burst on bonded port */
1396 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1397 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1400 /* Verify bonded port tx stats */
1401 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1402 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1403 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1404 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1407 /* Verify slave ports tx stats */
1408 for (i = 0; i < test_params->bonded_slave_count; i++) {
1409 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1410 TEST_ASSERT_EQUAL(port_stats.opackets,
1411 (uint64_t)burst_size / test_params->bonded_slave_count,
1412 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1413 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1414 burst_size / test_params->bonded_slave_count);
1417 /* Put all slaves down and try and transmit */
1418 for (i = 0; i < test_params->bonded_slave_count; i++) {
1419 virtual_ethdev_simulate_link_status_interrupt(
1420 test_params->slave_port_ids[i], 0);
1423 /* Send burst on bonded port */
1424 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1425 pkt_burst, burst_size), 0,
1426 "tx burst return unexpected value");
1428 /* Clean up and remove slaves from bonded device */
1429 return remove_slaves_and_stop_bonded_device();
1432 #ifdef RTE_MBUF_REFCNT
1434 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1438 for (i = 0; i < nb_mbufs; i++) {
1439 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1440 TEST_ASSERT_EQUAL(refcnt, val,
1441 "mbuf ref count (%d)is not the expected value (%d)",
1450 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1454 for (i = 0; i < nb_mbufs; i++)
1455 rte_pktmbuf_free(mbufs[i]);
1458 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1459 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1460 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1461 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1464 test_roundrobin_tx_burst_slave_tx_fail(void)
1466 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1467 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1469 struct rte_eth_stats port_stats;
1471 int i, first_fail_idx, tx_count;
1473 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1474 BONDING_MODE_ROUND_ROBIN, 0,
1475 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1476 "Failed to intialise bonded device");
1478 /* Generate test bursts of packets to transmit */
1479 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1480 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1481 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1482 "Failed to generate test packet burst");
1484 /* Copy references to packets which we expect not to be transmitted */
1485 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1486 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1487 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1488 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1490 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1491 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1492 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1495 /* Set virtual slave to only fail transmission of
1496 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1497 virtual_ethdev_tx_burst_fn_set_success(
1498 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1501 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1502 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1503 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1505 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1506 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1508 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1509 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1510 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1511 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1512 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1514 /* Verify that failed packet are expected failed packets */
1515 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1516 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1517 "expected mbuf (%d) pointer %p not expected pointer %p",
1518 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1521 /* Verify bonded port tx stats */
1522 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1524 TEST_ASSERT_EQUAL(port_stats.opackets,
1525 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1526 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1527 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1528 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1529 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1530 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1532 /* Verify slave ports tx stats */
1533 for (i = 0; i < test_params->bonded_slave_count; i++) {
1534 int slave_expected_tx_count;
1536 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1538 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1539 test_params->bonded_slave_count;
1541 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1542 slave_expected_tx_count = slave_expected_tx_count -
1543 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1545 TEST_ASSERT_EQUAL(port_stats.opackets,
1546 (uint64_t)slave_expected_tx_count,
1547 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1548 test_params->slave_port_ids[i],
1549 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1552 #ifdef RTE_MBUF_REFCNT
1553 /* Verify that all mbufs have a ref value of zero */
1554 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1555 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1556 "mbufs refcnts not as expected");
1558 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1560 /* Clean up and remove slaves from bonded device */
1561 return remove_slaves_and_stop_bonded_device();
1565 test_roundrobin_rx_burst_on_single_slave(void)
1567 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1568 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1570 struct rte_eth_stats port_stats;
1572 int i, j, burst_size = 25;
1574 /* Initialize bonded device with 4 slaves in round robin mode */
1575 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1576 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1577 "Failed to initialize bonded device with slaves");
1579 /* Generate test bursts of packets to transmit */
1580 TEST_ASSERT_EQUAL(generate_test_burst(
1581 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1582 "burst generation failed");
1584 for (i = 0; i < test_params->bonded_slave_count; i++) {
1585 /* Add rx data to slave */
1586 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1587 &gen_pkt_burst[0], burst_size);
1589 /* Call rx burst on bonded device */
1590 /* Send burst on bonded port */
1591 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1592 test_params->bonded_port_id, 0, rx_pkt_burst,
1593 MAX_PKT_BURST), burst_size,
1594 "round-robin rx burst failed");
1596 /* Verify bonded device rx count */
1597 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1598 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1599 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1600 test_params->bonded_port_id,
1601 (unsigned int)port_stats.ipackets, burst_size);
1605 /* Verify bonded slave devices rx count */
1606 /* Verify slave ports tx stats */
1607 for (j = 0; j < test_params->bonded_slave_count; j++) {
1608 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1611 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1612 "Slave Port (%d) ipackets value (%u) not as expected"
1613 " (%d)", test_params->slave_port_ids[i],
1614 (unsigned int)port_stats.ipackets, burst_size);
1616 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1617 "Slave Port (%d) ipackets value (%u) not as expected"
1618 " (%d)", test_params->slave_port_ids[i],
1619 (unsigned int)port_stats.ipackets, 0);
1622 /* Reset bonded slaves stats */
1623 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1625 /* reset bonded device stats */
1626 rte_eth_stats_reset(test_params->bonded_port_id);
1630 for (i = 0; i < MAX_PKT_BURST; i++) {
1631 if (gen_pkt_burst[i] != NULL)
1632 rte_pktmbuf_free(gen_pkt_burst[i]);
1634 if (rx_pkt_burst[i] != NULL)
1635 rte_pktmbuf_free(rx_pkt_burst[i]);
1639 /* Clean up and remove slaves from bonded device */
1640 return remove_slaves_and_stop_bonded_device();
1643 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1646 test_roundrobin_rx_burst_on_multiple_slaves(void)
1648 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1650 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1651 struct rte_eth_stats port_stats;
1653 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1656 /* Initialize bonded device with 4 slaves in round robin mode */
1657 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1658 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1659 "Failed to initialize bonded device with slaves");
1661 /* Generate test bursts of packets to transmit */
1662 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1663 TEST_ASSERT_EQUAL(generate_test_burst(
1664 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1665 burst_size[i], "burst generation failed");
1668 /* Add rx data to slaves */
1669 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1670 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1671 &gen_pkt_burst[i][0], burst_size[i]);
1674 /* Call rx burst on bonded device */
1675 /* Send burst on bonded port */
1676 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1678 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1679 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1680 burst_size[0] + burst_size[1] + burst_size[2]);
1682 /* Verify bonded device rx count */
1683 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1684 TEST_ASSERT_EQUAL(port_stats.ipackets,
1685 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1686 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1687 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1688 burst_size[0] + burst_size[1] + burst_size[2]);
1690 /* Verify bonded slave devices rx counts */
1691 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1692 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1693 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1694 test_params->slave_port_ids[0],
1695 (unsigned int)port_stats.ipackets, burst_size[0]);
1697 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1698 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1699 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1700 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1703 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1704 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1705 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1706 test_params->slave_port_ids[2],
1707 (unsigned int)port_stats.ipackets, burst_size[2]);
1709 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1710 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1711 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1712 test_params->slave_port_ids[3],
1713 (unsigned int)port_stats.ipackets, 0);
1716 for (i = 0; i < MAX_PKT_BURST; i++) {
1717 if (rx_pkt_burst[i] != NULL)
1718 rte_pktmbuf_free(rx_pkt_burst[i]);
1721 /* Clean up and remove slaves from bonded device */
1722 return remove_slaves_and_stop_bonded_device();
1726 test_roundrobin_verify_mac_assignment(void)
1728 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1732 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1733 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1735 /* Initialize bonded device with 4 slaves in round robin mode */
1736 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1737 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1738 "Failed to initialize bonded device with slaves");
1740 /* Verify that all MACs are the same as first slave added to bonded dev */
1741 for (i = 0; i < test_params->bonded_slave_count; i++) {
1742 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1743 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1744 sizeof(read_mac_addr)),
1745 "slave port (%d) mac address not set to that of primary port",
1746 test_params->slave_port_ids[i]);
1749 /* change primary and verify that MAC addresses haven't changed */
1750 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1751 test_params->slave_port_ids[2]),
1752 "Failed to set bonded port (%d) primary port to (%d)",
1753 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1755 for (i = 0; i < test_params->bonded_slave_count; i++) {
1756 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1757 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1758 sizeof(read_mac_addr)),
1759 "slave port (%d) mac address has changed to that of primary"
1760 " port without stop/start toggle of bonded device",
1761 test_params->slave_port_ids[i]);
1764 /* stop / start bonded device and verify that primary MAC address is
1765 * propagate to bonded device and slaves */
1766 rte_eth_dev_stop(test_params->bonded_port_id);
1768 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1769 "Failed to start bonded device");
1771 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1772 TEST_ASSERT_SUCCESS(
1773 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1774 "bonded port (%d) mac address not set to that of new primary port",
1775 test_params->slave_port_ids[i]);
1777 for (i = 0; i < test_params->bonded_slave_count; i++) {
1778 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1779 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1780 sizeof(read_mac_addr)),
1781 "slave port (%d) mac address not set to that of new primary"
1782 " port", test_params->slave_port_ids[i]);
1785 /* Set explicit MAC address */
1786 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1787 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1788 "Failed to set MAC");
1790 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1791 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1792 sizeof(read_mac_addr)),
1793 "bonded port (%d) mac address not set to that of new primary port",
1794 test_params->slave_port_ids[i]);
1796 for (i = 0; i < test_params->bonded_slave_count; i++) {
1797 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1798 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1799 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1800 " that of new primary port\n", test_params->slave_port_ids[i]);
1803 /* Clean up and remove slaves from bonded device */
1804 return remove_slaves_and_stop_bonded_device();
1808 test_roundrobin_verify_promiscuous_enable_disable(void)
1810 int i, promiscuous_en;
1812 /* Initialize bonded device with 4 slaves in round robin mode */
1813 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1814 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1815 "Failed to initialize bonded device with slaves");
1817 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1819 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1820 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1821 "Port (%d) promiscuous mode not enabled",
1822 test_params->bonded_port_id);
1824 for (i = 0; i < test_params->bonded_slave_count; i++) {
1825 promiscuous_en = rte_eth_promiscuous_get(
1826 test_params->slave_port_ids[i]);
1827 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1828 "slave port (%d) promiscuous mode not enabled",
1829 test_params->slave_port_ids[i]);
1832 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1834 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1835 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1836 "Port (%d) promiscuous mode not disabled\n",
1837 test_params->bonded_port_id);
1839 for (i = 0; i < test_params->bonded_slave_count; i++) {
1840 promiscuous_en = rte_eth_promiscuous_get(
1841 test_params->slave_port_ids[i]);
1842 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1843 "Port (%d) promiscuous mode not disabled\n",
1844 test_params->slave_port_ids[i]);
1847 /* Clean up and remove slaves from bonded device */
1848 return remove_slaves_and_stop_bonded_device();
1851 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1852 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1855 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1857 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1858 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1859 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1861 struct rte_eth_stats port_stats;
1862 uint8_t slaves[RTE_MAX_ETHPORTS];
1864 int i, burst_size, slave_count;
1866 /* NULL all pointers in array to simplify cleanup */
1867 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1869 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1870 * in round robin mode */
1871 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1872 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1873 "Failed to initialize bonded device with slaves");
1875 /* Verify Current Slaves Count /Active Slave Count is */
1876 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1878 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1879 "Number of slaves (%d) is not as expected (%d).",
1880 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1882 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1883 slaves, RTE_MAX_ETHPORTS);
1884 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1885 "Number of active slaves (%d) is not as expected (%d).",
1886 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1888 /* Set 2 slaves eth_devs link status to down */
1889 virtual_ethdev_simulate_link_status_interrupt(
1890 test_params->slave_port_ids[1], 0);
1891 virtual_ethdev_simulate_link_status_interrupt(
1892 test_params->slave_port_ids[3], 0);
1894 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1895 slaves, RTE_MAX_ETHPORTS);
1896 TEST_ASSERT_EQUAL(slave_count,
1897 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1898 "Number of active slaves (%d) is not as expected (%d).\n",
1899 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1903 /* Verify that pkts are not sent on slaves with link status down:
1905 * 1. Generate test burst of traffic
1906 * 2. Transmit burst on bonded eth_dev
1907 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1908 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1911 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1912 burst_size, "generate_test_burst failed");
1914 rte_eth_stats_reset(test_params->bonded_port_id);
1918 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1919 burst_size), burst_size, "rte_eth_tx_burst failed");
1921 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1922 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1923 "Port (%d) opackets stats (%d) not expected (%d) value",
1924 test_params->bonded_port_id, (int)port_stats.opackets,
1927 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1928 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1929 "Port (%d) opackets stats (%d) not expected (%d) value",
1930 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1932 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1933 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1934 "Port (%d) opackets stats (%d) not expected (%d) value",
1935 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1937 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1938 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1939 "Port (%d) opackets stats (%d) not expected (%d) value",
1940 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1942 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1943 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1944 "Port (%d) opackets stats (%d) not expected (%d) value",
1945 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1947 /* Verify that pkts are not sent on slaves with link status down:
1949 * 1. Generate test bursts of traffic
1950 * 2. Add bursts on to virtual eth_devs
1951 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1952 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1953 * 4. Verify stats for bonded eth_dev
1954 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1956 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1957 TEST_ASSERT_EQUAL(generate_test_burst(
1958 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1959 burst_size, "failed to generate packet burst");
1961 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1962 &gen_pkt_burst[i][0], burst_size);
1965 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1966 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1967 burst_size + burst_size,
1968 "rte_eth_rx_burst failed");
1970 /* Verify bonded device rx count */
1971 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1972 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1973 "(%d) port_stats.ipackets not as expected\n",
1974 test_params->bonded_port_id);
1977 for (i = 0; i < MAX_PKT_BURST; i++) {
1978 if (rx_pkt_burst[i] != NULL)
1979 rte_pktmbuf_free(rx_pkt_burst[i]);
1981 if (gen_pkt_burst[1][i] != NULL)
1982 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1984 if (gen_pkt_burst[3][i] != NULL)
1985 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1988 /* Clean up and remove slaves from bonded device */
1989 return remove_slaves_and_stop_bonded_device();
1992 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1994 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1997 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
2000 test_roundrobin_verfiy_polling_slave_link_status_change(void)
2002 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
2003 char slave_name[RTE_ETH_NAME_MAX_LEN];
2007 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2008 /* Generate slave name / MAC address */
2009 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2010 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2012 /* Create slave devices with no ISR Support */
2013 if (polling_test_slaves[i] == -1) {
2014 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2015 rte_socket_id(), 0);
2016 TEST_ASSERT(polling_test_slaves[i] >= 0,
2017 "Failed to create virtual virtual ethdev %s\n", slave_name);
2019 /* Configure slave */
2020 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2021 "Failed to configure virtual ethdev %s(%d)", slave_name,
2022 polling_test_slaves[i]);
2025 /* Add slave to bonded device */
2026 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2027 polling_test_slaves[i]),
2028 "Failed to add slave %s(%d) to bonded device %d",
2029 slave_name, polling_test_slaves[i],
2030 test_params->bonded_port_id);
2033 /* Initialize bonded device */
2034 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2035 "Failed to configure bonded device %d",
2036 test_params->bonded_port_id);
2039 /* Register link status change interrupt callback */
2040 rte_eth_dev_callback_register(test_params->bonded_port_id,
2041 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2042 &test_params->bonded_port_id);
2044 /* link status change callback for first slave link up */
2045 test_lsc_interrupt_count = 0;
2047 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2049 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2052 /* no link status change callback for second slave link up */
2053 test_lsc_interrupt_count = 0;
2055 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2057 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2059 /* link status change callback for both slave links down */
2060 test_lsc_interrupt_count = 0;
2062 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2063 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2065 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2067 /* Un-Register link status change interrupt callback */
2068 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2069 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2070 &test_params->bonded_port_id);
2073 /* Clean up and remove slaves from bonded device */
2074 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2076 TEST_ASSERT_SUCCESS(
2077 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2078 polling_test_slaves[i]),
2079 "Failed to remove slave %d from bonded port (%d)",
2080 polling_test_slaves[i], test_params->bonded_port_id);
2083 return remove_slaves_and_stop_bonded_device();
2087 /** Active Backup Mode Tests */
2090 test_activebackup_tx_burst(void)
2092 int i, pktlen, primary_port, burst_size;
2093 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2094 struct rte_eth_stats port_stats;
2096 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2097 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2098 "Failed to initialize bonded device with slaves");
2100 initialize_eth_header(test_params->pkt_eth_hdr,
2101 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2102 ETHER_TYPE_IPv4, 0, 0);
2103 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2105 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2106 dst_addr_0, pktlen);
2108 burst_size = 20 * test_params->bonded_slave_count;
2110 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2111 "Burst size specified is greater than supported.");
2113 /* Generate a burst of packets to transmit */
2114 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2115 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2116 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2117 burst_size, "failed to generate burst correctly");
2119 /* Send burst on bonded port */
2120 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2121 burst_size), burst_size, "tx burst failed");
2123 /* Verify bonded port tx stats */
2124 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2125 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2126 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2127 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2130 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2132 /* Verify slave ports tx stats */
2133 for (i = 0; i < test_params->bonded_slave_count; i++) {
2134 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2135 if (test_params->slave_port_ids[i] == primary_port) {
2136 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2137 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2138 test_params->bonded_port_id,
2139 (unsigned int)port_stats.opackets,
2140 burst_size / test_params->bonded_slave_count);
2142 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2143 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2144 test_params->bonded_port_id,
2145 (unsigned int)port_stats.opackets, 0);
2149 /* Put all slaves down and try and transmit */
2150 for (i = 0; i < test_params->bonded_slave_count; i++) {
2151 virtual_ethdev_simulate_link_status_interrupt(
2152 test_params->slave_port_ids[i], 0);
2155 /* Send burst on bonded port */
2156 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2157 pkts_burst, burst_size), 0, "Sending empty burst failed");
2159 /* Clean up and remove slaves from bonded device */
2160 return remove_slaves_and_stop_bonded_device();
2163 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2166 test_activebackup_rx_burst(void)
2168 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2169 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2171 struct rte_eth_stats port_stats;
2175 int i, j, burst_size = 17;
2177 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2178 BONDING_MODE_ACTIVE_BACKUP, 0,
2179 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2180 "Failed to initialize bonded device with slaves");
2182 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2183 TEST_ASSERT(primary_port >= 0,
2184 "failed to get primary slave for bonded port (%d)",
2185 test_params->bonded_port_id);
2187 for (i = 0; i < test_params->bonded_slave_count; i++) {
2188 /* Generate test bursts of packets to transmit */
2189 TEST_ASSERT_EQUAL(generate_test_burst(
2190 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2191 burst_size, "burst generation failed");
2193 /* Add rx data to slave */
2194 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2195 &gen_pkt_burst[0], burst_size);
2197 /* Call rx burst on bonded device */
2198 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2199 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2200 "rte_eth_rx_burst failed");
2202 if (test_params->slave_port_ids[i] == primary_port) {
2203 /* Verify bonded device rx count */
2204 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2205 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2206 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2207 test_params->bonded_port_id,
2208 (unsigned int)port_stats.ipackets, burst_size);
2210 /* Verify bonded slave devices rx count */
2211 for (j = 0; j < test_params->bonded_slave_count; j++) {
2212 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2214 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2215 "Slave Port (%d) ipackets value (%u) not as "
2216 "expected (%d)", test_params->slave_port_ids[i],
2217 (unsigned int)port_stats.ipackets, burst_size);
2219 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2220 "Slave Port (%d) ipackets value (%u) not as "
2221 "expected (%d)\n", test_params->slave_port_ids[i],
2222 (unsigned int)port_stats.ipackets, 0);
2226 for (j = 0; j < test_params->bonded_slave_count; j++) {
2227 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2228 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2229 "Slave Port (%d) ipackets value (%u) not as expected "
2230 "(%d)", test_params->slave_port_ids[i],
2231 (unsigned int)port_stats.ipackets, 0);
2236 for (i = 0; i < MAX_PKT_BURST; i++) {
2237 if (rx_pkt_burst[i] != NULL) {
2238 rte_pktmbuf_free(rx_pkt_burst[i]);
2239 rx_pkt_burst[i] = NULL;
2243 /* reset bonded device stats */
2244 rte_eth_stats_reset(test_params->bonded_port_id);
2247 /* Clean up and remove slaves from bonded device */
2248 return remove_slaves_and_stop_bonded_device();
2252 test_activebackup_verify_promiscuous_enable_disable(void)
2254 int i, primary_port, promiscuous_en;
2256 /* Initialize bonded device with 4 slaves in round robin mode */
2257 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2258 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2259 "Failed to initialize bonded device with slaves");
2261 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2262 TEST_ASSERT(primary_port >= 0,
2263 "failed to get primary slave for bonded port (%d)",
2264 test_params->bonded_port_id);
2266 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2268 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2269 "Port (%d) promiscuous mode not enabled",
2270 test_params->bonded_port_id);
2272 for (i = 0; i < test_params->bonded_slave_count; i++) {
2273 promiscuous_en = rte_eth_promiscuous_get(
2274 test_params->slave_port_ids[i]);
2275 if (primary_port == test_params->slave_port_ids[i]) {
2276 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2277 "slave port (%d) promiscuous mode not enabled",
2278 test_params->slave_port_ids[i]);
2280 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2281 "slave port (%d) promiscuous mode enabled",
2282 test_params->slave_port_ids[i]);
2287 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2289 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2290 "Port (%d) promiscuous mode not disabled\n",
2291 test_params->bonded_port_id);
2293 for (i = 0; i < test_params->bonded_slave_count; i++) {
2294 promiscuous_en = rte_eth_promiscuous_get(
2295 test_params->slave_port_ids[i]);
2296 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2297 "slave port (%d) promiscuous mode not disabled\n",
2298 test_params->slave_port_ids[i]);
2301 /* Clean up and remove slaves from bonded device */
2302 return remove_slaves_and_stop_bonded_device();
2306 test_activebackup_verify_mac_assignment(void)
2308 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2310 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2311 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2313 /* Initialize bonded device with 2 slaves in active backup mode */
2314 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2315 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2316 "Failed to initialize bonded device with slaves");
2318 /* Verify that bonded MACs is that of first slave and that the other slave
2319 * MAC hasn't been changed */
2320 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2321 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2322 sizeof(read_mac_addr)),
2323 "bonded port (%d) mac address not set to that of primary port",
2324 test_params->bonded_port_id);
2326 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2327 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2328 sizeof(read_mac_addr)),
2329 "slave port (%d) mac address not set to that of primary port",
2330 test_params->slave_port_ids[0]);
2332 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2333 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2334 sizeof(read_mac_addr)),
2335 "slave port (%d) mac address not as expected",
2336 test_params->slave_port_ids[1]);
2338 /* change primary and verify that MAC addresses haven't changed */
2339 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2340 test_params->slave_port_ids[1]), 0,
2341 "Failed to set bonded port (%d) primary port to (%d)",
2342 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2344 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2345 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2346 sizeof(read_mac_addr)),
2347 "bonded port (%d) mac address not set to that of primary port",
2348 test_params->bonded_port_id);
2350 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2351 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2352 sizeof(read_mac_addr)),
2353 "slave port (%d) mac address not set to that of primary port",
2354 test_params->slave_port_ids[0]);
2356 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2357 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2358 sizeof(read_mac_addr)),
2359 "slave port (%d) mac address not as expected",
2360 test_params->slave_port_ids[1]);
2362 /* stop / start bonded device and verify that primary MAC address is
2363 * propagated to bonded device and slaves */
2365 rte_eth_dev_stop(test_params->bonded_port_id);
2367 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2368 "Failed to start device");
2370 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2371 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2372 sizeof(read_mac_addr)),
2373 "bonded port (%d) mac address not set to that of primary port",
2374 test_params->bonded_port_id);
2376 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2377 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2378 sizeof(read_mac_addr)),
2379 "slave port (%d) mac address not as expected",
2380 test_params->slave_port_ids[0]);
2382 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2383 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2384 sizeof(read_mac_addr)),
2385 "slave port (%d) mac address not set to that of primary port",
2386 test_params->slave_port_ids[1]);
2388 /* Set explicit MAC address */
2389 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2390 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2391 "failed to set MAC address");
2393 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2394 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2395 sizeof(read_mac_addr)),
2396 "bonded port (%d) mac address not set to that of bonded port",
2397 test_params->bonded_port_id);
2399 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2400 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2401 sizeof(read_mac_addr)),
2402 "slave port (%d) mac address not as expected",
2403 test_params->slave_port_ids[0]);
2405 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2406 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2407 sizeof(read_mac_addr)),
2408 "slave port (%d) mac address not set to that of bonded port",
2409 test_params->slave_port_ids[1]);
2411 /* Clean up and remove slaves from bonded device */
2412 return remove_slaves_and_stop_bonded_device();
2416 test_activebackup_verify_slave_link_status_change_failover(void)
2418 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2419 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2420 struct rte_eth_stats port_stats;
2422 uint8_t slaves[RTE_MAX_ETHPORTS];
2424 int i, j, burst_size, slave_count, primary_port;
2428 memset(pkt_burst, 0, sizeof(pkt_burst));
2430 /* Generate packet burst for testing */
2431 TEST_ASSERT_EQUAL(generate_test_burst(
2432 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2433 "generate_test_burst failed");
2435 /* Initialize bonded device with 4 slaves in round robin mode */
2436 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2437 BONDING_MODE_ACTIVE_BACKUP, 0,
2438 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2439 "Failed to initialize bonded device with slaves");
2441 /* Verify Current Slaves Count /Active Slave Count is */
2442 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2444 TEST_ASSERT_EQUAL(slave_count, 4,
2445 "Number of slaves (%d) is not as expected (%d).",
2448 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2449 slaves, RTE_MAX_ETHPORTS);
2450 TEST_ASSERT_EQUAL(slave_count, 4,
2451 "Number of active slaves (%d) is not as expected (%d).",
2454 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2455 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2456 "Primary port not as expected");
2458 /* Bring 2 slaves down and verify active slave count */
2459 virtual_ethdev_simulate_link_status_interrupt(
2460 test_params->slave_port_ids[1], 0);
2461 virtual_ethdev_simulate_link_status_interrupt(
2462 test_params->slave_port_ids[3], 0);
2464 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2465 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2466 "Number of active slaves (%d) is not as expected (%d).",
2469 virtual_ethdev_simulate_link_status_interrupt(
2470 test_params->slave_port_ids[1], 1);
2471 virtual_ethdev_simulate_link_status_interrupt(
2472 test_params->slave_port_ids[3], 1);
2475 /* Bring primary port down, verify that active slave count is 3 and primary
2477 virtual_ethdev_simulate_link_status_interrupt(
2478 test_params->slave_port_ids[0], 0);
2480 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2481 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2483 "Number of active slaves (%d) is not as expected (%d).",
2486 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2487 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2488 "Primary port not as expected");
2490 /* Verify that pkts are sent on new primary slave */
2492 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2493 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2494 burst_size), burst_size, "rte_eth_tx_burst failed");
2496 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2497 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2498 "(%d) port_stats.opackets not as expected",
2499 test_params->slave_port_ids[2]);
2501 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2502 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2503 "(%d) port_stats.opackets not as expected\n",
2504 test_params->slave_port_ids[0]);
2506 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2507 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2508 "(%d) port_stats.opackets not as expected\n",
2509 test_params->slave_port_ids[1]);
2511 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2512 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2513 "(%d) port_stats.opackets not as expected\n",
2514 test_params->slave_port_ids[3]);
2516 /* Generate packet burst for testing */
2518 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2519 TEST_ASSERT_EQUAL(generate_test_burst(
2520 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2521 "generate_test_burst failed");
2523 virtual_ethdev_add_mbufs_to_rx_queue(
2524 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2527 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2528 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2529 burst_size, "rte_eth_rx_burst\n");
2531 /* Verify bonded device rx count */
2532 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2533 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2534 "(%d) port_stats.ipackets not as expected",
2535 test_params->bonded_port_id);
2537 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2538 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2539 "(%d) port_stats.opackets not as expected",
2540 test_params->slave_port_ids[2]);
2542 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2543 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2544 "(%d) port_stats.opackets not as expected",
2545 test_params->slave_port_ids[0]);
2547 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2548 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2549 "(%d) port_stats.opackets not as expected",
2550 test_params->slave_port_ids[1]);
2552 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2553 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2554 "(%d) port_stats.opackets not as expected",
2555 test_params->slave_port_ids[3]);
2558 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2559 for (j = 0; j < MAX_PKT_BURST; j++) {
2560 if (pkt_burst[i][j] != NULL) {
2561 rte_pktmbuf_free(pkt_burst[i][j]);
2562 pkt_burst[i][j] = NULL;
2567 /* Clean up and remove slaves from bonded device */
2568 return remove_slaves_and_stop_bonded_device();
2571 /** Balance Mode Tests */
2574 test_balance_xmit_policy_configuration(void)
2576 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2577 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2578 "Failed to initialize_bonded_device_with_slaves.");
2580 /* Invalid port id */
2581 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2582 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2583 "Expected call to failed as invalid port specified.");
2585 /* Set xmit policy on non bonded device */
2586 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2587 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2588 "Expected call to failed as invalid port specified.");
2591 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2592 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2593 "Failed to set balance xmit policy.");
2595 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2596 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2599 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2600 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2601 "Failed to set balance xmit policy.");
2603 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2604 BALANCE_XMIT_POLICY_LAYER23,
2605 "balance xmit policy not as expected.");
2608 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2609 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2610 "Failed to set balance xmit policy.");
2612 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2613 BALANCE_XMIT_POLICY_LAYER34,
2614 "balance xmit policy not as expected.");
2616 /* Invalid port id */
2617 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2618 "Expected call to failed as invalid port specified.");
2620 /* Clean up and remove slaves from bonded device */
2621 return remove_slaves_and_stop_bonded_device();
2624 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2627 test_balance_l2_tx_burst(void)
2629 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2630 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2634 struct rte_eth_stats port_stats;
2636 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2637 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2638 "Failed to initialize_bonded_device_with_slaves.");
2640 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2641 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2642 "Failed to set balance xmit policy.");
2644 initialize_eth_header(test_params->pkt_eth_hdr,
2645 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2646 ETHER_TYPE_IPv4, 0, 0);
2647 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2649 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2650 dst_addr_0, pktlen);
2652 /* Generate a burst 1 of packets to transmit */
2653 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2654 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2655 test_params->pkt_udp_hdr, burst_size[0],
2656 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2657 "failed to generate packet burst");
2659 initialize_eth_header(test_params->pkt_eth_hdr,
2660 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2661 ETHER_TYPE_IPv4, 0, 0);
2663 /* Generate a burst 2 of packets to transmit */
2664 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2665 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2666 test_params->pkt_udp_hdr, burst_size[1],
2667 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2668 "failed to generate packet burst");
2670 /* Send burst 1 on bonded port */
2671 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2672 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2673 &pkts_burst[i][0], burst_size[i]),
2674 burst_size[i], "Failed to transmit packet burst");
2677 /* Verify bonded port tx stats */
2678 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2679 TEST_ASSERT_EQUAL(port_stats.opackets,
2680 (uint64_t)(burst_size[0] + burst_size[1]),
2681 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2682 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2683 burst_size[0] + burst_size[1]);
2686 /* Verify slave ports tx stats */
2687 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2688 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2689 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2690 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2693 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2694 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2695 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2696 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2699 /* Put all slaves down and try and transmit */
2700 for (i = 0; i < test_params->bonded_slave_count; i++) {
2702 virtual_ethdev_simulate_link_status_interrupt(
2703 test_params->slave_port_ids[i], 0);
2706 /* Send burst on bonded port */
2707 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2708 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2709 0, "Expected zero packet");
2711 /* Clean up and remove slaves from bonded device */
2712 return remove_slaves_and_stop_bonded_device();
2716 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2717 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2719 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2721 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2722 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2724 struct rte_eth_stats port_stats;
2726 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2727 BONDING_MODE_BALANCE, 0, 2, 1),
2728 "Failed to initialize_bonded_device_with_slaves.");
2730 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2731 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2732 "Failed to set balance xmit policy.");
2737 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2738 "Burst size specified is greater than supported.");
2740 /* Generate test bursts of packets to transmit */
2741 TEST_ASSERT_EQUAL(generate_test_burst(
2742 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2743 burst_size_1, "failed to generate packet burst");
2745 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2746 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2747 "failed to generate packet burst");
2749 /* Send burst 1 on bonded port */
2750 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2752 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2754 /* Send burst 2 on bonded port */
2755 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2757 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2759 /* Verify bonded port tx stats */
2760 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2761 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2762 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2763 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2766 /* Verify slave ports tx stats */
2767 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2768 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2769 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2770 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2773 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2774 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2775 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2776 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2779 /* Put all slaves down and try and transmit */
2780 for (i = 0; i < test_params->bonded_slave_count; i++) {
2782 virtual_ethdev_simulate_link_status_interrupt(
2783 test_params->slave_port_ids[i], 0);
2786 /* Send burst on bonded port */
2787 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2788 test_params->bonded_port_id, 0, pkts_burst_1,
2789 burst_size_1), 0, "Expected zero packet");
2792 /* Clean up and remove slaves from bonded device */
2793 return remove_slaves_and_stop_bonded_device();
2797 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2799 return balance_l23_tx_burst(0, 1, 1, 0);
2803 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2805 return balance_l23_tx_burst(1, 1, 0, 1);
2809 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2811 return balance_l23_tx_burst(0, 0, 0, 1);
2815 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2817 return balance_l23_tx_burst(1, 0, 0, 1);
2821 test_balance_l23_tx_burst_toggle_mac_addr(void)
2823 return balance_l23_tx_burst(0, 0, 1, 0);
2827 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2828 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2829 uint8_t toggle_udp_port)
2831 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2833 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2834 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2836 struct rte_eth_stats port_stats;
2838 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2839 BONDING_MODE_BALANCE, 0, 2, 1),
2840 "Failed to initialize_bonded_device_with_slaves.");
2842 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2843 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2844 "Failed to set balance xmit policy.");
2849 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2850 "Burst size specified is greater than supported.");
2852 /* Generate test bursts of packets to transmit */
2853 TEST_ASSERT_EQUAL(generate_test_burst(
2854 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2855 burst_size_1, "failed to generate burst");
2857 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2858 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2859 toggle_udp_port), burst_size_2, "failed to generate burst");
2861 /* Send burst 1 on bonded port */
2862 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2864 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2866 /* Send burst 2 on bonded port */
2867 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2869 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2872 /* Verify bonded port tx stats */
2873 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2874 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2875 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2876 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2879 /* Verify slave ports tx stats */
2880 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2881 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2882 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2883 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2886 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2887 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2888 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2889 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2892 /* Put all slaves down and try and transmit */
2893 for (i = 0; i < test_params->bonded_slave_count; i++) {
2895 virtual_ethdev_simulate_link_status_interrupt(
2896 test_params->slave_port_ids[i], 0);
2899 /* Send burst on bonded port */
2900 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2901 test_params->bonded_port_id, 0, pkts_burst_1,
2902 burst_size_1), 0, "Expected zero packet");
2904 /* Clean up and remove slaves from bonded device */
2905 return remove_slaves_and_stop_bonded_device();
2909 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2911 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2915 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2917 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2921 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2923 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2927 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2929 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2933 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2935 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2939 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2941 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2944 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2945 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2946 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2947 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2948 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2951 test_balance_tx_burst_slave_tx_fail(void)
2953 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2954 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2956 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2958 struct rte_eth_stats port_stats;
2960 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2962 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2963 BONDING_MODE_BALANCE, 0,
2964 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2965 "Failed to intialise bonded device");
2967 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2968 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2969 "Failed to set balance xmit policy.");
2972 /* Generate test bursts for transmission */
2973 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2974 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2975 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2976 "Failed to generate test packet burst 1");
2978 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2979 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2981 /* copy mbuf referneces for expected transmission failures */
2982 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2983 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2985 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2986 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2987 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2988 "Failed to generate test packet burst 2");
2991 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2992 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2993 virtual_ethdev_tx_burst_fn_set_success(
2994 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2997 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2998 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2999 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3002 /* Transmit burst 1 */
3003 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
3004 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
3006 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3007 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3008 "Transmitted (%d) packets, expected to transmit (%d) packets",
3009 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3010 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3012 /* Verify that failed packet are expected failed packets */
3013 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3014 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3015 "expected mbuf (%d) pointer %p not expected pointer %p",
3016 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3019 /* Transmit burst 2 */
3020 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3021 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3023 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3024 "Transmitted (%d) packets, expected to transmit (%d) packets",
3025 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3028 /* Verify bonded port tx stats */
3029 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3031 TEST_ASSERT_EQUAL(port_stats.opackets,
3032 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3033 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3034 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3035 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3036 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3037 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3038 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3039 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3041 /* Verify slave ports tx stats */
3043 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3045 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3046 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3047 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3048 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3049 test_params->slave_port_ids[0],
3050 (unsigned int)port_stats.opackets,
3051 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3052 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3057 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3059 TEST_ASSERT_EQUAL(port_stats.opackets,
3060 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3061 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3062 test_params->slave_port_ids[1],
3063 (unsigned int)port_stats.opackets,
3064 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3066 #ifdef RTE_MBUF_REFCNT
3067 /* Verify that all mbufs have a ref value of zero */
3068 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3069 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3070 "mbufs refcnts not as expected");
3073 free_mbufs(&pkts_burst_1[tx_count_1],
3074 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3076 /* Clean up and remove slaves from bonded device */
3077 return remove_slaves_and_stop_bonded_device();
3080 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3083 test_balance_rx_burst(void)
3085 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3087 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3088 struct rte_eth_stats port_stats;
3090 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3093 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3095 /* Initialize bonded device with 4 slaves in round robin mode */
3096 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3097 BONDING_MODE_BALANCE, 0, 3, 1),
3098 "Failed to intialise bonded device");
3100 /* Generate test bursts of packets to transmit */
3101 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3102 TEST_ASSERT_EQUAL(generate_test_burst(
3103 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3104 0, 0), burst_size[i],
3105 "failed to generate packet burst");
3108 /* Add rx data to slaves */
3109 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3110 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3111 &gen_pkt_burst[i][0], burst_size[i]);
3114 /* Call rx burst on bonded device */
3115 /* Send burst on bonded port */
3116 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3117 rx_pkt_burst, MAX_PKT_BURST),
3118 burst_size[0] + burst_size[1] + burst_size[2],
3119 "balance rx burst failed\n");
3121 /* Verify bonded device rx count */
3122 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3123 TEST_ASSERT_EQUAL(port_stats.ipackets,
3124 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3125 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3126 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3127 burst_size[0] + burst_size[1] + burst_size[2]);
3130 /* Verify bonded slave devices rx counts */
3131 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3132 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3133 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3134 test_params->slave_port_ids[0],
3135 (unsigned int)port_stats.ipackets, burst_size[0]);
3137 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3138 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3139 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3140 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3143 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3144 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3145 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3146 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3149 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3150 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3151 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3152 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3156 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3157 for (j = 0; j < MAX_PKT_BURST; j++) {
3158 if (gen_pkt_burst[i][j] != NULL) {
3159 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3160 gen_pkt_burst[i][j] = NULL;
3165 /* Clean up and remove slaves from bonded device */
3166 return remove_slaves_and_stop_bonded_device();
3170 test_balance_verify_promiscuous_enable_disable(void)
3174 /* Initialize bonded device with 4 slaves in round robin mode */
3175 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3176 BONDING_MODE_BALANCE, 0, 4, 1),
3177 "Failed to intialise bonded device");
3179 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3181 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3182 "Port (%d) promiscuous mode not enabled",
3183 test_params->bonded_port_id);
3185 for (i = 0; i < test_params->bonded_slave_count; i++) {
3186 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3187 test_params->slave_port_ids[i]), 1,
3188 "Port (%d) promiscuous mode not enabled",
3189 test_params->slave_port_ids[i]);
3192 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3194 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3195 "Port (%d) promiscuous mode not disabled",
3196 test_params->bonded_port_id);
3198 for (i = 0; i < test_params->bonded_slave_count; i++) {
3199 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3200 test_params->slave_port_ids[i]), 0,
3201 "Port (%d) promiscuous mode not disabled",
3202 test_params->slave_port_ids[i]);
3205 /* Clean up and remove slaves from bonded device */
3206 return remove_slaves_and_stop_bonded_device();
3210 test_balance_verify_mac_assignment(void)
3212 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3214 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3215 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3217 /* Initialize bonded device with 2 slaves in active backup mode */
3218 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3219 BONDING_MODE_BALANCE, 0, 2, 1),
3220 "Failed to intialise bonded device");
3222 /* Verify that bonded MACs is that of first slave and that the other slave
3223 * MAC hasn't been changed */
3224 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3225 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3226 sizeof(read_mac_addr)),
3227 "bonded port (%d) mac address not set to that of primary port",
3228 test_params->bonded_port_id);
3230 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3231 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3232 sizeof(read_mac_addr)),
3233 "slave port (%d) mac address not set to that of primary port",
3234 test_params->slave_port_ids[0]);
3236 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3237 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3238 sizeof(read_mac_addr)),
3239 "slave port (%d) mac address not set to that of primary port",
3240 test_params->slave_port_ids[1]);
3242 /* change primary and verify that MAC addresses haven't changed */
3243 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3244 test_params->slave_port_ids[1]),
3245 "Failed to set bonded port (%d) primary port to (%d)\n",
3246 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3248 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3249 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3250 sizeof(read_mac_addr)),
3251 "bonded port (%d) mac address not set to that of primary port",
3252 test_params->bonded_port_id);
3254 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3255 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3256 sizeof(read_mac_addr)),
3257 "slave port (%d) mac address not set to that of primary port",
3258 test_params->slave_port_ids[0]);
3260 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3261 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3262 sizeof(read_mac_addr)),
3263 "slave port (%d) mac address not set to that of primary port",
3264 test_params->slave_port_ids[1]);
3266 /* stop / start bonded device and verify that primary MAC address is
3267 * propagated to bonded device and slaves */
3269 rte_eth_dev_stop(test_params->bonded_port_id);
3271 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3272 "Failed to start bonded device");
3274 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3275 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3276 sizeof(read_mac_addr)),
3277 "bonded port (%d) mac address not set to that of primary port",
3278 test_params->bonded_port_id);
3280 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3281 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3282 sizeof(read_mac_addr)),
3283 "slave port (%d) mac address not set to that of primary port",
3284 test_params->slave_port_ids[0]);
3286 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3287 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3288 sizeof(read_mac_addr)),
3289 "slave port (%d) mac address not set to that of primary port",
3290 test_params->slave_port_ids[1]);
3292 /* Set explicit MAC address */
3293 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3294 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3295 "failed to set MAC");
3297 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3298 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3299 sizeof(read_mac_addr)),
3300 "bonded port (%d) mac address not set to that of bonded port",
3301 test_params->bonded_port_id);
3303 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3304 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3305 sizeof(read_mac_addr)),
3306 "slave port (%d) mac address not as expected\n",
3307 test_params->slave_port_ids[0]);
3309 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3310 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3311 sizeof(read_mac_addr)),
3312 "slave port (%d) mac address not set to that of bonded port",
3313 test_params->slave_port_ids[1]);
3315 /* Clean up and remove slaves from bonded device */
3316 return remove_slaves_and_stop_bonded_device();
3319 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3322 test_balance_verify_slave_link_status_change_behaviour(void)
3324 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3325 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3326 struct rte_eth_stats port_stats;
3328 uint8_t slaves[RTE_MAX_ETHPORTS];
3330 int i, j, burst_size, slave_count;
3332 memset(pkt_burst, 0, sizeof(pkt_burst));
3334 /* Initialize bonded device with 4 slaves in round robin mode */
3335 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3336 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3337 "Failed to intialise bonded device");
3339 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3340 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3341 "Failed to set balance xmit policy.");
3344 /* Verify Current Slaves Count /Active Slave Count is */
3345 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3347 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3348 "Number of slaves (%d) is not as expected (%d).",
3349 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3351 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3352 slaves, RTE_MAX_ETHPORTS);
3353 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3354 "Number of active slaves (%d) is not as expected (%d).",
3355 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3357 /* Set 2 slaves link status to down */
3358 virtual_ethdev_simulate_link_status_interrupt(
3359 test_params->slave_port_ids[1], 0);
3360 virtual_ethdev_simulate_link_status_interrupt(
3361 test_params->slave_port_ids[3], 0);
3363 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3364 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3365 "Number of active slaves (%d) is not as expected (%d).",
3368 /* Send to sets of packet burst and verify that they are balanced across
3372 TEST_ASSERT_EQUAL(generate_test_burst(
3373 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3374 "generate_test_burst failed");
3376 TEST_ASSERT_EQUAL(generate_test_burst(
3377 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3378 "generate_test_burst failed");
3380 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3381 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3382 burst_size, "rte_eth_tx_burst failed");
3384 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3385 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3386 burst_size, "rte_eth_tx_burst failed");
3389 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3390 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3391 "(%d) port_stats.opackets (%d) not as expected (%d).",
3392 test_params->bonded_port_id, (int)port_stats.opackets,
3393 burst_size + burst_size);
3395 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3396 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3397 "(%d) port_stats.opackets (%d) not as expected (%d).",
3398 test_params->slave_port_ids[0], (int)port_stats.opackets,
3401 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3402 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3403 "(%d) port_stats.opackets (%d) not as expected (%d).",
3404 test_params->slave_port_ids[2], (int)port_stats.opackets,
3407 /* verify that all packets get send on primary slave when no other slaves
3409 virtual_ethdev_simulate_link_status_interrupt(
3410 test_params->slave_port_ids[2], 0);
3412 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3413 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3414 "Number of active slaves (%d) is not as expected (%d).",
3417 TEST_ASSERT_EQUAL(generate_test_burst(
3418 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3419 "generate_test_burst failed");
3421 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3422 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3423 burst_size, "rte_eth_tx_burst failed");
3425 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3426 TEST_ASSERT_EQUAL(port_stats.opackets,
3427 (uint64_t)(burst_size + burst_size + burst_size),
3428 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3429 test_params->bonded_port_id, (int)port_stats.opackets,
3430 burst_size + burst_size + burst_size);
3432 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3433 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3434 "(%d) port_stats.opackets (%d) not as expected (%d).",
3435 test_params->slave_port_ids[0], (int)port_stats.opackets,
3436 burst_size + burst_size);
3438 virtual_ethdev_simulate_link_status_interrupt(
3439 test_params->slave_port_ids[0], 0);
3440 virtual_ethdev_simulate_link_status_interrupt(
3441 test_params->slave_port_ids[1], 1);
3442 virtual_ethdev_simulate_link_status_interrupt(
3443 test_params->slave_port_ids[2], 1);
3444 virtual_ethdev_simulate_link_status_interrupt(
3445 test_params->slave_port_ids[3], 1);
3447 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3448 TEST_ASSERT_EQUAL(generate_test_burst(
3449 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3450 "Failed to generate packet burst");
3452 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3453 &pkt_burst[i][0], burst_size);
3456 /* Verify that pkts are not received on slaves with link status down */
3458 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3461 /* Verify bonded device rx count */
3462 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3463 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3464 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3465 test_params->bonded_port_id, (int)port_stats.ipackets,
3468 /* free mbufs allocate for rx testing */
3469 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3470 for (j = 0; j < MAX_PKT_BURST; j++) {
3471 if (pkt_burst[i][j] != NULL) {
3472 rte_pktmbuf_free(pkt_burst[i][j]);
3473 pkt_burst[i][j] = NULL;
3478 /* Clean up and remove slaves from bonded device */
3479 return remove_slaves_and_stop_bonded_device();
3482 #ifdef RTE_MBUF_REFCNT
3483 /** Broadcast Mode Tests */
3486 test_broadcast_tx_burst(void)
3488 int i, pktlen, burst_size;
3489 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3491 struct rte_eth_stats port_stats;
3493 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3494 BONDING_MODE_BROADCAST, 0, 2, 1),
3495 "Failed to intialise bonded device");
3497 initialize_eth_header(test_params->pkt_eth_hdr,
3498 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3499 ETHER_TYPE_IPv4, 0, 0);
3501 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3503 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3504 dst_addr_0, pktlen);
3506 burst_size = 20 * test_params->bonded_slave_count;
3508 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3509 "Burst size specified is greater than supported.");
3511 /* Generate a burst of packets to transmit */
3512 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3513 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3514 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3515 1), burst_size, "Failed to generate packet burst");
3517 /* Send burst on bonded port */
3518 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3519 pkts_burst, burst_size), burst_size,
3520 "Bonded Port (%d) rx burst failed, packets transmitted value "
3521 "not as expected (%d)",
3522 test_params->bonded_port_id, burst_size);
3524 /* Verify bonded port tx stats */
3525 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3526 TEST_ASSERT_EQUAL(port_stats.opackets,
3527 (uint64_t)burst_size * test_params->bonded_slave_count,
3528 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3529 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3532 /* Verify slave ports tx stats */
3533 for (i = 0; i < test_params->bonded_slave_count; i++) {
3534 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3535 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3536 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3537 test_params->bonded_port_id,
3538 (unsigned int)port_stats.opackets, burst_size);
3541 /* Put all slaves down and try and transmit */
3542 for (i = 0; i < test_params->bonded_slave_count; i++) {
3544 virtual_ethdev_simulate_link_status_interrupt(
3545 test_params->slave_port_ids[i], 0);
3548 /* Send burst on bonded port */
3549 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3550 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3551 "transmitted an unexpected number of packets");
3553 /* Clean up and remove slaves from bonded device */
3554 return remove_slaves_and_stop_bonded_device();
3558 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3559 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3560 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3561 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3564 test_broadcast_tx_burst_slave_tx_fail(void)
3566 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3567 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3569 struct rte_eth_stats port_stats;
3573 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3574 BONDING_MODE_BROADCAST, 0,
3575 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3576 "Failed to intialise bonded device");
3578 /* Generate test bursts for transmission */
3579 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3580 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3581 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3582 "Failed to generate test packet burst");
3584 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3585 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3586 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3589 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3590 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3591 virtual_ethdev_tx_burst_fn_set_success(
3592 test_params->slave_port_ids[0],
3594 virtual_ethdev_tx_burst_fn_set_success(
3595 test_params->slave_port_ids[1],
3597 virtual_ethdev_tx_burst_fn_set_success(
3598 test_params->slave_port_ids[2],
3601 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3602 test_params->slave_port_ids[0],
3603 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3605 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3606 test_params->slave_port_ids[1],
3607 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3609 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3610 test_params->slave_port_ids[2],
3611 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3613 /* Transmit burst */
3614 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3615 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3617 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3618 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3619 "Transmitted (%d) packets, expected to transmit (%d) packets",
3620 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3621 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3623 /* Verify that failed packet are expected failed packets */
3624 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3625 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3626 "expected mbuf (%d) pointer %p not expected pointer %p",
3627 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3630 /* Verify slave ports tx stats */
3632 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3634 TEST_ASSERT_EQUAL(port_stats.opackets,
3635 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3636 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3637 "Port (%d) opackets value (%u) not as expected (%d)",
3638 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3639 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3640 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3643 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3645 TEST_ASSERT_EQUAL(port_stats.opackets,
3646 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3647 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3648 "Port (%d) opackets value (%u) not as expected (%d)",
3649 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3650 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3651 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3653 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3655 TEST_ASSERT_EQUAL(port_stats.opackets,
3656 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3657 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3658 "Port (%d) opackets value (%u) not as expected (%d)",
3659 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3660 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3661 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3664 /* Verify that all mbufs who transmission failed have a ref value of one */
3665 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3666 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3667 "mbufs refcnts not as expected");
3669 free_mbufs(&pkts_burst[tx_count],
3670 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3672 /* Clean up and remove slaves from bonded device */
3673 return remove_slaves_and_stop_bonded_device();
3676 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3679 test_broadcast_rx_burst(void)
3681 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3683 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3684 struct rte_eth_stats port_stats;
3686 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3689 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3691 /* Initialize bonded device with 4 slaves in round robin mode */
3692 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3693 BONDING_MODE_BROADCAST, 0, 3, 1),
3694 "Failed to intialise bonded device");
3696 /* Generate test bursts of packets to transmit */
3697 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3698 TEST_ASSERT_EQUAL(generate_test_burst(
3699 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3700 burst_size[i], "failed to generate packet burst");
3703 /* Add rx data to slave 0 */
3704 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3705 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3706 &gen_pkt_burst[i][0], burst_size[i]);
3710 /* Call rx burst on bonded device */
3711 /* Send burst on bonded port */
3712 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3713 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3714 burst_size[0] + burst_size[1] + burst_size[2],
3717 /* Verify bonded device rx count */
3718 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3719 TEST_ASSERT_EQUAL(port_stats.ipackets,
3720 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3721 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3722 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3723 burst_size[0] + burst_size[1] + burst_size[2]);
3726 /* Verify bonded slave devices rx counts */
3727 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3728 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3729 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3730 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3733 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3734 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3735 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3736 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3739 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3740 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3741 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3742 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3745 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3746 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3747 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3748 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3751 /* free mbufs allocate for rx testing */
3752 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3753 for (j = 0; j < MAX_PKT_BURST; j++) {
3754 if (gen_pkt_burst[i][j] != NULL) {
3755 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3756 gen_pkt_burst[i][j] = NULL;
3761 /* Clean up and remove slaves from bonded device */
3762 return remove_slaves_and_stop_bonded_device();
3766 test_broadcast_verify_promiscuous_enable_disable(void)
3770 /* Initialize bonded device with 4 slaves in round robin mode */
3771 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3772 BONDING_MODE_BROADCAST, 0, 4, 1),
3773 "Failed to intialise bonded device");
3775 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3778 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3779 "Port (%d) promiscuous mode not enabled",
3780 test_params->bonded_port_id);
3782 for (i = 0; i < test_params->bonded_slave_count; i++) {
3783 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3784 test_params->slave_port_ids[i]), 1,
3785 "Port (%d) promiscuous mode not enabled",
3786 test_params->slave_port_ids[i]);
3789 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3791 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3792 "Port (%d) promiscuous mode not disabled",
3793 test_params->bonded_port_id);
3795 for (i = 0; i < test_params->bonded_slave_count; i++) {
3796 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3797 test_params->slave_port_ids[i]), 0,
3798 "Port (%d) promiscuous mode not disabled",
3799 test_params->slave_port_ids[i]);
3802 /* Clean up and remove slaves from bonded device */
3803 return remove_slaves_and_stop_bonded_device();
3807 test_broadcast_verify_mac_assignment(void)
3809 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3813 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3814 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3816 /* Initialize bonded device with 4 slaves in round robin mode */
3817 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3818 BONDING_MODE_BROADCAST, 0, 4, 1),
3819 "Failed to intialise bonded device");
3821 /* Verify that all MACs are the same as first slave added to bonded
3823 for (i = 0; i < test_params->bonded_slave_count; i++) {
3824 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3825 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3826 sizeof(read_mac_addr)),
3827 "slave port (%d) mac address not set to that of primary port",
3828 test_params->slave_port_ids[i]);
3831 /* change primary and verify that MAC addresses haven't changed */
3832 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3833 test_params->slave_port_ids[2]),
3834 "Failed to set bonded port (%d) primary port to (%d)",
3835 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3837 for (i = 0; i < test_params->bonded_slave_count; i++) {
3838 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3839 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3840 sizeof(read_mac_addr)),
3841 "slave port (%d) mac address has changed to that of primary "
3842 "port without stop/start toggle of bonded device",
3843 test_params->slave_port_ids[i]);
3846 /* stop / start bonded device and verify that primary MAC address is
3847 * propagated to bonded device and slaves */
3849 rte_eth_dev_stop(test_params->bonded_port_id);
3851 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3852 "Failed to start bonded device");
3854 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3855 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3856 sizeof(read_mac_addr)),
3857 "bonded port (%d) mac address not set to that of new primary port",
3858 test_params->slave_port_ids[i]);
3860 for (i = 0; i < test_params->bonded_slave_count; i++) {
3861 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3862 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3863 sizeof(read_mac_addr)),
3864 "slave port (%d) mac address not set to that of new primary "
3865 "port", test_params->slave_port_ids[i]);
3868 /* Set explicit MAC address */
3869 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3870 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3871 "Failed to set MAC address");
3873 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3874 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3875 sizeof(read_mac_addr)),
3876 "bonded port (%d) mac address not set to that of new primary port",
3877 test_params->slave_port_ids[i]);
3880 for (i = 0; i < test_params->bonded_slave_count; i++) {
3881 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3882 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3883 sizeof(read_mac_addr)),
3884 "slave port (%d) mac address not set to that of new primary "
3885 "port", test_params->slave_port_ids[i]);
3888 /* Clean up and remove slaves from bonded device */
3889 return remove_slaves_and_stop_bonded_device();
3892 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3894 test_broadcast_verify_slave_link_status_change_behaviour(void)
3896 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3897 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3898 struct rte_eth_stats port_stats;
3900 uint8_t slaves[RTE_MAX_ETHPORTS];
3902 int i, j, burst_size, slave_count;
3904 memset(pkt_burst, 0, sizeof(pkt_burst));
3906 /* Initialize bonded device with 4 slaves in round robin mode */
3907 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3908 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3909 1), "Failed to intialise bonded device");
3911 /* Verify Current Slaves Count /Active Slave Count is */
3912 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3914 TEST_ASSERT_EQUAL(slave_count, 4,
3915 "Number of slaves (%d) is not as expected (%d).",
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, 4,
3921 "Number of active slaves (%d) is not as expected (%d).",
3924 /* Set 2 slaves link status to down */
3925 virtual_ethdev_simulate_link_status_interrupt(
3926 test_params->slave_port_ids[1], 0);
3927 virtual_ethdev_simulate_link_status_interrupt(
3928 test_params->slave_port_ids[3], 0);
3930 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3931 slaves, RTE_MAX_ETHPORTS);
3932 TEST_ASSERT_EQUAL(slave_count, 2,
3933 "Number of active slaves (%d) is not as expected (%d).",
3936 for (i = 0; i < test_params->bonded_slave_count; i++)
3937 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3939 /* Verify that pkts are not sent on slaves with link status down */
3942 TEST_ASSERT_EQUAL(generate_test_burst(
3943 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3944 "generate_test_burst failed");
3946 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3947 &pkt_burst[0][0], burst_size), burst_size,
3948 "rte_eth_tx_burst failed\n");
3950 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3951 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3952 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3953 test_params->bonded_port_id, (int)port_stats.opackets,
3954 burst_size * slave_count);
3956 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3957 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3958 "(%d) port_stats.opackets not as expected",
3959 test_params->slave_port_ids[0]);
3961 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3962 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3963 "(%d) port_stats.opackets not as expected",
3964 test_params->slave_port_ids[1]);
3966 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3967 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3968 "(%d) port_stats.opackets not as expected",
3969 test_params->slave_port_ids[2]);
3972 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3973 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3974 "(%d) port_stats.opackets not as expected",
3975 test_params->slave_port_ids[3]);
3978 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3979 TEST_ASSERT_EQUAL(generate_test_burst(
3980 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3981 burst_size, "failed to generate packet burst");
3983 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3984 &pkt_burst[i][0], burst_size);
3987 /* Verify that pkts are not received on slaves with link status down */
3988 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3989 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3990 burst_size + burst_size, "rte_eth_rx_burst failed");
3993 /* Verify bonded device rx count */
3994 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3995 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3996 "(%d) port_stats.ipackets not as expected\n",
3997 test_params->bonded_port_id);
3999 /* free mbufs allocate for rx testing */
4000 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
4001 for (j = 0; j < MAX_PKT_BURST; j++) {
4002 if (pkt_burst[i][j] != NULL) {
4003 rte_pktmbuf_free(pkt_burst[i][j]);
4004 pkt_burst[i][j] = NULL;
4009 /* Clean up and remove slaves from bonded device */
4010 return remove_slaves_and_stop_bonded_device();
4015 test_reconfigure_bonded_device(void)
4017 test_params->nb_rx_q = 4;
4018 test_params->nb_tx_q = 4;
4020 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4021 "failed to reconfigure bonded device");
4023 test_params->nb_rx_q = 2;
4024 test_params->nb_tx_q = 2;
4026 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4027 "failed to reconfigure bonded device with less rx/tx queues");
4034 test_close_bonded_device(void)
4036 rte_eth_dev_close(test_params->bonded_port_id);
4041 testsuite_teardown(void)
4043 if (test_params->pkt_eth_hdr != NULL) {
4044 free(test_params->pkt_eth_hdr);
4045 test_params->pkt_eth_hdr = NULL;
4048 /* Clean up and remove slaves from bonded device */
4049 return remove_slaves_and_stop_bonded_device();
4053 free_virtualpmd_tx_queue(void)
4055 int i, slave_port, to_free_cnt;
4056 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4058 /* Free tx queue of virtual pmd */
4059 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4061 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4062 test_params->slave_port_ids[slave_port],
4063 pkts_to_free, MAX_PKT_BURST);
4064 for (i = 0; i < to_free_cnt; i++)
4065 rte_pktmbuf_free(pkts_to_free[i]);
4070 test_tlb_tx_burst(void)
4072 int i, burst_size, nb_tx;
4073 uint64_t nb_tx2 = 0;
4074 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4075 struct rte_eth_stats port_stats[32];
4076 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4078 uint64_t floor_obytes = 0, ceiling_obytes = 0;
4080 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4081 (BONDING_MODE_TLB, 1, 3, 1),
4082 "Failed to initialise bonded device");
4084 burst_size = 20 * test_params->bonded_slave_count;
4086 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4087 "Burst size specified is greater than supported.\n");
4090 /* Generate 400000 test bursts in 2s of packets to transmit */
4091 for (i = 0; i < 400000; i++) {
4092 /*test two types of mac src own(bonding) and others */
4094 initialize_eth_header(test_params->pkt_eth_hdr,
4095 (struct ether_addr *)src_mac,
4096 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4098 initialize_eth_header(test_params->pkt_eth_hdr,
4099 (struct ether_addr *)test_params->default_slave_mac,
4100 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4102 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4104 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4105 dst_addr_0, pktlen);
4106 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4107 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4108 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4109 /* Send burst on bonded port */
4110 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4114 free_virtualpmd_tx_queue();
4116 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4117 "number of packet not equal burst size");
4123 /* Verify bonded port tx stats */
4124 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4126 all_bond_opackets = port_stats[0].opackets;
4127 all_bond_obytes = port_stats[0].obytes;
4129 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4130 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4131 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4135 /* Verify slave ports tx stats */
4136 for (i = 0; i < test_params->bonded_slave_count; i++) {
4137 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4138 sum_ports_opackets += port_stats[i].opackets;
4141 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4142 "Total packets sent by slaves is not equal to packets sent by bond interface");
4143 /* distribution of packets on each slave within +/- 10% of the expected value. */
4144 for (i = 0; i < test_params->bonded_slave_count; i++) {
4146 floor_obytes = (all_bond_obytes*90)/(test_params->bonded_slave_count*100);
4147 ceiling_obytes = (all_bond_obytes*110)/(test_params->bonded_slave_count*100);
4148 TEST_ASSERT(port_stats[i].obytes >= floor_obytes &&
4149 port_stats[i].obytes <= ceiling_obytes,
4150 "Distribution is not even");
4152 /* Put all slaves down and try and transmit */
4153 for (i = 0; i < test_params->bonded_slave_count; i++) {
4154 virtual_ethdev_simulate_link_status_interrupt(
4155 test_params->slave_port_ids[i], 0);
4158 /* Send burst on bonded port */
4159 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4161 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4163 /* Clean ugit checkout masterp and remove slaves from bonded device */
4164 return remove_slaves_and_stop_bonded_device();
4167 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4170 test_tlb_rx_burst(void)
4172 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4173 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4175 struct rte_eth_stats port_stats;
4179 uint16_t i, j, nb_rx, burst_size = 17;
4181 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4182 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4184 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4185 "Failed to initialize bonded device");
4188 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4189 TEST_ASSERT(primary_port >= 0,
4190 "failed to get primary slave for bonded port (%d)",
4191 test_params->bonded_port_id);
4193 for (i = 0; i < test_params->bonded_slave_count; i++) {
4194 /* Generate test bursts of packets to transmit */
4195 TEST_ASSERT_EQUAL(generate_test_burst(
4196 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4197 "burst generation failed");
4199 /* Add rx data to slave */
4200 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4201 &gen_pkt_burst[0], burst_size);
4203 /* Call rx burst on bonded device */
4204 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4205 &rx_pkt_burst[0], MAX_PKT_BURST);
4207 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4209 if (test_params->slave_port_ids[i] == primary_port) {
4210 /* Verify bonded device rx count */
4211 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4212 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4213 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4214 test_params->bonded_port_id,
4215 (unsigned int)port_stats.ipackets, burst_size);
4217 /* Verify bonded slave devices rx count */
4218 for (j = 0; j < test_params->bonded_slave_count; j++) {
4219 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4221 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4222 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4223 test_params->slave_port_ids[i],
4224 (unsigned int)port_stats.ipackets, burst_size);
4226 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4227 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4228 test_params->slave_port_ids[i],
4229 (unsigned int)port_stats.ipackets, 0);
4233 for (j = 0; j < test_params->bonded_slave_count; j++) {
4234 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4235 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4236 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4237 test_params->slave_port_ids[i],
4238 (unsigned int)port_stats.ipackets, 0);
4243 for (i = 0; i < burst_size; i++)
4244 rte_pktmbuf_free(rx_pkt_burst[i]);
4246 /* reset bonded device stats */
4247 rte_eth_stats_reset(test_params->bonded_port_id);
4250 /* Clean up and remove slaves from bonded device */
4251 return remove_slaves_and_stop_bonded_device();
4255 test_tlb_verify_promiscuous_enable_disable(void)
4257 int i, primary_port, promiscuous_en;
4259 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4260 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4261 BONDING_MODE_TLB, 0, 4, 1),
4262 "Failed to initialize bonded device");
4264 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4265 TEST_ASSERT(primary_port >= 0,
4266 "failed to get primary slave for bonded port (%d)",
4267 test_params->bonded_port_id);
4269 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4271 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4272 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4273 "Port (%d) promiscuous mode not enabled\n",
4274 test_params->bonded_port_id);
4275 for (i = 0; i < test_params->bonded_slave_count; i++) {
4276 promiscuous_en = rte_eth_promiscuous_get(
4277 test_params->slave_port_ids[i]);
4278 if (primary_port == test_params->slave_port_ids[i]) {
4279 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4280 "Port (%d) promiscuous mode not enabled\n",
4281 test_params->bonded_port_id);
4283 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4284 "Port (%d) promiscuous mode enabled\n",
4285 test_params->bonded_port_id);
4290 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4292 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4293 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4294 "Port (%d) promiscuous mode not disabled\n",
4295 test_params->bonded_port_id);
4297 for (i = 0; i < test_params->bonded_slave_count; i++) {
4298 promiscuous_en = rte_eth_promiscuous_get(
4299 test_params->slave_port_ids[i]);
4300 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4301 "slave port (%d) promiscuous mode not disabled\n",
4302 test_params->slave_port_ids[i]);
4305 /* Clean up and remove slaves from bonded device */
4306 return remove_slaves_and_stop_bonded_device();
4310 test_tlb_verify_mac_assignment(void)
4312 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4314 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4315 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4317 /* Initialize bonded device with 2 slaves in active backup mode */
4318 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4319 BONDING_MODE_TLB, 0, 2, 1),
4320 "Failed to initialize bonded device");
4322 /* Verify that bonded MACs is that of first slave and that the other slave
4323 * MAC hasn't been changed */
4324 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4325 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4326 sizeof(read_mac_addr)),
4327 "bonded port (%d) mac address not set to that of primary port",
4328 test_params->bonded_port_id);
4330 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4331 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4332 sizeof(read_mac_addr)),
4333 "slave port (%d) mac address not set to that of primary port",
4334 test_params->slave_port_ids[0]);
4336 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4337 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4338 sizeof(read_mac_addr)),
4339 "slave port (%d) mac address not as expected",
4340 test_params->slave_port_ids[1]);
4342 /* change primary and verify that MAC addresses haven't changed */
4343 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4344 test_params->slave_port_ids[1]), 0,
4345 "Failed to set bonded port (%d) primary port to (%d)",
4346 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4348 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4349 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4350 sizeof(read_mac_addr)),
4351 "bonded port (%d) mac address not set to that of primary port",
4352 test_params->bonded_port_id);
4354 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4355 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4356 sizeof(read_mac_addr)),
4357 "slave port (%d) mac address not set to that of primary port",
4358 test_params->slave_port_ids[0]);
4360 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4361 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4362 sizeof(read_mac_addr)),
4363 "slave port (%d) mac address not as expected",
4364 test_params->slave_port_ids[1]);
4366 /* stop / start bonded device and verify that primary MAC address is
4367 * propagated to bonded device and slaves */
4369 rte_eth_dev_stop(test_params->bonded_port_id);
4371 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4372 "Failed to start device");
4374 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4375 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4376 sizeof(read_mac_addr)),
4377 "bonded port (%d) mac address not set to that of primary port",
4378 test_params->bonded_port_id);
4380 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4381 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4382 sizeof(read_mac_addr)),
4383 "slave port (%d) mac address not as expected",
4384 test_params->slave_port_ids[0]);
4386 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4387 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4388 sizeof(read_mac_addr)),
4389 "slave port (%d) mac address not set to that of primary port",
4390 test_params->slave_port_ids[1]);
4393 /* Set explicit MAC address */
4394 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4395 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4396 "failed to set MAC addres");
4398 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4399 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4400 sizeof(read_mac_addr)),
4401 "bonded port (%d) mac address not set to that of bonded port",
4402 test_params->bonded_port_id);
4404 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4405 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4406 sizeof(read_mac_addr)),
4407 "slave port (%d) mac address not as expected",
4408 test_params->slave_port_ids[0]);
4410 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4411 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4412 sizeof(read_mac_addr)),
4413 "slave port (%d) mac address not set to that of bonded port",
4414 test_params->slave_port_ids[1]);
4416 /* Clean up and remove slaves from bonded device */
4417 return remove_slaves_and_stop_bonded_device();
4421 test_tlb_verify_slave_link_status_change_failover(void)
4423 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4424 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4425 struct rte_eth_stats port_stats;
4427 uint8_t slaves[RTE_MAX_ETHPORTS];
4429 int i, j, burst_size, slave_count, primary_port;
4433 memset(pkt_burst, 0, sizeof(pkt_burst));
4437 /* Initialize bonded device with 4 slaves in round robin mode */
4438 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4439 BONDING_MODE_TLB, 0,
4440 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4441 "Failed to initialize bonded device with slaves");
4443 /* Verify Current Slaves Count /Active Slave Count is */
4444 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4446 TEST_ASSERT_EQUAL(slave_count, 4,
4447 "Number of slaves (%d) is not as expected (%d).\n",
4450 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4451 slaves, RTE_MAX_ETHPORTS);
4452 TEST_ASSERT_EQUAL(slave_count, (int)4,
4453 "Number of slaves (%d) is not as expected (%d).\n",
4456 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4457 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4458 "Primary port not as expected");
4460 /* Bring 2 slaves down and verify active slave count */
4461 virtual_ethdev_simulate_link_status_interrupt(
4462 test_params->slave_port_ids[1], 0);
4463 virtual_ethdev_simulate_link_status_interrupt(
4464 test_params->slave_port_ids[3], 0);
4466 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4467 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4468 "Number of active slaves (%d) is not as expected (%d).",
4471 virtual_ethdev_simulate_link_status_interrupt(
4472 test_params->slave_port_ids[1], 1);
4473 virtual_ethdev_simulate_link_status_interrupt(
4474 test_params->slave_port_ids[3], 1);
4477 /* Bring primary port down, verify that active slave count is 3 and primary
4479 virtual_ethdev_simulate_link_status_interrupt(
4480 test_params->slave_port_ids[0], 0);
4482 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4483 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4484 "Number of active slaves (%d) is not as expected (%d).",
4487 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4488 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4489 "Primary port not as expected");
4490 rte_delay_us(500000);
4491 /* Verify that pkts are sent on new primary slave */
4492 for (i = 0; i < 4; i++) {
4493 TEST_ASSERT_EQUAL(generate_test_burst(
4494 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4495 "generate_test_burst failed\n");
4496 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4497 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4498 "rte_eth_tx_burst failed\n");
4499 rte_delay_us(11000);
4502 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4503 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4504 "(%d) port_stats.opackets not as expected\n",
4505 test_params->slave_port_ids[0]);
4507 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4508 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4509 "(%d) port_stats.opackets not as expected\n",
4510 test_params->slave_port_ids[1]);
4512 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4513 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4514 "(%d) port_stats.opackets not as expected\n",
4515 test_params->slave_port_ids[2]);
4517 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4518 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4519 "(%d) port_stats.opackets not as expected\n",
4520 test_params->slave_port_ids[3]);
4523 /* Generate packet burst for testing */
4525 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4526 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4530 virtual_ethdev_add_mbufs_to_rx_queue(
4531 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4534 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4535 MAX_PKT_BURST) != burst_size) {
4536 printf("rte_eth_rx_burst\n");
4541 /* Verify bonded device rx count */
4542 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4543 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4544 "(%d) port_stats.ipackets not as expected\n",
4545 test_params->bonded_port_id);
4549 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4550 for (j = 0; j < MAX_PKT_BURST; j++) {
4551 if (pkt_burst[i][j] != NULL) {
4552 rte_pktmbuf_free(pkt_burst[i][j]);
4553 pkt_burst[i][j] = NULL;
4559 /* Clean up and remove slaves from bonded device */
4560 return remove_slaves_and_stop_bonded_device();
4563 #define TEST_ALB_SLAVE_COUNT 2
4565 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4566 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4567 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4568 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4570 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4571 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4572 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4573 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4574 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4577 test_alb_change_mac_in_reply_sent(void)
4579 struct rte_mbuf *pkt;
4580 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4582 struct ether_hdr *eth_pkt;
4583 struct arp_hdr *arp_pkt;
4585 int slave_idx, nb_pkts, pkt_idx;
4588 struct ether_addr bond_mac, client_mac;
4589 struct ether_addr *slave_mac1, *slave_mac2;
4591 TEST_ASSERT_SUCCESS(
4592 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4593 0, TEST_ALB_SLAVE_COUNT, 1),
4594 "Failed to initialize_bonded_device_with_slaves.");
4596 /* Flush tx queue */
4597 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4598 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4600 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4601 test_params->slave_port_ids[slave_idx], pkts_sent,
4606 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4610 * Generating four packets with different mac and ip addresses and sending
4611 * them through the bonding port.
4613 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4614 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4615 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4616 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4618 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4619 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4621 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4623 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4624 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4625 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4626 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4628 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4629 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4631 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4633 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4634 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4635 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4636 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4638 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4639 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4641 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4643 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4644 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4645 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4646 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4648 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4649 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4651 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4654 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4656 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4659 * Checking if packets are properly distributed on bonding ports. Packets
4660 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4662 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4663 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4664 test_params->slave_port_ids[slave_idx], pkts_sent,
4667 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4668 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4669 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4671 if (slave_idx%2 == 0) {
4672 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4677 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4686 retval += remove_slaves_and_stop_bonded_device();
4691 test_alb_reply_from_client(void)
4693 struct ether_hdr *eth_pkt;
4694 struct arp_hdr *arp_pkt;
4696 struct rte_mbuf *pkt;
4697 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4699 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4702 struct ether_addr bond_mac, client_mac;
4703 struct ether_addr *slave_mac1, *slave_mac2;
4705 TEST_ASSERT_SUCCESS(
4706 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4707 0, TEST_ALB_SLAVE_COUNT, 1),
4708 "Failed to initialize_bonded_device_with_slaves.");
4710 /* Flush tx queue */
4711 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4712 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4713 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4714 test_params->slave_port_ids[slave_idx], pkts_sent,
4719 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4723 * Generating four packets with different mac and ip addresses and placing
4724 * them in the rx queue to be received by the bonding driver on rx_burst.
4726 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4727 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4728 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4729 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4731 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4732 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4734 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4737 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4738 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4739 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4740 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4742 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4743 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4745 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4748 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4749 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4750 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4751 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4753 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4754 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4756 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4759 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4760 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4761 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4762 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4764 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4765 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4767 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4771 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4772 * packets to every client in alb table.
4774 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4775 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4777 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4778 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4781 * Checking if update ARP packets were properly send on slave ports.
4783 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4784 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4785 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4786 nb_pkts_sum += nb_pkts;
4788 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4789 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4790 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4792 if (slave_idx%2 == 0) {
4793 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4798 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4806 /* Check if proper number of packets was send */
4807 if (nb_pkts_sum < 4) {
4813 retval += remove_slaves_and_stop_bonded_device();
4818 test_alb_receive_vlan_reply(void)
4820 struct ether_hdr *eth_pkt;
4821 struct vlan_hdr *vlan_pkt;
4822 struct arp_hdr *arp_pkt;
4824 struct rte_mbuf *pkt;
4825 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4827 int slave_idx, nb_pkts, pkt_idx;
4830 struct ether_addr bond_mac, client_mac;
4832 TEST_ASSERT_SUCCESS(
4833 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4834 0, TEST_ALB_SLAVE_COUNT, 1),
4835 "Failed to initialize_bonded_device_with_slaves.");
4837 /* Flush tx queue */
4838 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4839 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4840 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4841 test_params->slave_port_ids[slave_idx], pkts_sent,
4846 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4850 * Generating packet with double VLAN header and placing it in the rx queue.
4852 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4853 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4854 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4855 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4857 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4858 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4859 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4860 vlan_pkt = vlan_pkt+1;
4861 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4862 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4863 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4864 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4866 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4869 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4870 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4873 * Checking if VLAN headers in generated ARP Update packet are correct.
4875 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4876 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4877 test_params->slave_port_ids[slave_idx], pkts_sent,
4880 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4881 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4882 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4883 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4887 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4891 vlan_pkt = vlan_pkt+1;
4892 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4896 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4904 retval += remove_slaves_and_stop_bonded_device();
4909 test_alb_ipv4_tx(void)
4911 int burst_size, retval, pkts_send;
4912 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4916 TEST_ASSERT_SUCCESS(
4917 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4918 0, TEST_ALB_SLAVE_COUNT, 1),
4919 "Failed to initialize_bonded_device_with_slaves.");
4923 /* Generate test bursts of packets to transmit */
4924 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4930 * Checking if ipv4 traffic is transmitted via TLB policy.
4932 pkts_send = rte_eth_tx_burst(
4933 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4934 if (pkts_send != burst_size) {
4940 retval += remove_slaves_and_stop_bonded_device();
4944 static struct unit_test_suite link_bonding_test_suite = {
4945 .suite_name = "Link Bonding Unit Test Suite",
4946 .setup = test_setup,
4947 .teardown = testsuite_teardown,
4948 .unit_test_cases = {
4949 TEST_CASE(test_create_bonded_device),
4950 TEST_CASE(test_create_bonded_device_with_invalid_params),
4951 TEST_CASE(test_add_slave_to_bonded_device),
4952 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4953 TEST_CASE(test_remove_slave_from_bonded_device),
4954 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4955 TEST_CASE(test_get_slaves_from_bonded_device),
4956 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4957 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4958 TEST_CASE(test_start_bonded_device),
4959 TEST_CASE(test_stop_bonded_device),
4960 TEST_CASE(test_set_bonding_mode),
4961 TEST_CASE(test_set_primary_slave),
4962 TEST_CASE(test_set_explicit_bonded_mac),
4963 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4964 TEST_CASE(test_status_interrupt),
4965 TEST_CASE(test_adding_slave_after_bonded_device_started),
4966 TEST_CASE(test_roundrobin_tx_burst),
4967 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4968 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4969 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4970 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4971 TEST_CASE(test_roundrobin_verify_mac_assignment),
4972 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4973 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4974 TEST_CASE(test_activebackup_tx_burst),
4975 TEST_CASE(test_activebackup_rx_burst),
4976 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4977 TEST_CASE(test_activebackup_verify_mac_assignment),
4978 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4979 TEST_CASE(test_balance_xmit_policy_configuration),
4980 TEST_CASE(test_balance_l2_tx_burst),
4981 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4982 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4983 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4984 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4985 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4986 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4987 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4988 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4989 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4990 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4991 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4992 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4993 TEST_CASE(test_balance_rx_burst),
4994 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4995 TEST_CASE(test_balance_verify_mac_assignment),
4996 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4997 TEST_CASE(test_tlb_tx_burst),
4998 TEST_CASE(test_tlb_rx_burst),
4999 TEST_CASE(test_tlb_verify_mac_assignment),
5000 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
5001 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
5002 TEST_CASE(test_alb_change_mac_in_reply_sent),
5003 TEST_CASE(test_alb_reply_from_client),
5004 TEST_CASE(test_alb_receive_vlan_reply),
5005 TEST_CASE(test_alb_ipv4_tx),
5006 #ifdef RTE_MBUF_REFCNT
5007 TEST_CASE(test_broadcast_tx_burst),
5008 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
5009 TEST_CASE(test_broadcast_rx_burst),
5010 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
5011 TEST_CASE(test_broadcast_verify_mac_assignment),
5012 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
5014 TEST_CASE(test_reconfigure_bonded_device),
5015 TEST_CASE(test_close_bonded_device),
5017 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
5023 test_link_bonding(void)
5025 return unit_test_suite_runner(&link_bonding_test_suite);
5028 static struct test_command link_bonding_cmd = {
5029 .command = "link_bonding_autotest",
5030 .callback = test_link_bonding,
5032 REGISTER_TEST_COMMAND(link_bonding_cmd);