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_DATA_SIZE (2048 + RTE_PKTMBUF_HEADROOM)
79 #define MBUF_CACHE_SIZE (250)
80 #define BURST_SIZE (32)
82 #define DEFAULT_MBUF_DATA_SIZE (2048)
83 #define RTE_TEST_RX_DESC_MAX (2048)
84 #define RTE_TEST_TX_DESC_MAX (2048)
85 #define MAX_PKT_BURST (512)
86 #define DEF_PKT_BURST (16)
88 #define BONDED_DEV_NAME ("unit_test_bonded_device")
90 #define INVALID_SOCKET_ID (-1)
91 #define INVALID_PORT_ID (-1)
92 #define INVALID_BONDING_MODE (-1)
95 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
96 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
98 struct link_bonding_unittest_params {
99 int8_t bonded_port_id;
100 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
101 uint8_t bonded_slave_count;
102 uint8_t bonding_mode;
107 struct rte_mempool *mbuf_pool;
109 struct ether_addr *default_slave_mac;
110 struct ether_addr *default_bonded_mac;
113 struct ether_hdr *pkt_eth_hdr;
114 struct ipv4_hdr *pkt_ipv4_hdr;
115 struct ipv6_hdr *pkt_ipv6_hdr;
116 struct udp_hdr *pkt_udp_hdr;
120 static struct ipv4_hdr pkt_ipv4_hdr;
121 static struct ipv6_hdr pkt_ipv6_hdr;
122 static struct udp_hdr pkt_udp_hdr;
124 static struct link_bonding_unittest_params default_params = {
125 .bonded_port_id = -1,
126 .slave_port_ids = { -1 },
127 .bonded_slave_count = 0,
128 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
135 .default_slave_mac = (struct ether_addr *)slave_mac,
136 .default_bonded_mac = (struct ether_addr *)bonded_mac,
139 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
140 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
141 .pkt_udp_hdr = &pkt_udp_hdr
145 static struct link_bonding_unittest_params *test_params = &default_params;
147 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
148 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
151 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
152 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
155 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
156 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
157 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
158 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
159 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
160 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
162 static uint16_t src_port = 1024;
163 static uint16_t dst_port_0 = 1024;
164 static uint16_t dst_port_1 = 2024;
166 static uint16_t vlan_id = 0x100;
168 struct rte_eth_rxmode rx_mode = {
169 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
171 .header_split = 0, /**< Header Split disabled. */
172 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
173 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
174 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
175 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
176 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
177 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
180 struct rte_fdir_conf fdir_conf = {
181 .mode = RTE_FDIR_MODE_NONE,
182 .pballoc = RTE_FDIR_PBALLOC_64K,
183 .status = RTE_FDIR_REPORT_STATUS,
187 static struct rte_eth_conf default_pmd_conf = {
189 .mq_mode = ETH_MQ_RX_NONE,
190 .max_rx_pkt_len = ETHER_MAX_LEN,
192 .header_split = 0, /**< Header Split disabled */
193 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
194 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
195 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
196 .hw_strip_crc = 0, /**< CRC stripped by hardware */
199 .mq_mode = ETH_MQ_TX_NONE,
204 static const struct rte_eth_rxconf rx_conf_default = {
206 .pthresh = RX_PTHRESH,
207 .hthresh = RX_HTHRESH,
208 .wthresh = RX_WTHRESH,
210 .rx_free_thresh = RX_FREE_THRESH,
214 static struct rte_eth_txconf tx_conf_default = {
216 .pthresh = TX_PTHRESH,
217 .hthresh = TX_HTHRESH,
218 .wthresh = TX_WTHRESH,
220 .tx_free_thresh = TX_FREE_THRESH,
221 .tx_rs_thresh = TX_RSBIT_THRESH,
222 .txq_flags = TX_Q_FLAGS
227 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
232 default_pmd_conf.intr_conf.lsc = 1;
234 default_pmd_conf.intr_conf.lsc = 0;
236 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
237 test_params->nb_tx_q, &default_pmd_conf),
238 "rte_eth_dev_configure for port %d failed", port_id);
240 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
241 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
242 rte_eth_dev_socket_id(port_id), &rx_conf_default,
243 test_params->mbuf_pool) ,
244 "rte_eth_rx_queue_setup for port %d failed", port_id);
246 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
247 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
248 rte_eth_dev_socket_id(port_id), &tx_conf_default),
249 "rte_eth_tx_queue_setup for port %d failed", port_id);
252 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
253 "rte_eth_dev_start for port %d failed", port_id);
258 static int slaves_initialized;
260 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
261 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
267 int i, nb_mbuf_per_pool;
268 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
270 /* Allocate ethernet packet header with space for VLAN header */
271 if (test_params->pkt_eth_hdr == NULL) {
272 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
273 sizeof(struct vlan_hdr));
275 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
276 "Ethernet header struct allocation failed!");
279 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
280 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
281 if (test_params->mbuf_pool == NULL) {
282 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
283 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0, MBUF_DATA_SIZE,
285 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
286 "rte_mempool_create failed");
289 /* Create / Initialize virtual eth devs */
290 if (!slaves_initialized) {
291 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
292 char pmd_name[RTE_ETH_NAME_MAX_LEN];
294 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
296 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
298 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
299 mac_addr, rte_socket_id(), 1);
300 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
301 "Failed to create virtual virtual ethdev %s", pmd_name);
303 TEST_ASSERT_SUCCESS(configure_ethdev(
304 test_params->slave_port_ids[i], 1, 0),
305 "Failed to configure virtual ethdev %s", pmd_name);
307 slaves_initialized = 1;
314 test_create_bonded_device(void)
316 int current_slave_count;
318 uint8_t slaves[RTE_MAX_ETHPORTS];
320 /* Don't try to recreate bonded device if re-running test suite*/
321 if (test_params->bonded_port_id == -1) {
322 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
323 test_params->bonding_mode, rte_socket_id());
325 TEST_ASSERT(test_params->bonded_port_id >= 0,
326 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
328 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
329 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
332 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
333 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
334 test_params->bonded_port_id, test_params->bonding_mode);
336 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
337 slaves, RTE_MAX_ETHPORTS);
339 TEST_ASSERT_EQUAL(current_slave_count, 0,
340 "Number of slaves %d is great than expected %d.",
341 current_slave_count, 0);
343 current_slave_count = rte_eth_bond_active_slaves_get(
344 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
346 TEST_ASSERT_EQUAL(current_slave_count, 0,
347 "Number of active slaves %d is great than expected %d.",
348 current_slave_count, 0);
355 test_create_bonded_device_with_invalid_params(void)
359 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
362 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
364 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
366 test_params->bonding_mode = INVALID_BONDING_MODE;
368 /* Invalid bonding mode */
369 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
371 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
373 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
375 /* Invalid socket id */
376 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
378 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
384 test_add_slave_to_bonded_device(void)
386 int current_slave_count;
388 uint8_t slaves[RTE_MAX_ETHPORTS];
390 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
391 test_params->slave_port_ids[test_params->bonded_slave_count]),
392 "Failed to add slave (%d) to bonded port (%d).",
393 test_params->slave_port_ids[test_params->bonded_slave_count],
394 test_params->bonded_port_id);
396 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
397 slaves, RTE_MAX_ETHPORTS);
398 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
399 "Number of slaves (%d) is greater than expected (%d).",
400 current_slave_count, test_params->bonded_slave_count + 1);
402 current_slave_count = rte_eth_bond_active_slaves_get(
403 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
404 TEST_ASSERT_EQUAL(current_slave_count, 0,
405 "Number of active slaves (%d) is not as expected (%d).\n",
406 current_slave_count, 0);
408 test_params->bonded_slave_count++;
414 test_add_slave_to_invalid_bonded_device(void)
416 /* Invalid port ID */
417 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
418 test_params->slave_port_ids[test_params->bonded_slave_count]),
419 "Expected call to failed as invalid port specified.");
421 /* Non bonded device */
422 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
423 test_params->slave_port_ids[test_params->bonded_slave_count]),
424 "Expected call to failed as invalid port specified.");
431 test_remove_slave_from_bonded_device(void)
433 int current_slave_count;
434 struct ether_addr read_mac_addr, *mac_addr;
435 uint8_t slaves[RTE_MAX_ETHPORTS];
437 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
438 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
439 "Failed to remove slave %d from bonded port (%d).",
440 test_params->slave_port_ids[test_params->bonded_slave_count-1],
441 test_params->bonded_port_id);
444 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
445 slaves, RTE_MAX_ETHPORTS);
447 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
448 "Number of slaves (%d) is great than expected (%d).\n",
449 current_slave_count, test_params->bonded_slave_count - 1);
452 mac_addr = (struct ether_addr *)slave_mac;
453 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
454 test_params->bonded_slave_count-1;
457 test_params->slave_port_ids[test_params->bonded_slave_count-1],
459 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
460 "bonded port mac address not set to that of primary port\n");
463 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
465 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
468 test_params->bonded_slave_count--;
474 test_remove_slave_from_invalid_bonded_device(void)
476 /* Invalid port ID */
477 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
478 test_params->bonded_port_id + 5,
479 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
480 "Expected call to failed as invalid port specified.");
482 /* Non bonded device */
483 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
484 test_params->slave_port_ids[0],
485 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
486 "Expected call to failed as invalid port specified.");
491 static int bonded_id = 2;
494 test_add_already_bonded_slave_to_bonded_device(void)
496 int port_id, current_slave_count;
497 uint8_t slaves[RTE_MAX_ETHPORTS];
498 char pmd_name[RTE_ETH_NAME_MAX_LEN];
500 test_add_slave_to_bonded_device();
502 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
503 slaves, RTE_MAX_ETHPORTS);
504 TEST_ASSERT_EQUAL(current_slave_count, 1,
505 "Number of slaves (%d) is not that expected (%d).",
506 current_slave_count, 1);
508 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
510 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
512 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
514 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
515 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
517 "Added slave (%d) to bonded port (%d) unexpectedly.",
518 test_params->slave_port_ids[test_params->bonded_slave_count-1],
521 return test_remove_slave_from_bonded_device();
526 test_get_slaves_from_bonded_device(void)
528 int current_slave_count;
529 uint8_t slaves[RTE_MAX_ETHPORTS];
531 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
532 "Failed to add slave to bonded device");
534 /* Invalid port id */
535 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
537 TEST_ASSERT(current_slave_count < 0,
538 "Invalid port id unexpectedly succeeded");
540 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
541 slaves, RTE_MAX_ETHPORTS);
542 TEST_ASSERT(current_slave_count < 0,
543 "Invalid port id unexpectedly succeeded");
545 /* Invalid slaves pointer */
546 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
547 NULL, RTE_MAX_ETHPORTS);
548 TEST_ASSERT(current_slave_count < 0,
549 "Invalid slave array unexpectedly succeeded");
551 current_slave_count = rte_eth_bond_active_slaves_get(
552 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
553 TEST_ASSERT(current_slave_count < 0,
554 "Invalid slave array unexpectedly succeeded");
556 /* non bonded device*/
557 current_slave_count = rte_eth_bond_slaves_get(
558 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
559 TEST_ASSERT(current_slave_count < 0,
560 "Invalid port id unexpectedly succeeded");
562 current_slave_count = rte_eth_bond_active_slaves_get(
563 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
564 TEST_ASSERT(current_slave_count < 0,
565 "Invalid port id unexpectedly succeeded");
567 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
568 "Failed to remove slaves from bonded device");
575 test_add_remove_multiple_slaves_to_from_bonded_device(void)
579 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
580 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
581 "Failed to add slave to bonded device");
583 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
584 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
585 "Failed to remove slaves from bonded device");
591 enable_bonded_slaves(void)
595 for (i = 0; i < test_params->bonded_slave_count; i++) {
596 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
599 virtual_ethdev_simulate_link_status_interrupt(
600 test_params->slave_port_ids[i], 1);
605 test_start_bonded_device(void)
607 struct rte_eth_link link_status;
609 int current_slave_count, current_bonding_mode, primary_port;
610 uint8_t slaves[RTE_MAX_ETHPORTS];
612 /* Add slave to bonded device*/
613 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
614 "Failed to add slave to bonded device");
616 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
617 "Failed to start bonded pmd eth device %d.",
618 test_params->bonded_port_id);
620 /* Change link status of virtual pmd so it will be added to the active
621 * slave list of the bonded device*/
622 virtual_ethdev_simulate_link_status_interrupt(
623 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
625 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
626 slaves, RTE_MAX_ETHPORTS);
627 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
628 "Number of slaves (%d) is not expected value (%d).",
629 current_slave_count, test_params->bonded_slave_count);
631 current_slave_count = rte_eth_bond_active_slaves_get(
632 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
633 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
634 "Number of active slaves (%d) is not expected value (%d).",
635 current_slave_count, test_params->bonded_slave_count);
637 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
638 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
639 "Bonded device mode (%d) is not expected value (%d).\n",
640 current_bonding_mode, test_params->bonding_mode);
642 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
643 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
644 "Primary port (%d) is not expected value (%d).",
645 primary_port, test_params->slave_port_ids[0]);
647 rte_eth_link_get(test_params->bonded_port_id, &link_status);
648 TEST_ASSERT_EQUAL(link_status.link_status, 1,
649 "Bonded port (%d) status (%d) is not expected value (%d).\n",
650 test_params->bonded_port_id, link_status.link_status, 1);
656 test_stop_bonded_device(void)
658 int current_slave_count;
659 uint8_t slaves[RTE_MAX_ETHPORTS];
661 struct rte_eth_link link_status;
663 rte_eth_dev_stop(test_params->bonded_port_id);
665 rte_eth_link_get(test_params->bonded_port_id, &link_status);
666 TEST_ASSERT_EQUAL(link_status.link_status, 0,
667 "Bonded port (%d) status (%d) is not expected value (%d).",
668 test_params->bonded_port_id, link_status.link_status, 0);
670 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
671 slaves, RTE_MAX_ETHPORTS);
672 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
673 "Number of slaves (%d) is not expected value (%d).",
674 current_slave_count, test_params->bonded_slave_count);
676 current_slave_count = rte_eth_bond_active_slaves_get(
677 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
678 TEST_ASSERT_EQUAL(current_slave_count, 0,
679 "Number of active slaves (%d) is not expected value (%d).",
680 current_slave_count, 0);
686 remove_slaves_and_stop_bonded_device(void)
688 /* Clean up and remove slaves from bonded device */
689 while (test_params->bonded_slave_count > 0)
690 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
691 "test_remove_slave_from_bonded_device failed");
693 rte_eth_dev_stop(test_params->bonded_port_id);
694 rte_eth_stats_reset(test_params->bonded_port_id);
695 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
701 test_set_bonding_mode(void)
705 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
706 BONDING_MODE_ACTIVE_BACKUP,
707 BONDING_MODE_BALANCE,
708 BONDING_MODE_BROADCAST
711 /* Test supported link bonding modes */
712 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
713 /* Invalid port ID */
714 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
716 "Expected call to failed as invalid port (%d) specified.",
719 /* Non bonded device */
720 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
722 "Expected call to failed as invalid port (%d) specified.",
723 test_params->slave_port_ids[0]);
725 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
727 "Failed to set link bonding mode on port (%d) to (%d).",
728 test_params->bonded_port_id, bonding_modes[i]);
730 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
731 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
732 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
733 bonding_mode, test_params->bonded_port_id,
736 /* Invalid port ID */
737 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
738 TEST_ASSERT(bonding_mode < 0,
739 "Expected call to failed as invalid port (%d) specified.",
742 /* Non bonded device */
743 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
744 TEST_ASSERT(bonding_mode < 0,
745 "Expected call to failed as invalid port (%d) specified.",
746 test_params->slave_port_ids[0]);
749 return remove_slaves_and_stop_bonded_device();
753 test_set_primary_slave(void)
756 struct ether_addr read_mac_addr;
757 struct ether_addr *expected_mac_addr;
759 /* Add 4 slaves to bonded device */
760 for (i = test_params->bonded_slave_count; i < 4; i++)
761 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
762 "Failed to add slave to bonded device.");
764 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
765 BONDING_MODE_ROUND_ROBIN),
766 "Failed to set link bonding mode on port (%d) to (%d).",
767 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
769 /* Invalid port ID */
770 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
771 test_params->slave_port_ids[i]),
772 "Expected call to failed as invalid port specified.");
774 /* Non bonded device */
775 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
776 test_params->slave_port_ids[i]),
777 "Expected call to failed as invalid port specified.");
779 /* Set slave as primary
780 * Verify slave it is now primary slave
781 * Verify that MAC address of bonded device is that of primary slave
782 * Verify that MAC address of all bonded slaves are that of primary slave
784 for (i = 0; i < 4; i++) {
785 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
786 test_params->slave_port_ids[i]),
787 "Failed to set bonded port (%d) primary port to (%d)",
788 test_params->bonded_port_id, test_params->slave_port_ids[i]);
790 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
791 TEST_ASSERT(retval >= 0,
792 "Failed to read primary port from bonded port (%d)\n",
793 test_params->bonded_port_id);
795 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
796 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
797 test_params->bonded_port_id, retval,
798 test_params->slave_port_ids[i]);
800 /* stop/start bonded eth dev to apply new MAC */
801 rte_eth_dev_stop(test_params->bonded_port_id);
803 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
804 "Failed to start bonded port %d",
805 test_params->bonded_port_id);
807 expected_mac_addr = (struct ether_addr *)&slave_mac;
808 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
810 /* Check primary slave MAC */
811 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
812 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
813 sizeof(read_mac_addr)),
814 "bonded port mac address not set to that of primary port\n");
816 /* Check bonded MAC */
817 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
818 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
819 sizeof(read_mac_addr)),
820 "bonded port mac address not set to that of primary port\n");
822 /* Check other slaves MACs */
823 for (j = 0; j < 4; j++) {
825 rte_eth_macaddr_get(test_params->slave_port_ids[j],
827 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
828 sizeof(read_mac_addr)),
829 "slave port mac address not set to that of primary "
836 /* Test with none existent port */
837 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
838 "read primary port from expectedly");
840 /* Test with slave port */
841 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
842 "read primary port from expectedly\n");
844 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
845 "Failed to stop and remove slaves from bonded device");
848 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
849 "read primary port from expectedly\n");
855 test_set_explicit_bonded_mac(void)
858 struct ether_addr read_mac_addr;
859 struct ether_addr *mac_addr;
861 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
863 mac_addr = (struct ether_addr *)explicit_bonded_mac;
865 /* Invalid port ID */
866 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
867 "Expected call to failed as invalid port specified.");
869 /* Non bonded device */
870 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
871 test_params->slave_port_ids[0], mac_addr),
872 "Expected call to failed as invalid port specified.");
874 /* NULL MAC address */
875 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
876 test_params->bonded_port_id, NULL),
877 "Expected call to failed as NULL MAC specified");
879 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
880 test_params->bonded_port_id, mac_addr),
881 "Failed to set MAC address on bonded port (%d)",
882 test_params->bonded_port_id);
884 /* Add 4 slaves to bonded device */
885 for (i = test_params->bonded_slave_count; i < 4; i++) {
886 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
887 "Failed to add slave to bonded device.\n");
890 /* Check bonded MAC */
891 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
892 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
893 "bonded port mac address not set to that of primary port");
895 /* Check other slaves MACs */
896 for (i = 0; i < 4; i++) {
897 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
898 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
899 sizeof(read_mac_addr)),
900 "slave port mac address not set to that of primary port");
903 /* test resetting mac address on bonded device */
905 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
906 "Failed to reset MAC address on bonded port (%d)",
907 test_params->bonded_port_id);
910 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
911 "Reset MAC address on bonded port (%d) unexpectedly",
912 test_params->slave_port_ids[1]);
914 /* test resetting mac address on bonded device with no slaves */
915 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
916 "Failed to remove slaves and stop bonded device");
918 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
919 "Failed to reset MAC address on bonded port (%d)",
920 test_params->bonded_port_id);
925 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
928 test_set_bonded_port_initialization_mac_assignment(void)
930 int i, slave_count, bonded_port_id;
932 uint8_t slaves[RTE_MAX_ETHPORTS];
933 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
935 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
937 /* Initialize default values for MAC addresses */
938 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
939 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
942 * 1. a - Create / configure bonded / slave ethdevs
944 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
945 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
946 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
948 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
949 "Failed to configure bonded ethdev");
951 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
952 char pmd_name[RTE_ETH_NAME_MAX_LEN];
954 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
956 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
958 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
959 &slave_mac_addr, rte_socket_id(), 1);
961 TEST_ASSERT(slave_port_ids[i] >= 0,
962 "Failed to create slave ethdev %s", pmd_name);
964 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
965 "Failed to configure virtual ethdev %s",
971 * 2. Add slave ethdevs to bonded device
973 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
974 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
976 "Failed to add slave (%d) to bonded port (%d).",
977 slave_port_ids[i], bonded_port_id);
980 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
982 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
983 "Number of slaves (%d) is not as expected (%d)",
984 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
988 * 3. Set explicit MAC address on bonded ethdev
990 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
991 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
993 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
994 bonded_port_id, &bonded_mac_addr),
995 "Failed to set MAC address on bonded port (%d)",
999 /* 4. a - Start bonded ethdev
1000 * b - Enable slave devices
1001 * c - Verify bonded/slaves ethdev MAC addresses
1003 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1004 "Failed to start bonded pmd eth device %d.",
1007 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1008 virtual_ethdev_simulate_link_status_interrupt(
1009 slave_port_ids[i], 1);
1012 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1013 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1014 sizeof(read_mac_addr)),
1015 "bonded port mac address not as expected");
1017 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1018 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1019 sizeof(read_mac_addr)),
1020 "slave port 0 mac address not as expected");
1022 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1023 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1024 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1025 sizeof(read_mac_addr)),
1026 "slave port 1 mac address not as expected");
1028 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1029 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1030 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1031 sizeof(read_mac_addr)),
1032 "slave port 2 mac address not as expected");
1035 /* 7. a - Change primary port
1036 * b - Stop / Start bonded port
1037 * d - Verify slave ethdev MAC addresses
1039 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1041 "failed to set primary port on bonded device.");
1043 rte_eth_dev_stop(bonded_port_id);
1044 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1045 "Failed to start bonded pmd eth device %d.",
1048 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1049 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1050 sizeof(read_mac_addr)),
1051 "bonded port mac address not as expected");
1053 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1054 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1055 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1056 sizeof(read_mac_addr)),
1057 "slave port 0 mac address not as expected");
1059 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1060 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1061 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1062 sizeof(read_mac_addr)),
1063 "slave port 1 mac address not as expected");
1065 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1066 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1067 sizeof(read_mac_addr)),
1068 "slave port 2 mac address not as expected");
1070 /* 6. a - Stop bonded ethdev
1071 * b - remove slave ethdevs
1072 * c - Verify slave ethdevs MACs are restored
1074 rte_eth_dev_stop(bonded_port_id);
1076 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1077 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1079 "Failed to remove slave %d from bonded port (%d).",
1080 slave_port_ids[i], bonded_port_id);
1083 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1086 TEST_ASSERT_EQUAL(slave_count, 0,
1087 "Number of slaves (%d) is great than expected (%d).",
1090 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1091 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1092 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1093 sizeof(read_mac_addr)),
1094 "slave port 0 mac address not as expected");
1096 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1097 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1098 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1099 sizeof(read_mac_addr)),
1100 "slave port 1 mac address not as expected");
1102 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1103 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1104 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1105 sizeof(read_mac_addr)),
1106 "slave port 2 mac address not as expected");
1113 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1114 uint8_t number_of_slaves, uint8_t enable_slave)
1116 /* Configure bonded device */
1117 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1118 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1119 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1122 /* Add slaves to bonded device */
1123 while (number_of_slaves > test_params->bonded_slave_count)
1124 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1125 "Failed to add slave (%d to bonding port (%d).",
1126 test_params->bonded_slave_count - 1,
1127 test_params->bonded_port_id);
1129 /* Set link bonding mode */
1130 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1132 "Failed to set link bonding mode on port (%d) to (%d).",
1133 test_params->bonded_port_id, bonding_mode);
1135 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1136 "Failed to start bonded pmd eth device %d.",
1137 test_params->bonded_port_id);
1140 enable_bonded_slaves();
1146 test_adding_slave_after_bonded_device_started(void)
1150 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1151 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1152 "Failed to add slaves to bonded device");
1154 /* Enabled slave devices */
1155 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1156 virtual_ethdev_simulate_link_status_interrupt(
1157 test_params->slave_port_ids[i], 1);
1160 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1161 test_params->slave_port_ids[test_params->bonded_slave_count]),
1162 "Failed to add slave to bonded port.\n");
1164 rte_eth_stats_reset(
1165 test_params->slave_port_ids[test_params->bonded_slave_count]);
1167 test_params->bonded_slave_count++;
1169 return remove_slaves_and_stop_bonded_device();
1172 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1173 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1175 int test_lsc_interrupt_count;
1179 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1180 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1182 pthread_mutex_lock(&mutex);
1183 test_lsc_interrupt_count++;
1185 pthread_cond_signal(&cvar);
1186 pthread_mutex_unlock(&mutex);
1190 lsc_timeout(int wait_us)
1197 gettimeofday(&tp, NULL);
1199 /* Convert from timeval to timespec */
1200 ts.tv_sec = tp.tv_sec;
1201 ts.tv_nsec = tp.tv_usec * 1000;
1202 ts.tv_nsec += wait_us * 1000;
1204 pthread_mutex_lock(&mutex);
1205 if (test_lsc_interrupt_count < 1)
1206 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1208 pthread_mutex_unlock(&mutex);
1210 if (retval == 0 && test_lsc_interrupt_count < 1)
1217 test_status_interrupt(void)
1220 uint8_t slaves[RTE_MAX_ETHPORTS];
1222 /* initialized bonding device with T slaves */
1223 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1224 BONDING_MODE_ROUND_ROBIN, 1,
1225 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1226 "Failed to initialise bonded device");
1228 test_lsc_interrupt_count = 0;
1230 /* register link status change interrupt callback */
1231 rte_eth_dev_callback_register(test_params->bonded_port_id,
1232 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1233 &test_params->bonded_port_id);
1235 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1236 slaves, RTE_MAX_ETHPORTS);
1238 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1239 "Number of active slaves (%d) is not as expected (%d)",
1240 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1242 /* Bring all 4 slaves link status to down and test that we have received a
1244 virtual_ethdev_simulate_link_status_interrupt(
1245 test_params->slave_port_ids[0], 0);
1246 virtual_ethdev_simulate_link_status_interrupt(
1247 test_params->slave_port_ids[1], 0);
1248 virtual_ethdev_simulate_link_status_interrupt(
1249 test_params->slave_port_ids[2], 0);
1251 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1252 "Received a link status change interrupt unexpectedly");
1254 virtual_ethdev_simulate_link_status_interrupt(
1255 test_params->slave_port_ids[3], 0);
1257 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1258 "timed out waiting for interrupt");
1260 TEST_ASSERT(test_lsc_interrupt_count > 0,
1261 "Did not receive link status change interrupt");
1263 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1264 slaves, RTE_MAX_ETHPORTS);
1266 TEST_ASSERT_EQUAL(slave_count, 0,
1267 "Number of active slaves (%d) is not as expected (%d)",
1270 /* bring one slave port up so link status will change */
1271 test_lsc_interrupt_count = 0;
1273 virtual_ethdev_simulate_link_status_interrupt(
1274 test_params->slave_port_ids[0], 1);
1276 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1277 "timed out waiting for interrupt");
1279 /* test that we have received another lsc interrupt */
1280 TEST_ASSERT(test_lsc_interrupt_count > 0,
1281 "Did not receive link status change interrupt");
1283 /* Verify that calling the same slave lsc interrupt doesn't cause another
1284 * lsc interrupt from bonded device */
1285 test_lsc_interrupt_count = 0;
1287 virtual_ethdev_simulate_link_status_interrupt(
1288 test_params->slave_port_ids[0], 1);
1290 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1291 "received unexpected interrupt");
1293 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1294 "Did not receive link status change interrupt");
1297 /* unregister lsc callback before exiting */
1298 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1299 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1300 &test_params->bonded_port_id);
1302 /* Clean up and remove slaves from bonded device */
1303 return remove_slaves_and_stop_bonded_device();
1307 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1308 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1309 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1311 uint16_t pktlen, generated_burst_size, ether_type;
1315 ether_type = ETHER_TYPE_IPv4;
1317 ether_type = ETHER_TYPE_IPv6;
1320 initialize_eth_header(test_params->pkt_eth_hdr,
1321 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1322 ether_type, vlan, vlan_id);
1324 initialize_eth_header(test_params->pkt_eth_hdr,
1325 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1326 ether_type, vlan, vlan_id);
1329 if (toggle_udp_port)
1330 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1333 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1338 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1339 dst_addr_1, pktlen);
1341 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1342 dst_addr_0, pktlen);
1344 ip_hdr = test_params->pkt_ipv4_hdr;
1347 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1348 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1351 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1352 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1355 ip_hdr = test_params->pkt_ipv6_hdr;
1358 /* Generate burst of packets to transmit */
1359 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1360 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1361 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1363 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1364 "Failed to generate packet burst");
1366 return generated_burst_size;
1369 /** Round Robin Mode Tests */
1372 test_roundrobin_tx_burst(void)
1375 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1376 struct rte_eth_stats port_stats;
1378 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1379 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1380 "Failed to intialise bonded device");
1382 burst_size = 20 * test_params->bonded_slave_count;
1384 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1385 "Burst size specified is greater than supported.");
1387 /* Generate test bursts of packets to transmit */
1388 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1389 burst_size, "failed to generate test burst");
1391 /* Send burst on bonded port */
1392 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1393 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1396 /* Verify bonded port tx stats */
1397 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1398 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1399 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1400 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1403 /* Verify slave ports tx stats */
1404 for (i = 0; i < test_params->bonded_slave_count; i++) {
1405 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1406 TEST_ASSERT_EQUAL(port_stats.opackets,
1407 (uint64_t)burst_size / test_params->bonded_slave_count,
1408 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1409 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1410 burst_size / test_params->bonded_slave_count);
1413 /* Put all slaves down and try and transmit */
1414 for (i = 0; i < test_params->bonded_slave_count; i++) {
1415 virtual_ethdev_simulate_link_status_interrupt(
1416 test_params->slave_port_ids[i], 0);
1419 /* Send burst on bonded port */
1420 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1421 pkt_burst, burst_size), 0,
1422 "tx burst return unexpected value");
1424 /* Clean up and remove slaves from bonded device */
1425 return remove_slaves_and_stop_bonded_device();
1429 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1433 for (i = 0; i < nb_mbufs; i++) {
1434 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1435 TEST_ASSERT_EQUAL(refcnt, val,
1436 "mbuf ref count (%d)is not the expected value (%d)",
1443 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1447 for (i = 0; i < nb_mbufs; i++)
1448 rte_pktmbuf_free(mbufs[i]);
1451 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1452 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1453 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1454 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1457 test_roundrobin_tx_burst_slave_tx_fail(void)
1459 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1460 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1462 struct rte_eth_stats port_stats;
1464 int i, first_fail_idx, tx_count;
1466 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1467 BONDING_MODE_ROUND_ROBIN, 0,
1468 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1469 "Failed to intialise bonded device");
1471 /* Generate test bursts of packets to transmit */
1472 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1473 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1474 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1475 "Failed to generate test packet burst");
1477 /* Copy references to packets which we expect not to be transmitted */
1478 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1479 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1480 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1481 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1483 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1484 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1485 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1488 /* Set virtual slave to only fail transmission of
1489 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1490 virtual_ethdev_tx_burst_fn_set_success(
1491 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1494 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1495 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1496 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1498 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1499 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1501 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1502 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1503 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1504 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1505 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1507 /* Verify that failed packet are expected failed packets */
1508 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1509 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1510 "expected mbuf (%d) pointer %p not expected pointer %p",
1511 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1514 /* Verify bonded port tx stats */
1515 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1517 TEST_ASSERT_EQUAL(port_stats.opackets,
1518 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1519 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1520 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1521 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1522 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1523 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1525 /* Verify slave ports tx stats */
1526 for (i = 0; i < test_params->bonded_slave_count; i++) {
1527 int slave_expected_tx_count;
1529 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1531 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1532 test_params->bonded_slave_count;
1534 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1535 slave_expected_tx_count = slave_expected_tx_count -
1536 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1538 TEST_ASSERT_EQUAL(port_stats.opackets,
1539 (uint64_t)slave_expected_tx_count,
1540 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1541 test_params->slave_port_ids[i],
1542 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1545 /* Verify that all mbufs have a ref value of zero */
1546 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1547 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1548 "mbufs refcnts not as expected");
1549 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1551 /* Clean up and remove slaves from bonded device */
1552 return remove_slaves_and_stop_bonded_device();
1556 test_roundrobin_rx_burst_on_single_slave(void)
1558 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1559 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1561 struct rte_eth_stats port_stats;
1563 int i, j, burst_size = 25;
1565 /* Initialize bonded device with 4 slaves in round robin mode */
1566 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1567 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1568 "Failed to initialize bonded device with slaves");
1570 /* Generate test bursts of packets to transmit */
1571 TEST_ASSERT_EQUAL(generate_test_burst(
1572 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1573 "burst generation failed");
1575 for (i = 0; i < test_params->bonded_slave_count; i++) {
1576 /* Add rx data to slave */
1577 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1578 &gen_pkt_burst[0], burst_size);
1580 /* Call rx burst on bonded device */
1581 /* Send burst on bonded port */
1582 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1583 test_params->bonded_port_id, 0, rx_pkt_burst,
1584 MAX_PKT_BURST), burst_size,
1585 "round-robin rx burst failed");
1587 /* Verify bonded device rx count */
1588 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1589 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1590 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1591 test_params->bonded_port_id,
1592 (unsigned int)port_stats.ipackets, burst_size);
1596 /* Verify bonded slave devices rx count */
1597 /* Verify slave ports tx stats */
1598 for (j = 0; j < test_params->bonded_slave_count; j++) {
1599 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1602 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1603 "Slave Port (%d) ipackets value (%u) not as expected"
1604 " (%d)", test_params->slave_port_ids[i],
1605 (unsigned int)port_stats.ipackets, burst_size);
1607 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1608 "Slave Port (%d) ipackets value (%u) not as expected"
1609 " (%d)", test_params->slave_port_ids[i],
1610 (unsigned int)port_stats.ipackets, 0);
1613 /* Reset bonded slaves stats */
1614 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1616 /* reset bonded device stats */
1617 rte_eth_stats_reset(test_params->bonded_port_id);
1621 for (i = 0; i < MAX_PKT_BURST; i++) {
1622 if (gen_pkt_burst[i] != NULL)
1623 rte_pktmbuf_free(gen_pkt_burst[i]);
1625 if (rx_pkt_burst[i] != NULL)
1626 rte_pktmbuf_free(rx_pkt_burst[i]);
1630 /* Clean up and remove slaves from bonded device */
1631 return remove_slaves_and_stop_bonded_device();
1634 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1637 test_roundrobin_rx_burst_on_multiple_slaves(void)
1639 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1641 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1642 struct rte_eth_stats port_stats;
1644 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1647 /* Initialize bonded device with 4 slaves in round robin mode */
1648 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1649 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1650 "Failed to initialize bonded device with slaves");
1652 /* Generate test bursts of packets to transmit */
1653 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1654 TEST_ASSERT_EQUAL(generate_test_burst(
1655 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1656 burst_size[i], "burst generation failed");
1659 /* Add rx data to slaves */
1660 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1661 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1662 &gen_pkt_burst[i][0], burst_size[i]);
1665 /* Call rx burst on bonded device */
1666 /* Send burst on bonded port */
1667 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1669 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1670 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1671 burst_size[0] + burst_size[1] + burst_size[2]);
1673 /* Verify bonded device rx count */
1674 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1675 TEST_ASSERT_EQUAL(port_stats.ipackets,
1676 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1677 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1678 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1679 burst_size[0] + burst_size[1] + burst_size[2]);
1681 /* Verify bonded slave devices rx counts */
1682 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1683 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1684 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1685 test_params->slave_port_ids[0],
1686 (unsigned int)port_stats.ipackets, burst_size[0]);
1688 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1689 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1690 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1691 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1694 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1695 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1696 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1697 test_params->slave_port_ids[2],
1698 (unsigned int)port_stats.ipackets, burst_size[2]);
1700 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1701 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1702 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1703 test_params->slave_port_ids[3],
1704 (unsigned int)port_stats.ipackets, 0);
1707 for (i = 0; i < MAX_PKT_BURST; i++) {
1708 if (rx_pkt_burst[i] != NULL)
1709 rte_pktmbuf_free(rx_pkt_burst[i]);
1712 /* Clean up and remove slaves from bonded device */
1713 return remove_slaves_and_stop_bonded_device();
1717 test_roundrobin_verify_mac_assignment(void)
1719 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1723 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1724 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1726 /* Initialize bonded device with 4 slaves in round robin mode */
1727 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1728 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1729 "Failed to initialize bonded device with slaves");
1731 /* Verify that all MACs are the same as first slave added to bonded dev */
1732 for (i = 0; i < test_params->bonded_slave_count; i++) {
1733 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1734 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1735 sizeof(read_mac_addr)),
1736 "slave port (%d) mac address not set to that of primary port",
1737 test_params->slave_port_ids[i]);
1740 /* change primary and verify that MAC addresses haven't changed */
1741 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1742 test_params->slave_port_ids[2]),
1743 "Failed to set bonded port (%d) primary port to (%d)",
1744 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1746 for (i = 0; i < test_params->bonded_slave_count; i++) {
1747 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1748 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1749 sizeof(read_mac_addr)),
1750 "slave port (%d) mac address has changed to that of primary"
1751 " port without stop/start toggle of bonded device",
1752 test_params->slave_port_ids[i]);
1755 /* stop / start bonded device and verify that primary MAC address is
1756 * propagate to bonded device and slaves */
1757 rte_eth_dev_stop(test_params->bonded_port_id);
1759 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1760 "Failed to start bonded device");
1762 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1763 TEST_ASSERT_SUCCESS(
1764 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1765 "bonded port (%d) mac address not set to that of new primary port",
1766 test_params->slave_port_ids[i]);
1768 for (i = 0; i < test_params->bonded_slave_count; i++) {
1769 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1770 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1771 sizeof(read_mac_addr)),
1772 "slave port (%d) mac address not set to that of new primary"
1773 " port", test_params->slave_port_ids[i]);
1776 /* Set explicit MAC address */
1777 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1778 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1779 "Failed to set MAC");
1781 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1782 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1783 sizeof(read_mac_addr)),
1784 "bonded port (%d) mac address not set to that of new primary port",
1785 test_params->slave_port_ids[i]);
1787 for (i = 0; i < test_params->bonded_slave_count; i++) {
1788 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1789 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1790 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1791 " that of new primary port\n", test_params->slave_port_ids[i]);
1794 /* Clean up and remove slaves from bonded device */
1795 return remove_slaves_and_stop_bonded_device();
1799 test_roundrobin_verify_promiscuous_enable_disable(void)
1801 int i, promiscuous_en;
1803 /* Initialize bonded device with 4 slaves in round robin mode */
1804 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1805 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1806 "Failed to initialize bonded device with slaves");
1808 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1810 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1811 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1812 "Port (%d) promiscuous mode not enabled",
1813 test_params->bonded_port_id);
1815 for (i = 0; i < test_params->bonded_slave_count; i++) {
1816 promiscuous_en = rte_eth_promiscuous_get(
1817 test_params->slave_port_ids[i]);
1818 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1819 "slave port (%d) promiscuous mode not enabled",
1820 test_params->slave_port_ids[i]);
1823 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1825 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1826 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1827 "Port (%d) promiscuous mode not disabled\n",
1828 test_params->bonded_port_id);
1830 for (i = 0; i < test_params->bonded_slave_count; i++) {
1831 promiscuous_en = rte_eth_promiscuous_get(
1832 test_params->slave_port_ids[i]);
1833 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1834 "Port (%d) promiscuous mode not disabled\n",
1835 test_params->slave_port_ids[i]);
1838 /* Clean up and remove slaves from bonded device */
1839 return remove_slaves_and_stop_bonded_device();
1842 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1843 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1846 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1848 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1849 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1850 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1852 struct rte_eth_stats port_stats;
1853 uint8_t slaves[RTE_MAX_ETHPORTS];
1855 int i, burst_size, slave_count;
1857 /* NULL all pointers in array to simplify cleanup */
1858 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1860 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1861 * in round robin mode */
1862 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1863 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1864 "Failed to initialize bonded device with slaves");
1866 /* Verify Current Slaves Count /Active Slave Count is */
1867 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1869 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1870 "Number of slaves (%d) is not as expected (%d).",
1871 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1873 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1874 slaves, RTE_MAX_ETHPORTS);
1875 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1876 "Number of active slaves (%d) is not as expected (%d).",
1877 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1879 /* Set 2 slaves eth_devs link status to down */
1880 virtual_ethdev_simulate_link_status_interrupt(
1881 test_params->slave_port_ids[1], 0);
1882 virtual_ethdev_simulate_link_status_interrupt(
1883 test_params->slave_port_ids[3], 0);
1885 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1886 slaves, RTE_MAX_ETHPORTS);
1887 TEST_ASSERT_EQUAL(slave_count,
1888 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1889 "Number of active slaves (%d) is not as expected (%d).\n",
1890 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1894 /* Verify that pkts are not sent on slaves with link status down:
1896 * 1. Generate test burst of traffic
1897 * 2. Transmit burst on bonded eth_dev
1898 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1899 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1902 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1903 burst_size, "generate_test_burst failed");
1905 rte_eth_stats_reset(test_params->bonded_port_id);
1909 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1910 burst_size), burst_size, "rte_eth_tx_burst failed");
1912 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1913 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1914 "Port (%d) opackets stats (%d) not expected (%d) value",
1915 test_params->bonded_port_id, (int)port_stats.opackets,
1918 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1919 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1920 "Port (%d) opackets stats (%d) not expected (%d) value",
1921 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1923 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1924 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1925 "Port (%d) opackets stats (%d) not expected (%d) value",
1926 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1928 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1929 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1930 "Port (%d) opackets stats (%d) not expected (%d) value",
1931 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1933 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1934 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1935 "Port (%d) opackets stats (%d) not expected (%d) value",
1936 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1938 /* Verify that pkts are not sent on slaves with link status down:
1940 * 1. Generate test bursts of traffic
1941 * 2. Add bursts on to virtual eth_devs
1942 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1943 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1944 * 4. Verify stats for bonded eth_dev
1945 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1947 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1948 TEST_ASSERT_EQUAL(generate_test_burst(
1949 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1950 burst_size, "failed to generate packet burst");
1952 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1953 &gen_pkt_burst[i][0], burst_size);
1956 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1957 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1958 burst_size + burst_size,
1959 "rte_eth_rx_burst failed");
1961 /* Verify bonded device rx count */
1962 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1963 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1964 "(%d) port_stats.ipackets not as expected\n",
1965 test_params->bonded_port_id);
1968 for (i = 0; i < MAX_PKT_BURST; i++) {
1969 if (rx_pkt_burst[i] != NULL)
1970 rte_pktmbuf_free(rx_pkt_burst[i]);
1972 if (gen_pkt_burst[1][i] != NULL)
1973 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1975 if (gen_pkt_burst[3][i] != NULL)
1976 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1979 /* Clean up and remove slaves from bonded device */
1980 return remove_slaves_and_stop_bonded_device();
1983 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1985 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1988 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1991 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1993 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1994 char slave_name[RTE_ETH_NAME_MAX_LEN];
1998 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1999 /* Generate slave name / MAC address */
2000 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
2001 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2003 /* Create slave devices with no ISR Support */
2004 if (polling_test_slaves[i] == -1) {
2005 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2006 rte_socket_id(), 0);
2007 TEST_ASSERT(polling_test_slaves[i] >= 0,
2008 "Failed to create virtual virtual ethdev %s\n", slave_name);
2010 /* Configure slave */
2011 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2012 "Failed to configure virtual ethdev %s(%d)", slave_name,
2013 polling_test_slaves[i]);
2016 /* Add slave to bonded device */
2017 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2018 polling_test_slaves[i]),
2019 "Failed to add slave %s(%d) to bonded device %d",
2020 slave_name, polling_test_slaves[i],
2021 test_params->bonded_port_id);
2024 /* Initialize bonded device */
2025 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2026 "Failed to configure bonded device %d",
2027 test_params->bonded_port_id);
2030 /* Register link status change interrupt callback */
2031 rte_eth_dev_callback_register(test_params->bonded_port_id,
2032 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2033 &test_params->bonded_port_id);
2035 /* link status change callback for first slave link up */
2036 test_lsc_interrupt_count = 0;
2038 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2040 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2043 /* no link status change callback for second slave link up */
2044 test_lsc_interrupt_count = 0;
2046 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2048 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2050 /* link status change callback for both slave links down */
2051 test_lsc_interrupt_count = 0;
2053 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2054 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2056 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2058 /* Un-Register link status change interrupt callback */
2059 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2060 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2061 &test_params->bonded_port_id);
2064 /* Clean up and remove slaves from bonded device */
2065 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2067 TEST_ASSERT_SUCCESS(
2068 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2069 polling_test_slaves[i]),
2070 "Failed to remove slave %d from bonded port (%d)",
2071 polling_test_slaves[i], test_params->bonded_port_id);
2074 return remove_slaves_and_stop_bonded_device();
2078 /** Active Backup Mode Tests */
2081 test_activebackup_tx_burst(void)
2083 int i, pktlen, primary_port, burst_size;
2084 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2085 struct rte_eth_stats port_stats;
2087 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2088 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2089 "Failed to initialize bonded device with slaves");
2091 initialize_eth_header(test_params->pkt_eth_hdr,
2092 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2093 ETHER_TYPE_IPv4, 0, 0);
2094 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2096 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2097 dst_addr_0, pktlen);
2099 burst_size = 20 * test_params->bonded_slave_count;
2101 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2102 "Burst size specified is greater than supported.");
2104 /* Generate a burst of packets to transmit */
2105 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2106 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2107 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2108 burst_size, "failed to generate burst correctly");
2110 /* Send burst on bonded port */
2111 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2112 burst_size), burst_size, "tx burst failed");
2114 /* Verify bonded port tx stats */
2115 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2116 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2117 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2118 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2121 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2123 /* Verify slave ports tx stats */
2124 for (i = 0; i < test_params->bonded_slave_count; i++) {
2125 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2126 if (test_params->slave_port_ids[i] == primary_port) {
2127 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2128 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2129 test_params->bonded_port_id,
2130 (unsigned int)port_stats.opackets,
2131 burst_size / test_params->bonded_slave_count);
2133 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2134 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2135 test_params->bonded_port_id,
2136 (unsigned int)port_stats.opackets, 0);
2140 /* Put all slaves down and try and transmit */
2141 for (i = 0; i < test_params->bonded_slave_count; i++) {
2142 virtual_ethdev_simulate_link_status_interrupt(
2143 test_params->slave_port_ids[i], 0);
2146 /* Send burst on bonded port */
2147 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2148 pkts_burst, burst_size), 0, "Sending empty burst failed");
2150 /* Clean up and remove slaves from bonded device */
2151 return remove_slaves_and_stop_bonded_device();
2154 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2157 test_activebackup_rx_burst(void)
2159 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2160 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2162 struct rte_eth_stats port_stats;
2166 int i, j, burst_size = 17;
2168 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2169 BONDING_MODE_ACTIVE_BACKUP, 0,
2170 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2171 "Failed to initialize bonded device with slaves");
2173 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2174 TEST_ASSERT(primary_port >= 0,
2175 "failed to get primary slave for bonded port (%d)",
2176 test_params->bonded_port_id);
2178 for (i = 0; i < test_params->bonded_slave_count; i++) {
2179 /* Generate test bursts of packets to transmit */
2180 TEST_ASSERT_EQUAL(generate_test_burst(
2181 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2182 burst_size, "burst generation failed");
2184 /* Add rx data to slave */
2185 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2186 &gen_pkt_burst[0], burst_size);
2188 /* Call rx burst on bonded device */
2189 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2190 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2191 "rte_eth_rx_burst failed");
2193 if (test_params->slave_port_ids[i] == primary_port) {
2194 /* Verify bonded device rx count */
2195 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2196 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2197 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2198 test_params->bonded_port_id,
2199 (unsigned int)port_stats.ipackets, burst_size);
2201 /* Verify bonded slave devices rx count */
2202 for (j = 0; j < test_params->bonded_slave_count; j++) {
2203 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2205 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2206 "Slave Port (%d) ipackets value (%u) not as "
2207 "expected (%d)", test_params->slave_port_ids[i],
2208 (unsigned int)port_stats.ipackets, burst_size);
2210 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2211 "Slave Port (%d) ipackets value (%u) not as "
2212 "expected (%d)\n", test_params->slave_port_ids[i],
2213 (unsigned int)port_stats.ipackets, 0);
2217 for (j = 0; j < test_params->bonded_slave_count; j++) {
2218 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2219 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2220 "Slave Port (%d) ipackets value (%u) not as expected "
2221 "(%d)", test_params->slave_port_ids[i],
2222 (unsigned int)port_stats.ipackets, 0);
2227 for (i = 0; i < MAX_PKT_BURST; i++) {
2228 if (rx_pkt_burst[i] != NULL) {
2229 rte_pktmbuf_free(rx_pkt_burst[i]);
2230 rx_pkt_burst[i] = NULL;
2234 /* reset bonded device stats */
2235 rte_eth_stats_reset(test_params->bonded_port_id);
2238 /* Clean up and remove slaves from bonded device */
2239 return remove_slaves_and_stop_bonded_device();
2243 test_activebackup_verify_promiscuous_enable_disable(void)
2245 int i, primary_port, promiscuous_en;
2247 /* Initialize bonded device with 4 slaves in round robin mode */
2248 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2249 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2250 "Failed to initialize bonded device with slaves");
2252 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2253 TEST_ASSERT(primary_port >= 0,
2254 "failed to get primary slave for bonded port (%d)",
2255 test_params->bonded_port_id);
2257 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2259 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2260 "Port (%d) promiscuous mode not enabled",
2261 test_params->bonded_port_id);
2263 for (i = 0; i < test_params->bonded_slave_count; i++) {
2264 promiscuous_en = rte_eth_promiscuous_get(
2265 test_params->slave_port_ids[i]);
2266 if (primary_port == test_params->slave_port_ids[i]) {
2267 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2268 "slave port (%d) promiscuous mode not enabled",
2269 test_params->slave_port_ids[i]);
2271 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2272 "slave port (%d) promiscuous mode enabled",
2273 test_params->slave_port_ids[i]);
2278 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2280 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2281 "Port (%d) promiscuous mode not disabled\n",
2282 test_params->bonded_port_id);
2284 for (i = 0; i < test_params->bonded_slave_count; i++) {
2285 promiscuous_en = rte_eth_promiscuous_get(
2286 test_params->slave_port_ids[i]);
2287 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2288 "slave port (%d) promiscuous mode not disabled\n",
2289 test_params->slave_port_ids[i]);
2292 /* Clean up and remove slaves from bonded device */
2293 return remove_slaves_and_stop_bonded_device();
2297 test_activebackup_verify_mac_assignment(void)
2299 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2301 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2302 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2304 /* Initialize bonded device with 2 slaves in active backup mode */
2305 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2306 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2307 "Failed to initialize bonded device with slaves");
2309 /* Verify that bonded MACs is that of first slave and that the other slave
2310 * MAC hasn't been changed */
2311 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2312 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2313 sizeof(read_mac_addr)),
2314 "bonded port (%d) mac address not set to that of primary port",
2315 test_params->bonded_port_id);
2317 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2318 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2319 sizeof(read_mac_addr)),
2320 "slave port (%d) mac address not set to that of primary port",
2321 test_params->slave_port_ids[0]);
2323 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2324 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2325 sizeof(read_mac_addr)),
2326 "slave port (%d) mac address not as expected",
2327 test_params->slave_port_ids[1]);
2329 /* change primary and verify that MAC addresses haven't changed */
2330 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2331 test_params->slave_port_ids[1]), 0,
2332 "Failed to set bonded port (%d) primary port to (%d)",
2333 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2335 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2336 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2337 sizeof(read_mac_addr)),
2338 "bonded port (%d) mac address not set to that of primary port",
2339 test_params->bonded_port_id);
2341 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2342 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2343 sizeof(read_mac_addr)),
2344 "slave port (%d) mac address not set to that of primary port",
2345 test_params->slave_port_ids[0]);
2347 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2348 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2349 sizeof(read_mac_addr)),
2350 "slave port (%d) mac address not as expected",
2351 test_params->slave_port_ids[1]);
2353 /* stop / start bonded device and verify that primary MAC address is
2354 * propagated to bonded device and slaves */
2356 rte_eth_dev_stop(test_params->bonded_port_id);
2358 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2359 "Failed to start device");
2361 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2362 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2363 sizeof(read_mac_addr)),
2364 "bonded port (%d) mac address not set to that of primary port",
2365 test_params->bonded_port_id);
2367 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2368 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2369 sizeof(read_mac_addr)),
2370 "slave port (%d) mac address not as expected",
2371 test_params->slave_port_ids[0]);
2373 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2374 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2375 sizeof(read_mac_addr)),
2376 "slave port (%d) mac address not set to that of primary port",
2377 test_params->slave_port_ids[1]);
2379 /* Set explicit MAC address */
2380 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2381 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2382 "failed to set MAC address");
2384 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2385 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2386 sizeof(read_mac_addr)),
2387 "bonded port (%d) mac address not set to that of bonded port",
2388 test_params->bonded_port_id);
2390 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2391 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2392 sizeof(read_mac_addr)),
2393 "slave port (%d) mac address not as expected",
2394 test_params->slave_port_ids[0]);
2396 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2397 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2398 sizeof(read_mac_addr)),
2399 "slave port (%d) mac address not set to that of bonded port",
2400 test_params->slave_port_ids[1]);
2402 /* Clean up and remove slaves from bonded device */
2403 return remove_slaves_and_stop_bonded_device();
2407 test_activebackup_verify_slave_link_status_change_failover(void)
2409 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2410 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2411 struct rte_eth_stats port_stats;
2413 uint8_t slaves[RTE_MAX_ETHPORTS];
2415 int i, j, burst_size, slave_count, primary_port;
2419 memset(pkt_burst, 0, sizeof(pkt_burst));
2421 /* Generate packet burst for testing */
2422 TEST_ASSERT_EQUAL(generate_test_burst(
2423 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2424 "generate_test_burst failed");
2426 /* Initialize bonded device with 4 slaves in round robin mode */
2427 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2428 BONDING_MODE_ACTIVE_BACKUP, 0,
2429 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2430 "Failed to initialize bonded device with slaves");
2432 /* Verify Current Slaves Count /Active Slave Count is */
2433 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2435 TEST_ASSERT_EQUAL(slave_count, 4,
2436 "Number of slaves (%d) is not as expected (%d).",
2439 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2440 slaves, RTE_MAX_ETHPORTS);
2441 TEST_ASSERT_EQUAL(slave_count, 4,
2442 "Number of active slaves (%d) is not as expected (%d).",
2445 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2446 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2447 "Primary port not as expected");
2449 /* Bring 2 slaves down and verify active slave count */
2450 virtual_ethdev_simulate_link_status_interrupt(
2451 test_params->slave_port_ids[1], 0);
2452 virtual_ethdev_simulate_link_status_interrupt(
2453 test_params->slave_port_ids[3], 0);
2455 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2456 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2457 "Number of active slaves (%d) is not as expected (%d).",
2460 virtual_ethdev_simulate_link_status_interrupt(
2461 test_params->slave_port_ids[1], 1);
2462 virtual_ethdev_simulate_link_status_interrupt(
2463 test_params->slave_port_ids[3], 1);
2466 /* Bring primary port down, verify that active slave count is 3 and primary
2468 virtual_ethdev_simulate_link_status_interrupt(
2469 test_params->slave_port_ids[0], 0);
2471 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2472 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2474 "Number of active slaves (%d) is not as expected (%d).",
2477 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2478 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2479 "Primary port not as expected");
2481 /* Verify that pkts are sent on new primary slave */
2483 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2484 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2485 burst_size), burst_size, "rte_eth_tx_burst failed");
2487 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2488 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2489 "(%d) port_stats.opackets not as expected",
2490 test_params->slave_port_ids[2]);
2492 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2493 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2494 "(%d) port_stats.opackets not as expected\n",
2495 test_params->slave_port_ids[0]);
2497 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2498 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2499 "(%d) port_stats.opackets not as expected\n",
2500 test_params->slave_port_ids[1]);
2502 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2503 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2504 "(%d) port_stats.opackets not as expected\n",
2505 test_params->slave_port_ids[3]);
2507 /* Generate packet burst for testing */
2509 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2510 TEST_ASSERT_EQUAL(generate_test_burst(
2511 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2512 "generate_test_burst failed");
2514 virtual_ethdev_add_mbufs_to_rx_queue(
2515 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2518 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2519 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2520 burst_size, "rte_eth_rx_burst\n");
2522 /* Verify bonded device rx count */
2523 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2524 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2525 "(%d) port_stats.ipackets not as expected",
2526 test_params->bonded_port_id);
2528 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2529 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2530 "(%d) port_stats.opackets not as expected",
2531 test_params->slave_port_ids[2]);
2533 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2534 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2535 "(%d) port_stats.opackets not as expected",
2536 test_params->slave_port_ids[0]);
2538 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2539 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2540 "(%d) port_stats.opackets not as expected",
2541 test_params->slave_port_ids[1]);
2543 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2544 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2545 "(%d) port_stats.opackets not as expected",
2546 test_params->slave_port_ids[3]);
2549 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2550 for (j = 0; j < MAX_PKT_BURST; j++) {
2551 if (pkt_burst[i][j] != NULL) {
2552 rte_pktmbuf_free(pkt_burst[i][j]);
2553 pkt_burst[i][j] = NULL;
2558 /* Clean up and remove slaves from bonded device */
2559 return remove_slaves_and_stop_bonded_device();
2562 /** Balance Mode Tests */
2565 test_balance_xmit_policy_configuration(void)
2567 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2568 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2569 "Failed to initialize_bonded_device_with_slaves.");
2571 /* Invalid port id */
2572 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2573 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2574 "Expected call to failed as invalid port specified.");
2576 /* Set xmit policy on non bonded device */
2577 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2578 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2579 "Expected call to failed as invalid port specified.");
2582 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2583 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2584 "Failed to set balance xmit policy.");
2586 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2587 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2590 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2591 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2592 "Failed to set balance xmit policy.");
2594 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2595 BALANCE_XMIT_POLICY_LAYER23,
2596 "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_LAYER34),
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_LAYER34,
2605 "balance xmit policy not as expected.");
2607 /* Invalid port id */
2608 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2609 "Expected call to failed as invalid port specified.");
2611 /* Clean up and remove slaves from bonded device */
2612 return remove_slaves_and_stop_bonded_device();
2615 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2618 test_balance_l2_tx_burst(void)
2620 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2621 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2625 struct rte_eth_stats port_stats;
2627 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2628 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2629 "Failed to initialize_bonded_device_with_slaves.");
2631 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2632 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2633 "Failed to set balance xmit policy.");
2635 initialize_eth_header(test_params->pkt_eth_hdr,
2636 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2637 ETHER_TYPE_IPv4, 0, 0);
2638 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2640 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2641 dst_addr_0, pktlen);
2643 /* Generate a burst 1 of packets to transmit */
2644 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2645 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2646 test_params->pkt_udp_hdr, burst_size[0],
2647 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2648 "failed to generate packet burst");
2650 initialize_eth_header(test_params->pkt_eth_hdr,
2651 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2652 ETHER_TYPE_IPv4, 0, 0);
2654 /* Generate a burst 2 of packets to transmit */
2655 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2656 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2657 test_params->pkt_udp_hdr, burst_size[1],
2658 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2659 "failed to generate packet burst");
2661 /* Send burst 1 on bonded port */
2662 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2663 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2664 &pkts_burst[i][0], burst_size[i]),
2665 burst_size[i], "Failed to transmit packet burst");
2668 /* Verify bonded port tx stats */
2669 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2670 TEST_ASSERT_EQUAL(port_stats.opackets,
2671 (uint64_t)(burst_size[0] + burst_size[1]),
2672 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2673 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2674 burst_size[0] + burst_size[1]);
2677 /* Verify slave ports tx stats */
2678 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2679 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2680 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2681 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2684 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2685 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2686 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2687 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2690 /* Put all slaves down and try and transmit */
2691 for (i = 0; i < test_params->bonded_slave_count; i++) {
2693 virtual_ethdev_simulate_link_status_interrupt(
2694 test_params->slave_port_ids[i], 0);
2697 /* Send burst on bonded port */
2698 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2699 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2700 0, "Expected zero packet");
2702 /* Clean up and remove slaves from bonded device */
2703 return remove_slaves_and_stop_bonded_device();
2707 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2708 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2710 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2712 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2713 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2715 struct rte_eth_stats port_stats;
2717 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2718 BONDING_MODE_BALANCE, 0, 2, 1),
2719 "Failed to initialize_bonded_device_with_slaves.");
2721 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2722 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2723 "Failed to set balance xmit policy.");
2728 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2729 "Burst size specified is greater than supported.");
2731 /* Generate test bursts of packets to transmit */
2732 TEST_ASSERT_EQUAL(generate_test_burst(
2733 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2734 burst_size_1, "failed to generate packet burst");
2736 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2737 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2738 "failed to generate packet burst");
2740 /* Send burst 1 on bonded port */
2741 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2743 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2745 /* Send burst 2 on bonded port */
2746 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2748 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2750 /* Verify bonded port tx stats */
2751 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2752 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2753 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2754 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2757 /* Verify slave ports tx stats */
2758 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2759 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2760 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2761 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2764 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2765 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2766 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2767 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2770 /* Put all slaves down and try and transmit */
2771 for (i = 0; i < test_params->bonded_slave_count; i++) {
2773 virtual_ethdev_simulate_link_status_interrupt(
2774 test_params->slave_port_ids[i], 0);
2777 /* Send burst on bonded port */
2778 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2779 test_params->bonded_port_id, 0, pkts_burst_1,
2780 burst_size_1), 0, "Expected zero packet");
2783 /* Clean up and remove slaves from bonded device */
2784 return remove_slaves_and_stop_bonded_device();
2788 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2790 return balance_l23_tx_burst(0, 1, 1, 0);
2794 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2796 return balance_l23_tx_burst(1, 1, 0, 1);
2800 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2802 return balance_l23_tx_burst(0, 0, 0, 1);
2806 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2808 return balance_l23_tx_burst(1, 0, 0, 1);
2812 test_balance_l23_tx_burst_toggle_mac_addr(void)
2814 return balance_l23_tx_burst(0, 0, 1, 0);
2818 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2819 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2820 uint8_t toggle_udp_port)
2822 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2824 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2825 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2827 struct rte_eth_stats port_stats;
2829 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2830 BONDING_MODE_BALANCE, 0, 2, 1),
2831 "Failed to initialize_bonded_device_with_slaves.");
2833 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2834 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2835 "Failed to set balance xmit policy.");
2840 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2841 "Burst size specified is greater than supported.");
2843 /* Generate test bursts of packets to transmit */
2844 TEST_ASSERT_EQUAL(generate_test_burst(
2845 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2846 burst_size_1, "failed to generate burst");
2848 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2849 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2850 toggle_udp_port), burst_size_2, "failed to generate burst");
2852 /* Send burst 1 on bonded port */
2853 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2855 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2857 /* Send burst 2 on bonded port */
2858 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2860 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2863 /* Verify bonded port tx stats */
2864 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2865 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2866 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2867 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2870 /* Verify slave ports tx stats */
2871 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2872 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2873 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2874 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2877 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2878 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2879 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2880 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2883 /* Put all slaves down and try and transmit */
2884 for (i = 0; i < test_params->bonded_slave_count; i++) {
2886 virtual_ethdev_simulate_link_status_interrupt(
2887 test_params->slave_port_ids[i], 0);
2890 /* Send burst on bonded port */
2891 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2892 test_params->bonded_port_id, 0, pkts_burst_1,
2893 burst_size_1), 0, "Expected zero packet");
2895 /* Clean up and remove slaves from bonded device */
2896 return remove_slaves_and_stop_bonded_device();
2900 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2902 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2906 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2908 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2912 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2914 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2918 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2920 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2924 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2926 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2930 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2932 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2935 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2936 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2937 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2938 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2939 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2942 test_balance_tx_burst_slave_tx_fail(void)
2944 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2945 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2947 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2949 struct rte_eth_stats port_stats;
2951 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2953 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2954 BONDING_MODE_BALANCE, 0,
2955 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2956 "Failed to intialise bonded device");
2958 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2959 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2960 "Failed to set balance xmit policy.");
2963 /* Generate test bursts for transmission */
2964 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2965 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2966 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2967 "Failed to generate test packet burst 1");
2969 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2970 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2972 /* copy mbuf referneces for expected transmission failures */
2973 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2974 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2976 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2977 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2978 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2979 "Failed to generate test packet burst 2");
2982 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2983 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2984 virtual_ethdev_tx_burst_fn_set_success(
2985 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2988 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2989 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2990 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2993 /* Transmit burst 1 */
2994 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2995 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2997 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2998 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2999 "Transmitted (%d) packets, expected to transmit (%d) packets",
3000 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3001 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3003 /* Verify that failed packet are expected failed packets */
3004 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3005 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3006 "expected mbuf (%d) pointer %p not expected pointer %p",
3007 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3010 /* Transmit burst 2 */
3011 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3012 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3014 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3015 "Transmitted (%d) packets, expected to transmit (%d) packets",
3016 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3019 /* Verify bonded port tx stats */
3020 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3022 TEST_ASSERT_EQUAL(port_stats.opackets,
3023 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3024 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3025 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3026 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3027 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3028 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3029 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3030 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3032 /* Verify slave ports tx stats */
3034 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3036 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3037 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3038 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3039 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3040 test_params->slave_port_ids[0],
3041 (unsigned int)port_stats.opackets,
3042 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3043 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3048 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3050 TEST_ASSERT_EQUAL(port_stats.opackets,
3051 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3052 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3053 test_params->slave_port_ids[1],
3054 (unsigned int)port_stats.opackets,
3055 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3057 /* Verify that all mbufs have a ref value of zero */
3058 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3059 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3060 "mbufs refcnts not as expected");
3062 free_mbufs(&pkts_burst_1[tx_count_1],
3063 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3065 /* Clean up and remove slaves from bonded device */
3066 return remove_slaves_and_stop_bonded_device();
3069 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3072 test_balance_rx_burst(void)
3074 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3076 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3077 struct rte_eth_stats port_stats;
3079 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3082 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3084 /* Initialize bonded device with 4 slaves in round robin mode */
3085 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3086 BONDING_MODE_BALANCE, 0, 3, 1),
3087 "Failed to intialise bonded device");
3089 /* Generate test bursts of packets to transmit */
3090 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3091 TEST_ASSERT_EQUAL(generate_test_burst(
3092 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3093 0, 0), burst_size[i],
3094 "failed to generate packet burst");
3097 /* Add rx data to slaves */
3098 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3099 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3100 &gen_pkt_burst[i][0], burst_size[i]);
3103 /* Call rx burst on bonded device */
3104 /* Send burst on bonded port */
3105 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3106 rx_pkt_burst, MAX_PKT_BURST),
3107 burst_size[0] + burst_size[1] + burst_size[2],
3108 "balance rx burst failed\n");
3110 /* Verify bonded device rx count */
3111 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3112 TEST_ASSERT_EQUAL(port_stats.ipackets,
3113 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3114 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3115 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3116 burst_size[0] + burst_size[1] + burst_size[2]);
3119 /* Verify bonded slave devices rx counts */
3120 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3121 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3122 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3123 test_params->slave_port_ids[0],
3124 (unsigned int)port_stats.ipackets, burst_size[0]);
3126 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3127 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3128 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3129 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3132 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3133 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3134 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3135 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3138 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3139 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3140 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3141 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3145 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3146 for (j = 0; j < MAX_PKT_BURST; j++) {
3147 if (gen_pkt_burst[i][j] != NULL) {
3148 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3149 gen_pkt_burst[i][j] = NULL;
3154 /* Clean up and remove slaves from bonded device */
3155 return remove_slaves_and_stop_bonded_device();
3159 test_balance_verify_promiscuous_enable_disable(void)
3163 /* Initialize bonded device with 4 slaves in round robin mode */
3164 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3165 BONDING_MODE_BALANCE, 0, 4, 1),
3166 "Failed to intialise bonded device");
3168 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3170 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3171 "Port (%d) promiscuous mode not enabled",
3172 test_params->bonded_port_id);
3174 for (i = 0; i < test_params->bonded_slave_count; i++) {
3175 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3176 test_params->slave_port_ids[i]), 1,
3177 "Port (%d) promiscuous mode not enabled",
3178 test_params->slave_port_ids[i]);
3181 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3183 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3184 "Port (%d) promiscuous mode not disabled",
3185 test_params->bonded_port_id);
3187 for (i = 0; i < test_params->bonded_slave_count; i++) {
3188 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3189 test_params->slave_port_ids[i]), 0,
3190 "Port (%d) promiscuous mode not disabled",
3191 test_params->slave_port_ids[i]);
3194 /* Clean up and remove slaves from bonded device */
3195 return remove_slaves_and_stop_bonded_device();
3199 test_balance_verify_mac_assignment(void)
3201 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3203 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3204 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3206 /* Initialize bonded device with 2 slaves in active backup mode */
3207 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3208 BONDING_MODE_BALANCE, 0, 2, 1),
3209 "Failed to intialise bonded device");
3211 /* Verify that bonded MACs is that of first slave and that the other slave
3212 * MAC hasn't been changed */
3213 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3214 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3215 sizeof(read_mac_addr)),
3216 "bonded port (%d) mac address not set to that of primary port",
3217 test_params->bonded_port_id);
3219 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3220 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3221 sizeof(read_mac_addr)),
3222 "slave port (%d) mac address not set to that of primary port",
3223 test_params->slave_port_ids[0]);
3225 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3226 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3227 sizeof(read_mac_addr)),
3228 "slave port (%d) mac address not set to that of primary port",
3229 test_params->slave_port_ids[1]);
3231 /* change primary and verify that MAC addresses haven't changed */
3232 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3233 test_params->slave_port_ids[1]),
3234 "Failed to set bonded port (%d) primary port to (%d)\n",
3235 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3237 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3238 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3239 sizeof(read_mac_addr)),
3240 "bonded port (%d) mac address not set to that of primary port",
3241 test_params->bonded_port_id);
3243 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3244 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3245 sizeof(read_mac_addr)),
3246 "slave port (%d) mac address not set to that of primary port",
3247 test_params->slave_port_ids[0]);
3249 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3250 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3251 sizeof(read_mac_addr)),
3252 "slave port (%d) mac address not set to that of primary port",
3253 test_params->slave_port_ids[1]);
3255 /* stop / start bonded device and verify that primary MAC address is
3256 * propagated to bonded device and slaves */
3258 rte_eth_dev_stop(test_params->bonded_port_id);
3260 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3261 "Failed to start bonded device");
3263 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3264 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3265 sizeof(read_mac_addr)),
3266 "bonded port (%d) mac address not set to that of primary port",
3267 test_params->bonded_port_id);
3269 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3270 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3271 sizeof(read_mac_addr)),
3272 "slave port (%d) mac address not set to that of primary port",
3273 test_params->slave_port_ids[0]);
3275 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3276 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3277 sizeof(read_mac_addr)),
3278 "slave port (%d) mac address not set to that of primary port",
3279 test_params->slave_port_ids[1]);
3281 /* Set explicit MAC address */
3282 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3283 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3284 "failed to set MAC");
3286 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3287 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3288 sizeof(read_mac_addr)),
3289 "bonded port (%d) mac address not set to that of bonded port",
3290 test_params->bonded_port_id);
3292 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3293 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3294 sizeof(read_mac_addr)),
3295 "slave port (%d) mac address not as expected\n",
3296 test_params->slave_port_ids[0]);
3298 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3299 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3300 sizeof(read_mac_addr)),
3301 "slave port (%d) mac address not set to that of bonded port",
3302 test_params->slave_port_ids[1]);
3304 /* Clean up and remove slaves from bonded device */
3305 return remove_slaves_and_stop_bonded_device();
3308 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3311 test_balance_verify_slave_link_status_change_behaviour(void)
3313 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3314 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3315 struct rte_eth_stats port_stats;
3317 uint8_t slaves[RTE_MAX_ETHPORTS];
3319 int i, j, burst_size, slave_count;
3321 memset(pkt_burst, 0, sizeof(pkt_burst));
3323 /* Initialize bonded device with 4 slaves in round robin mode */
3324 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3325 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3326 "Failed to intialise bonded device");
3328 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3329 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3330 "Failed to set balance xmit policy.");
3333 /* Verify Current Slaves Count /Active Slave Count is */
3334 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3336 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3337 "Number of slaves (%d) is not as expected (%d).",
3338 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3340 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3341 slaves, RTE_MAX_ETHPORTS);
3342 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3343 "Number of active slaves (%d) is not as expected (%d).",
3344 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3346 /* Set 2 slaves link status to down */
3347 virtual_ethdev_simulate_link_status_interrupt(
3348 test_params->slave_port_ids[1], 0);
3349 virtual_ethdev_simulate_link_status_interrupt(
3350 test_params->slave_port_ids[3], 0);
3352 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3353 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3354 "Number of active slaves (%d) is not as expected (%d).",
3357 /* Send to sets of packet burst and verify that they are balanced across
3361 TEST_ASSERT_EQUAL(generate_test_burst(
3362 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3363 "generate_test_burst failed");
3365 TEST_ASSERT_EQUAL(generate_test_burst(
3366 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3367 "generate_test_burst failed");
3369 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3370 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3371 burst_size, "rte_eth_tx_burst failed");
3373 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3374 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3375 burst_size, "rte_eth_tx_burst failed");
3378 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3379 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3380 "(%d) port_stats.opackets (%d) not as expected (%d).",
3381 test_params->bonded_port_id, (int)port_stats.opackets,
3382 burst_size + burst_size);
3384 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3385 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3386 "(%d) port_stats.opackets (%d) not as expected (%d).",
3387 test_params->slave_port_ids[0], (int)port_stats.opackets,
3390 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3391 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3392 "(%d) port_stats.opackets (%d) not as expected (%d).",
3393 test_params->slave_port_ids[2], (int)port_stats.opackets,
3396 /* verify that all packets get send on primary slave when no other slaves
3398 virtual_ethdev_simulate_link_status_interrupt(
3399 test_params->slave_port_ids[2], 0);
3401 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3402 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3403 "Number of active slaves (%d) is not as expected (%d).",
3406 TEST_ASSERT_EQUAL(generate_test_burst(
3407 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3408 "generate_test_burst failed");
3410 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3411 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3412 burst_size, "rte_eth_tx_burst failed");
3414 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3415 TEST_ASSERT_EQUAL(port_stats.opackets,
3416 (uint64_t)(burst_size + burst_size + burst_size),
3417 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3418 test_params->bonded_port_id, (int)port_stats.opackets,
3419 burst_size + burst_size + burst_size);
3421 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3422 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3423 "(%d) port_stats.opackets (%d) not as expected (%d).",
3424 test_params->slave_port_ids[0], (int)port_stats.opackets,
3425 burst_size + burst_size);
3427 virtual_ethdev_simulate_link_status_interrupt(
3428 test_params->slave_port_ids[0], 0);
3429 virtual_ethdev_simulate_link_status_interrupt(
3430 test_params->slave_port_ids[1], 1);
3431 virtual_ethdev_simulate_link_status_interrupt(
3432 test_params->slave_port_ids[2], 1);
3433 virtual_ethdev_simulate_link_status_interrupt(
3434 test_params->slave_port_ids[3], 1);
3436 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3437 TEST_ASSERT_EQUAL(generate_test_burst(
3438 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3439 "Failed to generate packet burst");
3441 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3442 &pkt_burst[i][0], burst_size);
3445 /* Verify that pkts are not received on slaves with link status down */
3447 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3450 /* Verify bonded device rx count */
3451 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3452 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3453 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3454 test_params->bonded_port_id, (int)port_stats.ipackets,
3457 /* free mbufs allocate for rx testing */
3458 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3459 for (j = 0; j < MAX_PKT_BURST; j++) {
3460 if (pkt_burst[i][j] != NULL) {
3461 rte_pktmbuf_free(pkt_burst[i][j]);
3462 pkt_burst[i][j] = NULL;
3467 /* Clean up and remove slaves from bonded device */
3468 return remove_slaves_and_stop_bonded_device();
3472 test_broadcast_tx_burst(void)
3474 int i, pktlen, burst_size;
3475 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3477 struct rte_eth_stats port_stats;
3479 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3480 BONDING_MODE_BROADCAST, 0, 2, 1),
3481 "Failed to intialise bonded device");
3483 initialize_eth_header(test_params->pkt_eth_hdr,
3484 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3485 ETHER_TYPE_IPv4, 0, 0);
3487 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3489 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3490 dst_addr_0, pktlen);
3492 burst_size = 20 * test_params->bonded_slave_count;
3494 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3495 "Burst size specified is greater than supported.");
3497 /* Generate a burst of packets to transmit */
3498 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3499 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3500 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3501 1), burst_size, "Failed to generate packet burst");
3503 /* Send burst on bonded port */
3504 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3505 pkts_burst, burst_size), burst_size,
3506 "Bonded Port (%d) rx burst failed, packets transmitted value "
3507 "not as expected (%d)",
3508 test_params->bonded_port_id, burst_size);
3510 /* Verify bonded port tx stats */
3511 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3512 TEST_ASSERT_EQUAL(port_stats.opackets,
3513 (uint64_t)burst_size * test_params->bonded_slave_count,
3514 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3515 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3518 /* Verify slave ports tx stats */
3519 for (i = 0; i < test_params->bonded_slave_count; i++) {
3520 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3521 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3522 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3523 test_params->bonded_port_id,
3524 (unsigned int)port_stats.opackets, burst_size);
3527 /* Put all slaves down and try and transmit */
3528 for (i = 0; i < test_params->bonded_slave_count; i++) {
3530 virtual_ethdev_simulate_link_status_interrupt(
3531 test_params->slave_port_ids[i], 0);
3534 /* Send burst on bonded port */
3535 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3536 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3537 "transmitted an unexpected number of packets");
3539 /* Clean up and remove slaves from bonded device */
3540 return remove_slaves_and_stop_bonded_device();
3544 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3545 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3546 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3547 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3550 test_broadcast_tx_burst_slave_tx_fail(void)
3552 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3553 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3555 struct rte_eth_stats port_stats;
3559 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3560 BONDING_MODE_BROADCAST, 0,
3561 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3562 "Failed to intialise bonded device");
3564 /* Generate test bursts for transmission */
3565 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3566 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3567 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3568 "Failed to generate test packet burst");
3570 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3571 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3572 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3575 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3576 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3577 virtual_ethdev_tx_burst_fn_set_success(
3578 test_params->slave_port_ids[0],
3580 virtual_ethdev_tx_burst_fn_set_success(
3581 test_params->slave_port_ids[1],
3583 virtual_ethdev_tx_burst_fn_set_success(
3584 test_params->slave_port_ids[2],
3587 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3588 test_params->slave_port_ids[0],
3589 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3591 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3592 test_params->slave_port_ids[1],
3593 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3595 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3596 test_params->slave_port_ids[2],
3597 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3599 /* Transmit burst */
3600 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3601 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3603 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3604 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3605 "Transmitted (%d) packets, expected to transmit (%d) packets",
3606 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3607 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3609 /* Verify that failed packet are expected failed packets */
3610 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3611 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3612 "expected mbuf (%d) pointer %p not expected pointer %p",
3613 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3616 /* Verify slave ports tx stats */
3618 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3620 TEST_ASSERT_EQUAL(port_stats.opackets,
3621 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3622 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3623 "Port (%d) opackets value (%u) not as expected (%d)",
3624 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3625 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3626 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3629 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3631 TEST_ASSERT_EQUAL(port_stats.opackets,
3632 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3633 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3634 "Port (%d) opackets value (%u) not as expected (%d)",
3635 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3636 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3637 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3639 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3641 TEST_ASSERT_EQUAL(port_stats.opackets,
3642 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3643 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3644 "Port (%d) opackets value (%u) not as expected (%d)",
3645 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3646 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3647 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3650 /* Verify that all mbufs who transmission failed have a ref value of one */
3651 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3652 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3653 "mbufs refcnts not as expected");
3655 free_mbufs(&pkts_burst[tx_count],
3656 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3658 /* Clean up and remove slaves from bonded device */
3659 return remove_slaves_and_stop_bonded_device();
3662 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3665 test_broadcast_rx_burst(void)
3667 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3669 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3670 struct rte_eth_stats port_stats;
3672 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3675 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3677 /* Initialize bonded device with 4 slaves in round robin mode */
3678 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3679 BONDING_MODE_BROADCAST, 0, 3, 1),
3680 "Failed to intialise bonded device");
3682 /* Generate test bursts of packets to transmit */
3683 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3684 TEST_ASSERT_EQUAL(generate_test_burst(
3685 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3686 burst_size[i], "failed to generate packet burst");
3689 /* Add rx data to slave 0 */
3690 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3691 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3692 &gen_pkt_burst[i][0], burst_size[i]);
3696 /* Call rx burst on bonded device */
3697 /* Send burst on bonded port */
3698 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3699 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3700 burst_size[0] + burst_size[1] + burst_size[2],
3703 /* Verify bonded device rx count */
3704 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3705 TEST_ASSERT_EQUAL(port_stats.ipackets,
3706 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3707 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3708 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3709 burst_size[0] + burst_size[1] + burst_size[2]);
3712 /* Verify bonded slave devices rx counts */
3713 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3714 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3715 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3716 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3719 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3720 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3721 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3722 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3725 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3726 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3727 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3728 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3731 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3732 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3733 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3734 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3737 /* free mbufs allocate for rx testing */
3738 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3739 for (j = 0; j < MAX_PKT_BURST; j++) {
3740 if (gen_pkt_burst[i][j] != NULL) {
3741 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3742 gen_pkt_burst[i][j] = NULL;
3747 /* Clean up and remove slaves from bonded device */
3748 return remove_slaves_and_stop_bonded_device();
3752 test_broadcast_verify_promiscuous_enable_disable(void)
3756 /* Initialize bonded device with 4 slaves in round robin mode */
3757 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3758 BONDING_MODE_BROADCAST, 0, 4, 1),
3759 "Failed to intialise bonded device");
3761 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3764 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3765 "Port (%d) promiscuous mode not enabled",
3766 test_params->bonded_port_id);
3768 for (i = 0; i < test_params->bonded_slave_count; i++) {
3769 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3770 test_params->slave_port_ids[i]), 1,
3771 "Port (%d) promiscuous mode not enabled",
3772 test_params->slave_port_ids[i]);
3775 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3777 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3778 "Port (%d) promiscuous mode not disabled",
3779 test_params->bonded_port_id);
3781 for (i = 0; i < test_params->bonded_slave_count; i++) {
3782 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3783 test_params->slave_port_ids[i]), 0,
3784 "Port (%d) promiscuous mode not disabled",
3785 test_params->slave_port_ids[i]);
3788 /* Clean up and remove slaves from bonded device */
3789 return remove_slaves_and_stop_bonded_device();
3793 test_broadcast_verify_mac_assignment(void)
3795 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3799 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3800 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3802 /* Initialize bonded device with 4 slaves in round robin mode */
3803 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3804 BONDING_MODE_BROADCAST, 0, 4, 1),
3805 "Failed to intialise bonded device");
3807 /* Verify that all MACs are the same as first slave added to bonded
3809 for (i = 0; i < test_params->bonded_slave_count; i++) {
3810 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3811 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3812 sizeof(read_mac_addr)),
3813 "slave port (%d) mac address not set to that of primary port",
3814 test_params->slave_port_ids[i]);
3817 /* change primary and verify that MAC addresses haven't changed */
3818 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3819 test_params->slave_port_ids[2]),
3820 "Failed to set bonded port (%d) primary port to (%d)",
3821 test_params->bonded_port_id, test_params->slave_port_ids[i]);
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 has changed to that of primary "
3828 "port without stop/start toggle of bonded device",
3829 test_params->slave_port_ids[i]);
3832 /* stop / start bonded device and verify that primary MAC address is
3833 * propagated to bonded device and slaves */
3835 rte_eth_dev_stop(test_params->bonded_port_id);
3837 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3838 "Failed to start bonded device");
3840 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3841 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3842 sizeof(read_mac_addr)),
3843 "bonded port (%d) mac address not set to that of new primary port",
3844 test_params->slave_port_ids[i]);
3846 for (i = 0; i < test_params->bonded_slave_count; i++) {
3847 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3848 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3849 sizeof(read_mac_addr)),
3850 "slave port (%d) mac address not set to that of new primary "
3851 "port", test_params->slave_port_ids[i]);
3854 /* Set explicit MAC address */
3855 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3856 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3857 "Failed to set MAC address");
3859 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3860 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3861 sizeof(read_mac_addr)),
3862 "bonded port (%d) mac address not set to that of new primary port",
3863 test_params->slave_port_ids[i]);
3866 for (i = 0; i < test_params->bonded_slave_count; i++) {
3867 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3868 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3869 sizeof(read_mac_addr)),
3870 "slave port (%d) mac address not set to that of new primary "
3871 "port", test_params->slave_port_ids[i]);
3874 /* Clean up and remove slaves from bonded device */
3875 return remove_slaves_and_stop_bonded_device();
3878 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3880 test_broadcast_verify_slave_link_status_change_behaviour(void)
3882 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3883 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3884 struct rte_eth_stats port_stats;
3886 uint8_t slaves[RTE_MAX_ETHPORTS];
3888 int i, j, burst_size, slave_count;
3890 memset(pkt_burst, 0, sizeof(pkt_burst));
3892 /* Initialize bonded device with 4 slaves in round robin mode */
3893 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3894 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3895 1), "Failed to intialise bonded device");
3897 /* Verify Current Slaves Count /Active Slave Count is */
3898 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3900 TEST_ASSERT_EQUAL(slave_count, 4,
3901 "Number of slaves (%d) is not as expected (%d).",
3904 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3905 slaves, RTE_MAX_ETHPORTS);
3906 TEST_ASSERT_EQUAL(slave_count, 4,
3907 "Number of active slaves (%d) is not as expected (%d).",
3910 /* Set 2 slaves link status to down */
3911 virtual_ethdev_simulate_link_status_interrupt(
3912 test_params->slave_port_ids[1], 0);
3913 virtual_ethdev_simulate_link_status_interrupt(
3914 test_params->slave_port_ids[3], 0);
3916 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3917 slaves, RTE_MAX_ETHPORTS);
3918 TEST_ASSERT_EQUAL(slave_count, 2,
3919 "Number of active slaves (%d) is not as expected (%d).",
3922 for (i = 0; i < test_params->bonded_slave_count; i++)
3923 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3925 /* Verify that pkts are not sent on slaves with link status down */
3928 TEST_ASSERT_EQUAL(generate_test_burst(
3929 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3930 "generate_test_burst failed");
3932 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3933 &pkt_burst[0][0], burst_size), burst_size,
3934 "rte_eth_tx_burst failed\n");
3936 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3937 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3938 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3939 test_params->bonded_port_id, (int)port_stats.opackets,
3940 burst_size * slave_count);
3942 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3943 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3944 "(%d) port_stats.opackets not as expected",
3945 test_params->slave_port_ids[0]);
3947 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3948 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3949 "(%d) port_stats.opackets not as expected",
3950 test_params->slave_port_ids[1]);
3952 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3953 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3954 "(%d) port_stats.opackets not as expected",
3955 test_params->slave_port_ids[2]);
3958 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3959 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3960 "(%d) port_stats.opackets not as expected",
3961 test_params->slave_port_ids[3]);
3964 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3965 TEST_ASSERT_EQUAL(generate_test_burst(
3966 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3967 burst_size, "failed to generate packet burst");
3969 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3970 &pkt_burst[i][0], burst_size);
3973 /* Verify that pkts are not received on slaves with link status down */
3974 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3975 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3976 burst_size + burst_size, "rte_eth_rx_burst failed");
3979 /* Verify bonded device rx count */
3980 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3981 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3982 "(%d) port_stats.ipackets not as expected\n",
3983 test_params->bonded_port_id);
3985 /* free mbufs allocate for rx testing */
3986 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3987 for (j = 0; j < MAX_PKT_BURST; j++) {
3988 if (pkt_burst[i][j] != NULL) {
3989 rte_pktmbuf_free(pkt_burst[i][j]);
3990 pkt_burst[i][j] = NULL;
3995 /* Clean up and remove slaves from bonded device */
3996 return remove_slaves_and_stop_bonded_device();
4000 test_reconfigure_bonded_device(void)
4002 test_params->nb_rx_q = 4;
4003 test_params->nb_tx_q = 4;
4005 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4006 "failed to reconfigure bonded device");
4008 test_params->nb_rx_q = 2;
4009 test_params->nb_tx_q = 2;
4011 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4012 "failed to reconfigure bonded device with less rx/tx queues");
4019 test_close_bonded_device(void)
4021 rte_eth_dev_close(test_params->bonded_port_id);
4026 testsuite_teardown(void)
4028 if (test_params->pkt_eth_hdr != NULL) {
4029 free(test_params->pkt_eth_hdr);
4030 test_params->pkt_eth_hdr = NULL;
4033 /* Clean up and remove slaves from bonded device */
4034 return remove_slaves_and_stop_bonded_device();
4038 free_virtualpmd_tx_queue(void)
4040 int i, slave_port, to_free_cnt;
4041 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4043 /* Free tx queue of virtual pmd */
4044 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4046 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4047 test_params->slave_port_ids[slave_port],
4048 pkts_to_free, MAX_PKT_BURST);
4049 for (i = 0; i < to_free_cnt; i++)
4050 rte_pktmbuf_free(pkts_to_free[i]);
4055 test_tlb_tx_burst(void)
4057 int i, burst_size, nb_tx;
4058 uint64_t nb_tx2 = 0;
4059 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4060 struct rte_eth_stats port_stats[32];
4061 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4063 uint64_t floor_obytes = 0, ceiling_obytes = 0;
4065 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4066 (BONDING_MODE_TLB, 1, 3, 1),
4067 "Failed to initialise bonded device");
4069 burst_size = 20 * test_params->bonded_slave_count;
4071 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4072 "Burst size specified is greater than supported.\n");
4075 /* Generate 400000 test bursts in 2s of packets to transmit */
4076 for (i = 0; i < 400000; i++) {
4077 /*test two types of mac src own(bonding) and others */
4079 initialize_eth_header(test_params->pkt_eth_hdr,
4080 (struct ether_addr *)src_mac,
4081 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4083 initialize_eth_header(test_params->pkt_eth_hdr,
4084 (struct ether_addr *)test_params->default_slave_mac,
4085 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4087 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4089 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4090 dst_addr_0, pktlen);
4091 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4092 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4093 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4094 /* Send burst on bonded port */
4095 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4099 free_virtualpmd_tx_queue();
4101 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4102 "number of packet not equal burst size");
4108 /* Verify bonded port tx stats */
4109 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4111 all_bond_opackets = port_stats[0].opackets;
4112 all_bond_obytes = port_stats[0].obytes;
4114 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4115 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4116 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4120 /* Verify slave ports tx stats */
4121 for (i = 0; i < test_params->bonded_slave_count; i++) {
4122 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4123 sum_ports_opackets += port_stats[i].opackets;
4126 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4127 "Total packets sent by slaves is not equal to packets sent by bond interface");
4128 /* distribution of packets on each slave within +/- 10% of the expected value. */
4129 for (i = 0; i < test_params->bonded_slave_count; i++) {
4131 floor_obytes = (all_bond_obytes*90)/(test_params->bonded_slave_count*100);
4132 ceiling_obytes = (all_bond_obytes*110)/(test_params->bonded_slave_count*100);
4133 TEST_ASSERT(port_stats[i].obytes >= floor_obytes &&
4134 port_stats[i].obytes <= ceiling_obytes,
4135 "Distribution is not even");
4137 /* Put all slaves down and try and transmit */
4138 for (i = 0; i < test_params->bonded_slave_count; i++) {
4139 virtual_ethdev_simulate_link_status_interrupt(
4140 test_params->slave_port_ids[i], 0);
4143 /* Send burst on bonded port */
4144 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4146 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4148 /* Clean ugit checkout masterp and remove slaves from bonded device */
4149 return remove_slaves_and_stop_bonded_device();
4152 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4155 test_tlb_rx_burst(void)
4157 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4158 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4160 struct rte_eth_stats port_stats;
4164 uint16_t i, j, nb_rx, burst_size = 17;
4166 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4167 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4169 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4170 "Failed to initialize bonded device");
4173 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4174 TEST_ASSERT(primary_port >= 0,
4175 "failed to get primary slave for bonded port (%d)",
4176 test_params->bonded_port_id);
4178 for (i = 0; i < test_params->bonded_slave_count; i++) {
4179 /* Generate test bursts of packets to transmit */
4180 TEST_ASSERT_EQUAL(generate_test_burst(
4181 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4182 "burst generation failed");
4184 /* Add rx data to slave */
4185 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4186 &gen_pkt_burst[0], burst_size);
4188 /* Call rx burst on bonded device */
4189 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4190 &rx_pkt_burst[0], MAX_PKT_BURST);
4192 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4194 if (test_params->slave_port_ids[i] == primary_port) {
4195 /* Verify bonded device rx count */
4196 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4197 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4198 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4199 test_params->bonded_port_id,
4200 (unsigned int)port_stats.ipackets, burst_size);
4202 /* Verify bonded slave devices rx count */
4203 for (j = 0; j < test_params->bonded_slave_count; j++) {
4204 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4206 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4207 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4208 test_params->slave_port_ids[i],
4209 (unsigned int)port_stats.ipackets, burst_size);
4211 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4212 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4213 test_params->slave_port_ids[i],
4214 (unsigned int)port_stats.ipackets, 0);
4218 for (j = 0; j < test_params->bonded_slave_count; j++) {
4219 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4220 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4221 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4222 test_params->slave_port_ids[i],
4223 (unsigned int)port_stats.ipackets, 0);
4228 for (i = 0; i < burst_size; i++)
4229 rte_pktmbuf_free(rx_pkt_burst[i]);
4231 /* reset bonded device stats */
4232 rte_eth_stats_reset(test_params->bonded_port_id);
4235 /* Clean up and remove slaves from bonded device */
4236 return remove_slaves_and_stop_bonded_device();
4240 test_tlb_verify_promiscuous_enable_disable(void)
4242 int i, primary_port, promiscuous_en;
4244 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4245 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4246 BONDING_MODE_TLB, 0, 4, 1),
4247 "Failed to initialize bonded device");
4249 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4250 TEST_ASSERT(primary_port >= 0,
4251 "failed to get primary slave for bonded port (%d)",
4252 test_params->bonded_port_id);
4254 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4256 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4257 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4258 "Port (%d) promiscuous mode not enabled\n",
4259 test_params->bonded_port_id);
4260 for (i = 0; i < test_params->bonded_slave_count; i++) {
4261 promiscuous_en = rte_eth_promiscuous_get(
4262 test_params->slave_port_ids[i]);
4263 if (primary_port == test_params->slave_port_ids[i]) {
4264 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4265 "Port (%d) promiscuous mode not enabled\n",
4266 test_params->bonded_port_id);
4268 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4269 "Port (%d) promiscuous mode enabled\n",
4270 test_params->bonded_port_id);
4275 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4277 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4278 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4279 "Port (%d) promiscuous mode not disabled\n",
4280 test_params->bonded_port_id);
4282 for (i = 0; i < test_params->bonded_slave_count; i++) {
4283 promiscuous_en = rte_eth_promiscuous_get(
4284 test_params->slave_port_ids[i]);
4285 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4286 "slave port (%d) promiscuous mode not disabled\n",
4287 test_params->slave_port_ids[i]);
4290 /* Clean up and remove slaves from bonded device */
4291 return remove_slaves_and_stop_bonded_device();
4295 test_tlb_verify_mac_assignment(void)
4297 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4299 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4300 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4302 /* Initialize bonded device with 2 slaves in active backup mode */
4303 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4304 BONDING_MODE_TLB, 0, 2, 1),
4305 "Failed to initialize bonded device");
4307 /* Verify that bonded MACs is that of first slave and that the other slave
4308 * MAC hasn't been changed */
4309 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4311 sizeof(read_mac_addr)),
4312 "bonded port (%d) mac address not set to that of primary port",
4313 test_params->bonded_port_id);
4315 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4317 sizeof(read_mac_addr)),
4318 "slave port (%d) mac address not set to that of primary port",
4319 test_params->slave_port_ids[0]);
4321 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4323 sizeof(read_mac_addr)),
4324 "slave port (%d) mac address not as expected",
4325 test_params->slave_port_ids[1]);
4327 /* change primary and verify that MAC addresses haven't changed */
4328 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4329 test_params->slave_port_ids[1]), 0,
4330 "Failed to set bonded port (%d) primary port to (%d)",
4331 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4333 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4335 sizeof(read_mac_addr)),
4336 "bonded port (%d) mac address not set to that of primary port",
4337 test_params->bonded_port_id);
4339 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4340 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4341 sizeof(read_mac_addr)),
4342 "slave port (%d) mac address not set to that of primary port",
4343 test_params->slave_port_ids[0]);
4345 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4347 sizeof(read_mac_addr)),
4348 "slave port (%d) mac address not as expected",
4349 test_params->slave_port_ids[1]);
4351 /* stop / start bonded device and verify that primary MAC address is
4352 * propagated to bonded device and slaves */
4354 rte_eth_dev_stop(test_params->bonded_port_id);
4356 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4357 "Failed to start device");
4359 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4361 sizeof(read_mac_addr)),
4362 "bonded port (%d) mac address not set to that of primary port",
4363 test_params->bonded_port_id);
4365 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4367 sizeof(read_mac_addr)),
4368 "slave port (%d) mac address not as expected",
4369 test_params->slave_port_ids[0]);
4371 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4372 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4373 sizeof(read_mac_addr)),
4374 "slave port (%d) mac address not set to that of primary port",
4375 test_params->slave_port_ids[1]);
4378 /* Set explicit MAC address */
4379 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4380 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4381 "failed to set MAC addres");
4383 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4384 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4385 sizeof(read_mac_addr)),
4386 "bonded port (%d) mac address not set to that of bonded port",
4387 test_params->bonded_port_id);
4389 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4390 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4391 sizeof(read_mac_addr)),
4392 "slave port (%d) mac address not as expected",
4393 test_params->slave_port_ids[0]);
4395 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4396 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4397 sizeof(read_mac_addr)),
4398 "slave port (%d) mac address not set to that of bonded port",
4399 test_params->slave_port_ids[1]);
4401 /* Clean up and remove slaves from bonded device */
4402 return remove_slaves_and_stop_bonded_device();
4406 test_tlb_verify_slave_link_status_change_failover(void)
4408 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4409 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4410 struct rte_eth_stats port_stats;
4412 uint8_t slaves[RTE_MAX_ETHPORTS];
4414 int i, j, burst_size, slave_count, primary_port;
4418 memset(pkt_burst, 0, sizeof(pkt_burst));
4422 /* Initialize bonded device with 4 slaves in round robin mode */
4423 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4424 BONDING_MODE_TLB, 0,
4425 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4426 "Failed to initialize bonded device with slaves");
4428 /* Verify Current Slaves Count /Active Slave Count is */
4429 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4431 TEST_ASSERT_EQUAL(slave_count, 4,
4432 "Number of slaves (%d) is not as expected (%d).\n",
4435 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4436 slaves, RTE_MAX_ETHPORTS);
4437 TEST_ASSERT_EQUAL(slave_count, (int)4,
4438 "Number of slaves (%d) is not as expected (%d).\n",
4441 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4442 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4443 "Primary port not as expected");
4445 /* Bring 2 slaves down and verify active slave count */
4446 virtual_ethdev_simulate_link_status_interrupt(
4447 test_params->slave_port_ids[1], 0);
4448 virtual_ethdev_simulate_link_status_interrupt(
4449 test_params->slave_port_ids[3], 0);
4451 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4452 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4453 "Number of active slaves (%d) is not as expected (%d).",
4456 virtual_ethdev_simulate_link_status_interrupt(
4457 test_params->slave_port_ids[1], 1);
4458 virtual_ethdev_simulate_link_status_interrupt(
4459 test_params->slave_port_ids[3], 1);
4462 /* Bring primary port down, verify that active slave count is 3 and primary
4464 virtual_ethdev_simulate_link_status_interrupt(
4465 test_params->slave_port_ids[0], 0);
4467 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4468 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4469 "Number of active slaves (%d) is not as expected (%d).",
4472 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4473 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4474 "Primary port not as expected");
4475 rte_delay_us(500000);
4476 /* Verify that pkts are sent on new primary slave */
4477 for (i = 0; i < 4; i++) {
4478 TEST_ASSERT_EQUAL(generate_test_burst(
4479 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4480 "generate_test_burst failed\n");
4481 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4482 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4483 "rte_eth_tx_burst failed\n");
4484 rte_delay_us(11000);
4487 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4488 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4489 "(%d) port_stats.opackets not as expected\n",
4490 test_params->slave_port_ids[0]);
4492 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4493 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4494 "(%d) port_stats.opackets not as expected\n",
4495 test_params->slave_port_ids[1]);
4497 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4498 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4499 "(%d) port_stats.opackets not as expected\n",
4500 test_params->slave_port_ids[2]);
4502 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4503 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4504 "(%d) port_stats.opackets not as expected\n",
4505 test_params->slave_port_ids[3]);
4508 /* Generate packet burst for testing */
4510 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4511 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4515 virtual_ethdev_add_mbufs_to_rx_queue(
4516 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4519 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4520 MAX_PKT_BURST) != burst_size) {
4521 printf("rte_eth_rx_burst\n");
4526 /* Verify bonded device rx count */
4527 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4528 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4529 "(%d) port_stats.ipackets not as expected\n",
4530 test_params->bonded_port_id);
4534 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4535 for (j = 0; j < MAX_PKT_BURST; j++) {
4536 if (pkt_burst[i][j] != NULL) {
4537 rte_pktmbuf_free(pkt_burst[i][j]);
4538 pkt_burst[i][j] = NULL;
4544 /* Clean up and remove slaves from bonded device */
4545 return remove_slaves_and_stop_bonded_device();
4548 #define TEST_ALB_SLAVE_COUNT 2
4550 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4551 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4552 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4553 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4555 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4556 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4557 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4558 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4559 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4562 test_alb_change_mac_in_reply_sent(void)
4564 struct rte_mbuf *pkt;
4565 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4567 struct ether_hdr *eth_pkt;
4568 struct arp_hdr *arp_pkt;
4570 int slave_idx, nb_pkts, pkt_idx;
4573 struct ether_addr bond_mac, client_mac;
4574 struct ether_addr *slave_mac1, *slave_mac2;
4576 TEST_ASSERT_SUCCESS(
4577 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4578 0, TEST_ALB_SLAVE_COUNT, 1),
4579 "Failed to initialize_bonded_device_with_slaves.");
4581 /* Flush tx queue */
4582 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4583 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4585 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4586 test_params->slave_port_ids[slave_idx], pkts_sent,
4591 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4595 * Generating four packets with different mac and ip addresses and sending
4596 * them through the bonding port.
4598 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4599 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4600 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4601 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4603 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4604 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4606 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4608 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4609 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4610 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4611 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4613 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4614 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4616 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4618 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4619 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4620 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4621 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4623 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4624 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4626 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4628 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4629 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4630 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4631 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4633 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4634 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4636 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4639 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4641 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4644 * Checking if packets are properly distributed on bonding ports. Packets
4645 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4647 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4648 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4649 test_params->slave_port_ids[slave_idx], pkts_sent,
4652 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4653 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4654 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4656 if (slave_idx%2 == 0) {
4657 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4662 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4671 retval += remove_slaves_and_stop_bonded_device();
4676 test_alb_reply_from_client(void)
4678 struct ether_hdr *eth_pkt;
4679 struct arp_hdr *arp_pkt;
4681 struct rte_mbuf *pkt;
4682 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4684 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4687 struct ether_addr bond_mac, client_mac;
4688 struct ether_addr *slave_mac1, *slave_mac2;
4690 TEST_ASSERT_SUCCESS(
4691 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4692 0, TEST_ALB_SLAVE_COUNT, 1),
4693 "Failed to initialize_bonded_device_with_slaves.");
4695 /* Flush tx queue */
4696 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4697 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4698 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4699 test_params->slave_port_ids[slave_idx], pkts_sent,
4704 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4708 * Generating four packets with different mac and ip addresses and placing
4709 * them in the rx queue to be received by the bonding driver on rx_burst.
4711 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4712 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4713 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4714 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4716 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4717 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4719 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4722 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4723 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4724 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4725 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4727 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4728 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4730 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4733 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4734 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4735 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4736 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4738 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4739 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4741 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4744 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4745 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4746 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4747 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4749 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4750 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4752 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4756 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4757 * packets to every client in alb table.
4759 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4760 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4762 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4763 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4766 * Checking if update ARP packets were properly send on slave ports.
4768 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4769 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4770 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4771 nb_pkts_sum += nb_pkts;
4773 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4774 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4775 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4777 if (slave_idx%2 == 0) {
4778 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4783 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4791 /* Check if proper number of packets was send */
4792 if (nb_pkts_sum < 4) {
4798 retval += remove_slaves_and_stop_bonded_device();
4803 test_alb_receive_vlan_reply(void)
4805 struct ether_hdr *eth_pkt;
4806 struct vlan_hdr *vlan_pkt;
4807 struct arp_hdr *arp_pkt;
4809 struct rte_mbuf *pkt;
4810 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4812 int slave_idx, nb_pkts, pkt_idx;
4815 struct ether_addr bond_mac, client_mac;
4817 TEST_ASSERT_SUCCESS(
4818 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4819 0, TEST_ALB_SLAVE_COUNT, 1),
4820 "Failed to initialize_bonded_device_with_slaves.");
4822 /* Flush tx queue */
4823 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4824 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4825 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4826 test_params->slave_port_ids[slave_idx], pkts_sent,
4831 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4835 * Generating packet with double VLAN header and placing it in the rx queue.
4837 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4838 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4839 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4840 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4842 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4843 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4844 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4845 vlan_pkt = vlan_pkt+1;
4846 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4847 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4848 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4849 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4851 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4854 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4855 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4858 * Checking if VLAN headers in generated ARP Update packet are correct.
4860 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4861 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4862 test_params->slave_port_ids[slave_idx], pkts_sent,
4865 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4866 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4867 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4868 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4872 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4876 vlan_pkt = vlan_pkt+1;
4877 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4881 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4889 retval += remove_slaves_and_stop_bonded_device();
4894 test_alb_ipv4_tx(void)
4896 int burst_size, retval, pkts_send;
4897 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4901 TEST_ASSERT_SUCCESS(
4902 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4903 0, TEST_ALB_SLAVE_COUNT, 1),
4904 "Failed to initialize_bonded_device_with_slaves.");
4908 /* Generate test bursts of packets to transmit */
4909 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4915 * Checking if ipv4 traffic is transmitted via TLB policy.
4917 pkts_send = rte_eth_tx_burst(
4918 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4919 if (pkts_send != burst_size) {
4925 retval += remove_slaves_and_stop_bonded_device();
4929 static struct unit_test_suite link_bonding_test_suite = {
4930 .suite_name = "Link Bonding Unit Test Suite",
4931 .setup = test_setup,
4932 .teardown = testsuite_teardown,
4933 .unit_test_cases = {
4934 TEST_CASE(test_create_bonded_device),
4935 TEST_CASE(test_create_bonded_device_with_invalid_params),
4936 TEST_CASE(test_add_slave_to_bonded_device),
4937 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4938 TEST_CASE(test_remove_slave_from_bonded_device),
4939 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4940 TEST_CASE(test_get_slaves_from_bonded_device),
4941 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4942 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4943 TEST_CASE(test_start_bonded_device),
4944 TEST_CASE(test_stop_bonded_device),
4945 TEST_CASE(test_set_bonding_mode),
4946 TEST_CASE(test_set_primary_slave),
4947 TEST_CASE(test_set_explicit_bonded_mac),
4948 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4949 TEST_CASE(test_status_interrupt),
4950 TEST_CASE(test_adding_slave_after_bonded_device_started),
4951 TEST_CASE(test_roundrobin_tx_burst),
4952 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4953 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4954 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4955 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4956 TEST_CASE(test_roundrobin_verify_mac_assignment),
4957 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4958 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4959 TEST_CASE(test_activebackup_tx_burst),
4960 TEST_CASE(test_activebackup_rx_burst),
4961 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4962 TEST_CASE(test_activebackup_verify_mac_assignment),
4963 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4964 TEST_CASE(test_balance_xmit_policy_configuration),
4965 TEST_CASE(test_balance_l2_tx_burst),
4966 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4967 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4968 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4969 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4970 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4971 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4972 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4973 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4974 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4975 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4976 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4977 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4978 TEST_CASE(test_balance_rx_burst),
4979 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4980 TEST_CASE(test_balance_verify_mac_assignment),
4981 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4982 TEST_CASE(test_tlb_tx_burst),
4983 TEST_CASE(test_tlb_rx_burst),
4984 TEST_CASE(test_tlb_verify_mac_assignment),
4985 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4986 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4987 TEST_CASE(test_alb_change_mac_in_reply_sent),
4988 TEST_CASE(test_alb_reply_from_client),
4989 TEST_CASE(test_alb_receive_vlan_reply),
4990 TEST_CASE(test_alb_ipv4_tx),
4991 TEST_CASE(test_broadcast_tx_burst),
4992 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4993 TEST_CASE(test_broadcast_rx_burst),
4994 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4995 TEST_CASE(test_broadcast_verify_mac_assignment),
4996 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4997 TEST_CASE(test_reconfigure_bonded_device),
4998 TEST_CASE(test_close_bonded_device),
5000 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
5006 test_link_bonding(void)
5008 return unit_test_suite_runner(&link_bonding_test_suite);
5011 static struct test_command link_bonding_cmd = {
5012 .command = "link_bonding_autotest",
5013 .callback = test_link_bonding,
5015 REGISTER_TEST_COMMAND(link_bonding_cmd);