]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/test/test/test_link_bonding.c
update download target update for octopus release
[ceph.git] / ceph / src / seastar / dpdk / test / test / test_link_bonding.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
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
16 * distribution.
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.
20 *
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.
32 */
33
34 #include "unistd.h"
35 #include <string.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdint.h>
40 #include <inttypes.h>
41 #include <errno.h>
42 #include <sys/queue.h>
43 #include <sys/time.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>
49 #include <rte_log.h>
50 #include <rte_lcore.h>
51 #include <rte_memory.h>
52 #include <rte_string_fns.h>
53 #include <rte_eth_bond.h>
54
55 #include "virtual_pmd.h"
56 #include "packet_burst_generator.h"
57
58 #include "test.h"
59
60 #define TEST_MAX_NUMBER_OF_PORTS (6)
61
62 #define RX_RING_SIZE 128
63 #define RX_FREE_THRESH 32
64 #define RX_PTHRESH 8
65 #define RX_HTHRESH 8
66 #define RX_WTHRESH 0
67
68 #define TX_RING_SIZE 512
69 #define TX_FREE_THRESH 32
70 #define TX_PTHRESH 32
71 #define TX_HTHRESH 0
72 #define TX_WTHRESH 0
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)
77
78 #define MBUF_CACHE_SIZE (250)
79 #define BURST_SIZE (32)
80
81 #define RTE_TEST_RX_DESC_MAX (2048)
82 #define RTE_TEST_TX_DESC_MAX (2048)
83 #define MAX_PKT_BURST (512)
84 #define DEF_PKT_BURST (16)
85
86 #define BONDED_DEV_NAME ("unit_test_bond_dev")
87
88 #define INVALID_SOCKET_ID (-1)
89 #define INVALID_PORT_ID (-1)
90 #define INVALID_BONDING_MODE (-1)
91
92
93 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
94 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
95
96 struct link_bonding_unittest_params {
97 int8_t bonded_port_id;
98 int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
99 uint8_t bonded_slave_count;
100 uint8_t bonding_mode;
101
102 uint16_t nb_rx_q;
103 uint16_t nb_tx_q;
104
105 struct rte_mempool *mbuf_pool;
106
107 struct ether_addr *default_slave_mac;
108 struct ether_addr *default_bonded_mac;
109
110 /* Packet Headers */
111 struct ether_hdr *pkt_eth_hdr;
112 struct ipv4_hdr *pkt_ipv4_hdr;
113 struct ipv6_hdr *pkt_ipv6_hdr;
114 struct udp_hdr *pkt_udp_hdr;
115
116 };
117
118 static struct ipv4_hdr pkt_ipv4_hdr;
119 static struct ipv6_hdr pkt_ipv6_hdr;
120 static struct udp_hdr pkt_udp_hdr;
121
122 static struct link_bonding_unittest_params default_params = {
123 .bonded_port_id = -1,
124 .slave_port_ids = { -1 },
125 .bonded_slave_count = 0,
126 .bonding_mode = BONDING_MODE_ROUND_ROBIN,
127
128 .nb_rx_q = 1,
129 .nb_tx_q = 1,
130
131 .mbuf_pool = NULL,
132
133 .default_slave_mac = (struct ether_addr *)slave_mac,
134 .default_bonded_mac = (struct ether_addr *)bonded_mac,
135
136 .pkt_eth_hdr = NULL,
137 .pkt_ipv4_hdr = &pkt_ipv4_hdr,
138 .pkt_ipv6_hdr = &pkt_ipv6_hdr,
139 .pkt_udp_hdr = &pkt_udp_hdr
140
141 };
142
143 static struct link_bonding_unittest_params *test_params = &default_params;
144
145 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
146 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
147 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
148
149 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
150 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
151 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
152
153 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
154 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA };
155 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
156 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA };
157 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
158 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB };
159
160 static uint16_t src_port = 1024;
161 static uint16_t dst_port_0 = 1024;
162 static uint16_t dst_port_1 = 2024;
163
164 static uint16_t vlan_id = 0x100;
165
166 struct rte_eth_rxmode rx_mode = {
167 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
168 .split_hdr_size = 0,
169 .header_split = 0, /**< Header Split disabled. */
170 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
171 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
172 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
173 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
174 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
175 .hw_strip_crc = 1, /**< CRC stripping by hardware enabled. */
176 };
177
178 struct rte_fdir_conf fdir_conf = {
179 .mode = RTE_FDIR_MODE_NONE,
180 .pballoc = RTE_FDIR_PBALLOC_64K,
181 .status = RTE_FDIR_REPORT_STATUS,
182 .drop_queue = 127,
183 };
184
185 static struct rte_eth_conf default_pmd_conf = {
186 .rxmode = {
187 .mq_mode = ETH_MQ_RX_NONE,
188 .max_rx_pkt_len = ETHER_MAX_LEN,
189 .split_hdr_size = 0,
190 .header_split = 0, /**< Header Split disabled */
191 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
192 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
193 .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
194 .hw_strip_crc = 1, /**< CRC stripped by hardware */
195 },
196 .txmode = {
197 .mq_mode = ETH_MQ_TX_NONE,
198 },
199 .lpbk_mode = 0,
200 };
201
202 static const struct rte_eth_rxconf rx_conf_default = {
203 .rx_thresh = {
204 .pthresh = RX_PTHRESH,
205 .hthresh = RX_HTHRESH,
206 .wthresh = RX_WTHRESH,
207 },
208 .rx_free_thresh = RX_FREE_THRESH,
209 .rx_drop_en = 0,
210 };
211
212 static struct rte_eth_txconf tx_conf_default = {
213 .tx_thresh = {
214 .pthresh = TX_PTHRESH,
215 .hthresh = TX_HTHRESH,
216 .wthresh = TX_WTHRESH,
217 },
218 .tx_free_thresh = TX_FREE_THRESH,
219 .tx_rs_thresh = TX_RSBIT_THRESH,
220 .txq_flags = TX_Q_FLAGS
221
222 };
223
224 static int
225 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
226 {
227 int q_id;
228
229 if (en_isr)
230 default_pmd_conf.intr_conf.lsc = 1;
231 else
232 default_pmd_conf.intr_conf.lsc = 0;
233
234 TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
235 test_params->nb_tx_q, &default_pmd_conf),
236 "rte_eth_dev_configure for port %d failed", port_id);
237
238 for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
239 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
240 rte_eth_dev_socket_id(port_id), &rx_conf_default,
241 test_params->mbuf_pool) ,
242 "rte_eth_rx_queue_setup for port %d failed", port_id);
243
244 for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
245 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
246 rte_eth_dev_socket_id(port_id), &tx_conf_default),
247 "rte_eth_tx_queue_setup for port %d failed", port_id);
248
249 if (start)
250 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
251 "rte_eth_dev_start for port %d failed", port_id);
252
253 return 0;
254 }
255
256 static int slaves_initialized;
257
258 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
259 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
260
261
262 static int
263 test_setup(void)
264 {
265 int i, nb_mbuf_per_pool;
266 struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
267
268 /* Allocate ethernet packet header with space for VLAN header */
269 if (test_params->pkt_eth_hdr == NULL) {
270 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
271 sizeof(struct vlan_hdr));
272
273 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
274 "Ethernet header struct allocation failed!");
275 }
276
277 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
278 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
279 if (test_params->mbuf_pool == NULL) {
280 test_params->mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
281 nb_mbuf_per_pool, MBUF_CACHE_SIZE, 0,
282 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
283 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
284 "rte_mempool_create failed");
285 }
286
287 /* Create / Initialize virtual eth devs */
288 if (!slaves_initialized) {
289 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
290 char pmd_name[RTE_ETH_NAME_MAX_LEN];
291
292 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
293
294 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
295
296 test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
297 mac_addr, rte_socket_id(), 1);
298 TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
299 "Failed to create virtual virtual ethdev %s", pmd_name);
300
301 TEST_ASSERT_SUCCESS(configure_ethdev(
302 test_params->slave_port_ids[i], 1, 0),
303 "Failed to configure virtual ethdev %s", pmd_name);
304 }
305 slaves_initialized = 1;
306 }
307
308 return 0;
309 }
310
311 static int
312 test_create_bonded_device(void)
313 {
314 int current_slave_count;
315
316 uint8_t slaves[RTE_MAX_ETHPORTS];
317
318 /* Don't try to recreate bonded device if re-running test suite*/
319 if (test_params->bonded_port_id == -1) {
320 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
321 test_params->bonding_mode, rte_socket_id());
322
323 TEST_ASSERT(test_params->bonded_port_id >= 0,
324 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
325
326 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
327 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
328 }
329
330 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
331 test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
332 test_params->bonded_port_id, test_params->bonding_mode);
333
334 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
335 slaves, RTE_MAX_ETHPORTS);
336
337 TEST_ASSERT_EQUAL(current_slave_count, 0,
338 "Number of slaves %d is great than expected %d.",
339 current_slave_count, 0);
340
341 current_slave_count = rte_eth_bond_active_slaves_get(
342 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
343
344 TEST_ASSERT_EQUAL(current_slave_count, 0,
345 "Number of active slaves %d is great than expected %d.",
346 current_slave_count, 0);
347
348 return 0;
349 }
350
351
352 static int
353 test_create_bonded_device_with_invalid_params(void)
354 {
355 int port_id;
356
357 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
358
359 /* Invalid name */
360 port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
361 rte_socket_id());
362 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
363
364 test_params->bonding_mode = INVALID_BONDING_MODE;
365
366 /* Invalid bonding mode */
367 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
368 rte_socket_id());
369 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
370
371 test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
372
373 /* Invalid socket id */
374 port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
375 INVALID_SOCKET_ID);
376 TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
377
378 return 0;
379 }
380
381 static int
382 test_add_slave_to_bonded_device(void)
383 {
384 int current_slave_count;
385
386 uint8_t slaves[RTE_MAX_ETHPORTS];
387
388 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
389 test_params->slave_port_ids[test_params->bonded_slave_count]),
390 "Failed to add slave (%d) to bonded port (%d).",
391 test_params->slave_port_ids[test_params->bonded_slave_count],
392 test_params->bonded_port_id);
393
394 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
395 slaves, RTE_MAX_ETHPORTS);
396 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
397 "Number of slaves (%d) is greater than expected (%d).",
398 current_slave_count, test_params->bonded_slave_count + 1);
399
400 current_slave_count = rte_eth_bond_active_slaves_get(
401 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
402 TEST_ASSERT_EQUAL(current_slave_count, 0,
403 "Number of active slaves (%d) is not as expected (%d).\n",
404 current_slave_count, 0);
405
406 test_params->bonded_slave_count++;
407
408 return 0;
409 }
410
411 static int
412 test_add_slave_to_invalid_bonded_device(void)
413 {
414 /* Invalid port ID */
415 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
416 test_params->slave_port_ids[test_params->bonded_slave_count]),
417 "Expected call to failed as invalid port specified.");
418
419 /* Non bonded device */
420 TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
421 test_params->slave_port_ids[test_params->bonded_slave_count]),
422 "Expected call to failed as invalid port specified.");
423
424 return 0;
425 }
426
427
428 static int
429 test_remove_slave_from_bonded_device(void)
430 {
431 int current_slave_count;
432 struct ether_addr read_mac_addr, *mac_addr;
433 uint8_t slaves[RTE_MAX_ETHPORTS];
434
435 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
436 test_params->slave_port_ids[test_params->bonded_slave_count-1]),
437 "Failed to remove slave %d from bonded port (%d).",
438 test_params->slave_port_ids[test_params->bonded_slave_count-1],
439 test_params->bonded_port_id);
440
441
442 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
443 slaves, RTE_MAX_ETHPORTS);
444
445 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
446 "Number of slaves (%d) is great than expected (%d).\n",
447 current_slave_count, test_params->bonded_slave_count - 1);
448
449
450 mac_addr = (struct ether_addr *)slave_mac;
451 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
452 test_params->bonded_slave_count-1;
453
454 rte_eth_macaddr_get(
455 test_params->slave_port_ids[test_params->bonded_slave_count-1],
456 &read_mac_addr);
457 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
458 "bonded port mac address not set to that of primary port\n");
459
460 rte_eth_stats_reset(
461 test_params->slave_port_ids[test_params->bonded_slave_count-1]);
462
463 virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
464 0);
465
466 test_params->bonded_slave_count--;
467
468 return 0;
469 }
470
471 static int
472 test_remove_slave_from_invalid_bonded_device(void)
473 {
474 /* Invalid port ID */
475 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
476 test_params->bonded_port_id + 5,
477 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
478 "Expected call to failed as invalid port specified.");
479
480 /* Non bonded device */
481 TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
482 test_params->slave_port_ids[0],
483 test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
484 "Expected call to failed as invalid port specified.");
485
486 return 0;
487 }
488
489 static int bonded_id = 2;
490
491 static int
492 test_add_already_bonded_slave_to_bonded_device(void)
493 {
494 int port_id, current_slave_count;
495 uint8_t slaves[RTE_MAX_ETHPORTS];
496 char pmd_name[RTE_ETH_NAME_MAX_LEN];
497
498 test_add_slave_to_bonded_device();
499
500 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
501 slaves, RTE_MAX_ETHPORTS);
502 TEST_ASSERT_EQUAL(current_slave_count, 1,
503 "Number of slaves (%d) is not that expected (%d).",
504 current_slave_count, 1);
505
506 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
507
508 port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
509 rte_socket_id());
510 TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
511
512 TEST_ASSERT(rte_eth_bond_slave_add(port_id,
513 test_params->slave_port_ids[test_params->bonded_slave_count - 1])
514 < 0,
515 "Added slave (%d) to bonded port (%d) unexpectedly.",
516 test_params->slave_port_ids[test_params->bonded_slave_count-1],
517 port_id);
518
519 return test_remove_slave_from_bonded_device();
520 }
521
522
523 static int
524 test_get_slaves_from_bonded_device(void)
525 {
526 int current_slave_count;
527 uint8_t slaves[RTE_MAX_ETHPORTS];
528
529 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
530 "Failed to add slave to bonded device");
531
532 /* Invalid port id */
533 current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
534 RTE_MAX_ETHPORTS);
535 TEST_ASSERT(current_slave_count < 0,
536 "Invalid port id unexpectedly succeeded");
537
538 current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
539 slaves, RTE_MAX_ETHPORTS);
540 TEST_ASSERT(current_slave_count < 0,
541 "Invalid port id unexpectedly succeeded");
542
543 /* Invalid slaves pointer */
544 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
545 NULL, RTE_MAX_ETHPORTS);
546 TEST_ASSERT(current_slave_count < 0,
547 "Invalid slave array unexpectedly succeeded");
548
549 current_slave_count = rte_eth_bond_active_slaves_get(
550 test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
551 TEST_ASSERT(current_slave_count < 0,
552 "Invalid slave array unexpectedly succeeded");
553
554 /* non bonded device*/
555 current_slave_count = rte_eth_bond_slaves_get(
556 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
557 TEST_ASSERT(current_slave_count < 0,
558 "Invalid port id unexpectedly succeeded");
559
560 current_slave_count = rte_eth_bond_active_slaves_get(
561 test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
562 TEST_ASSERT(current_slave_count < 0,
563 "Invalid port id unexpectedly succeeded");
564
565 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
566 "Failed to remove slaves from bonded device");
567
568 return 0;
569 }
570
571
572 static int
573 test_add_remove_multiple_slaves_to_from_bonded_device(void)
574 {
575 int i;
576
577 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
578 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
579 "Failed to add slave to bonded device");
580
581 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
582 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
583 "Failed to remove slaves from bonded device");
584
585 return 0;
586 }
587
588 static void
589 enable_bonded_slaves(void)
590 {
591 int i;
592
593 for (i = 0; i < test_params->bonded_slave_count; i++) {
594 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
595 1);
596
597 virtual_ethdev_simulate_link_status_interrupt(
598 test_params->slave_port_ids[i], 1);
599 }
600 }
601
602 static int
603 test_start_bonded_device(void)
604 {
605 struct rte_eth_link link_status;
606
607 int current_slave_count, current_bonding_mode, primary_port;
608 uint8_t slaves[RTE_MAX_ETHPORTS];
609
610 /* Add slave to bonded device*/
611 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
612 "Failed to add slave to bonded device");
613
614 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
615 "Failed to start bonded pmd eth device %d.",
616 test_params->bonded_port_id);
617
618 /* Change link status of virtual pmd so it will be added to the active
619 * slave list of the bonded device*/
620 virtual_ethdev_simulate_link_status_interrupt(
621 test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
622
623 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
624 slaves, RTE_MAX_ETHPORTS);
625 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
626 "Number of slaves (%d) is not expected value (%d).",
627 current_slave_count, test_params->bonded_slave_count);
628
629 current_slave_count = rte_eth_bond_active_slaves_get(
630 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
631 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
632 "Number of active slaves (%d) is not expected value (%d).",
633 current_slave_count, test_params->bonded_slave_count);
634
635 current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
636 TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
637 "Bonded device mode (%d) is not expected value (%d).\n",
638 current_bonding_mode, test_params->bonding_mode);
639
640 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
641 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
642 "Primary port (%d) is not expected value (%d).",
643 primary_port, test_params->slave_port_ids[0]);
644
645 rte_eth_link_get(test_params->bonded_port_id, &link_status);
646 TEST_ASSERT_EQUAL(link_status.link_status, 1,
647 "Bonded port (%d) status (%d) is not expected value (%d).\n",
648 test_params->bonded_port_id, link_status.link_status, 1);
649
650 return 0;
651 }
652
653 static int
654 test_stop_bonded_device(void)
655 {
656 int current_slave_count;
657 uint8_t slaves[RTE_MAX_ETHPORTS];
658
659 struct rte_eth_link link_status;
660
661 rte_eth_dev_stop(test_params->bonded_port_id);
662
663 rte_eth_link_get(test_params->bonded_port_id, &link_status);
664 TEST_ASSERT_EQUAL(link_status.link_status, 0,
665 "Bonded port (%d) status (%d) is not expected value (%d).",
666 test_params->bonded_port_id, link_status.link_status, 0);
667
668 current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
669 slaves, RTE_MAX_ETHPORTS);
670 TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
671 "Number of slaves (%d) is not expected value (%d).",
672 current_slave_count, test_params->bonded_slave_count);
673
674 current_slave_count = rte_eth_bond_active_slaves_get(
675 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
676 TEST_ASSERT_EQUAL(current_slave_count, 0,
677 "Number of active slaves (%d) is not expected value (%d).",
678 current_slave_count, 0);
679
680 return 0;
681 }
682
683 static int
684 remove_slaves_and_stop_bonded_device(void)
685 {
686 /* Clean up and remove slaves from bonded device */
687 while (test_params->bonded_slave_count > 0)
688 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
689 "test_remove_slave_from_bonded_device failed");
690
691 rte_eth_dev_stop(test_params->bonded_port_id);
692 rte_eth_stats_reset(test_params->bonded_port_id);
693 rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
694
695 return 0;
696 }
697
698 static int
699 test_set_bonding_mode(void)
700 {
701 int i, bonding_mode;
702
703 int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
704 BONDING_MODE_ACTIVE_BACKUP,
705 BONDING_MODE_BALANCE,
706 BONDING_MODE_BROADCAST
707 };
708
709 /* Test supported link bonding modes */
710 for (i = 0; i < (int)RTE_DIM(bonding_modes); i++) {
711 /* Invalid port ID */
712 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
713 bonding_modes[i]),
714 "Expected call to failed as invalid port (%d) specified.",
715 INVALID_PORT_ID);
716
717 /* Non bonded device */
718 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
719 bonding_modes[i]),
720 "Expected call to failed as invalid port (%d) specified.",
721 test_params->slave_port_ids[0]);
722
723 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
724 bonding_modes[i]),
725 "Failed to set link bonding mode on port (%d) to (%d).",
726 test_params->bonded_port_id, bonding_modes[i]);
727
728 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
729 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
730 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
731 bonding_mode, test_params->bonded_port_id,
732 bonding_modes[i]);
733
734 /* Invalid port ID */
735 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
736 TEST_ASSERT(bonding_mode < 0,
737 "Expected call to failed as invalid port (%d) specified.",
738 INVALID_PORT_ID);
739
740 /* Non bonded device */
741 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
742 TEST_ASSERT(bonding_mode < 0,
743 "Expected call to failed as invalid port (%d) specified.",
744 test_params->slave_port_ids[0]);
745 }
746
747 return remove_slaves_and_stop_bonded_device();
748 }
749
750 static int
751 test_set_primary_slave(void)
752 {
753 int i, j, retval;
754 struct ether_addr read_mac_addr;
755 struct ether_addr *expected_mac_addr;
756
757 /* Add 4 slaves to bonded device */
758 for (i = test_params->bonded_slave_count; i < 4; i++)
759 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
760 "Failed to add slave to bonded device.");
761
762 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
763 BONDING_MODE_ROUND_ROBIN),
764 "Failed to set link bonding mode on port (%d) to (%d).",
765 test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
766
767 /* Invalid port ID */
768 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
769 test_params->slave_port_ids[i]),
770 "Expected call to failed as invalid port specified.");
771
772 /* Non bonded device */
773 TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
774 test_params->slave_port_ids[i]),
775 "Expected call to failed as invalid port specified.");
776
777 /* Set slave as primary
778 * Verify slave it is now primary slave
779 * Verify that MAC address of bonded device is that of primary slave
780 * Verify that MAC address of all bonded slaves are that of primary slave
781 */
782 for (i = 0; i < 4; i++) {
783 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
784 test_params->slave_port_ids[i]),
785 "Failed to set bonded port (%d) primary port to (%d)",
786 test_params->bonded_port_id, test_params->slave_port_ids[i]);
787
788 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
789 TEST_ASSERT(retval >= 0,
790 "Failed to read primary port from bonded port (%d)\n",
791 test_params->bonded_port_id);
792
793 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
794 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
795 test_params->bonded_port_id, retval,
796 test_params->slave_port_ids[i]);
797
798 /* stop/start bonded eth dev to apply new MAC */
799 rte_eth_dev_stop(test_params->bonded_port_id);
800
801 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
802 "Failed to start bonded port %d",
803 test_params->bonded_port_id);
804
805 expected_mac_addr = (struct ether_addr *)&slave_mac;
806 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
807
808 /* Check primary slave MAC */
809 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
810 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
811 sizeof(read_mac_addr)),
812 "bonded port mac address not set to that of primary port\n");
813
814 /* Check bonded MAC */
815 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
816 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
817 sizeof(read_mac_addr)),
818 "bonded port mac address not set to that of primary port\n");
819
820 /* Check other slaves MACs */
821 for (j = 0; j < 4; j++) {
822 if (j != i) {
823 rte_eth_macaddr_get(test_params->slave_port_ids[j],
824 &read_mac_addr);
825 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
826 sizeof(read_mac_addr)),
827 "slave port mac address not set to that of primary "
828 "port");
829 }
830 }
831 }
832
833
834 /* Test with none existent port */
835 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
836 "read primary port from expectedly");
837
838 /* Test with slave port */
839 TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
840 "read primary port from expectedly\n");
841
842 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
843 "Failed to stop and remove slaves from bonded device");
844
845 /* No slaves */
846 TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id) < 0,
847 "read primary port from expectedly\n");
848
849 return 0;
850 }
851
852 static int
853 test_set_explicit_bonded_mac(void)
854 {
855 int i;
856 struct ether_addr read_mac_addr;
857 struct ether_addr *mac_addr;
858
859 uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
860
861 mac_addr = (struct ether_addr *)explicit_bonded_mac;
862
863 /* Invalid port ID */
864 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
865 "Expected call to failed as invalid port specified.");
866
867 /* Non bonded device */
868 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
869 test_params->slave_port_ids[0], mac_addr),
870 "Expected call to failed as invalid port specified.");
871
872 /* NULL MAC address */
873 TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
874 test_params->bonded_port_id, NULL),
875 "Expected call to failed as NULL MAC specified");
876
877 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
878 test_params->bonded_port_id, mac_addr),
879 "Failed to set MAC address on bonded port (%d)",
880 test_params->bonded_port_id);
881
882 /* Add 4 slaves to bonded device */
883 for (i = test_params->bonded_slave_count; i < 4; i++) {
884 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
885 "Failed to add slave to bonded device.\n");
886 }
887
888 /* Check bonded MAC */
889 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
890 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
891 "bonded port mac address not set to that of primary port");
892
893 /* Check other slaves MACs */
894 for (i = 0; i < 4; i++) {
895 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
896 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
897 sizeof(read_mac_addr)),
898 "slave port mac address not set to that of primary port");
899 }
900
901 /* test resetting mac address on bonded device */
902 TEST_ASSERT_SUCCESS(
903 rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
904 "Failed to reset MAC address on bonded port (%d)",
905 test_params->bonded_port_id);
906
907 TEST_ASSERT_FAIL(
908 rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
909 "Reset MAC address on bonded port (%d) unexpectedly",
910 test_params->slave_port_ids[1]);
911
912 /* test resetting mac address on bonded device with no slaves */
913 TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
914 "Failed to remove slaves and stop bonded device");
915
916 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
917 "Failed to reset MAC address on bonded port (%d)",
918 test_params->bonded_port_id);
919
920 return 0;
921 }
922
923 #define BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT (3)
924
925 static int
926 test_set_bonded_port_initialization_mac_assignment(void)
927 {
928 int i, slave_count, bonded_port_id;
929
930 uint8_t slaves[RTE_MAX_ETHPORTS];
931 int slave_port_ids[BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT];
932
933 struct ether_addr slave_mac_addr, bonded_mac_addr, read_mac_addr;
934
935 /* Initialize default values for MAC addresses */
936 memcpy(&slave_mac_addr, slave_mac, sizeof(struct ether_addr));
937 memcpy(&bonded_mac_addr, slave_mac, sizeof(struct ether_addr));
938
939 /*
940 * 1. a - Create / configure bonded / slave ethdevs
941 */
942 bonded_port_id = rte_eth_bond_create("ethdev_bond_mac_ass_test",
943 BONDING_MODE_ACTIVE_BACKUP, rte_socket_id());
944 TEST_ASSERT(bonded_port_id > 0, "failed to create bonded device");
945
946 TEST_ASSERT_SUCCESS(configure_ethdev(bonded_port_id, 0, 0),
947 "Failed to configure bonded ethdev");
948
949 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
950 char pmd_name[RTE_ETH_NAME_MAX_LEN];
951
952 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = i + 100;
953
954 snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_slave_%d", i);
955
956 slave_port_ids[i] = virtual_ethdev_create(pmd_name,
957 &slave_mac_addr, rte_socket_id(), 1);
958
959 TEST_ASSERT(slave_port_ids[i] >= 0,
960 "Failed to create slave ethdev %s", pmd_name);
961
962 TEST_ASSERT_SUCCESS(configure_ethdev(slave_port_ids[i], 1, 0),
963 "Failed to configure virtual ethdev %s",
964 pmd_name);
965 }
966
967
968 /*
969 * 2. Add slave ethdevs to bonded device
970 */
971 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
972 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(bonded_port_id,
973 slave_port_ids[i]),
974 "Failed to add slave (%d) to bonded port (%d).",
975 slave_port_ids[i], bonded_port_id);
976 }
977
978 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
979 RTE_MAX_ETHPORTS);
980 TEST_ASSERT_EQUAL(BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT, slave_count,
981 "Number of slaves (%d) is not as expected (%d)",
982 slave_count, BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT);
983
984
985 /*
986 * 3. Set explicit MAC address on bonded ethdev
987 */
988 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-2] = 0xFF;
989 bonded_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0xAA;
990
991 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
992 bonded_port_id, &bonded_mac_addr),
993 "Failed to set MAC address on bonded port (%d)",
994 bonded_port_id);
995
996
997 /* 4. a - Start bonded ethdev
998 * b - Enable slave devices
999 * c - Verify bonded/slaves ethdev MAC addresses
1000 */
1001 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1002 "Failed to start bonded pmd eth device %d.",
1003 bonded_port_id);
1004
1005 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1006 virtual_ethdev_simulate_link_status_interrupt(
1007 slave_port_ids[i], 1);
1008 }
1009
1010 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1011 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1012 sizeof(read_mac_addr)),
1013 "bonded port mac address not as expected");
1014
1015 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1016 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1017 sizeof(read_mac_addr)),
1018 "slave port 0 mac address not as expected");
1019
1020 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1021 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1022 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1023 sizeof(read_mac_addr)),
1024 "slave port 1 mac address not as expected");
1025
1026 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1027 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1028 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1029 sizeof(read_mac_addr)),
1030 "slave port 2 mac address not as expected");
1031
1032
1033 /* 7. a - Change primary port
1034 * b - Stop / Start bonded port
1035 * d - Verify slave ethdev MAC addresses
1036 */
1037 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(bonded_port_id,
1038 slave_port_ids[2]),
1039 "failed to set primary port on bonded device.");
1040
1041 rte_eth_dev_stop(bonded_port_id);
1042 TEST_ASSERT_SUCCESS(rte_eth_dev_start(bonded_port_id),
1043 "Failed to start bonded pmd eth device %d.",
1044 bonded_port_id);
1045
1046 rte_eth_macaddr_get(bonded_port_id, &read_mac_addr);
1047 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1048 sizeof(read_mac_addr)),
1049 "bonded port mac address not as expected");
1050
1051 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1052 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1053 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1054 sizeof(read_mac_addr)),
1055 "slave port 0 mac address not as expected");
1056
1057 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1058 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1059 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1060 sizeof(read_mac_addr)),
1061 "slave port 1 mac address not as expected");
1062
1063 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1064 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac_addr, &read_mac_addr,
1065 sizeof(read_mac_addr)),
1066 "slave port 2 mac address not as expected");
1067
1068 /* 6. a - Stop bonded ethdev
1069 * b - remove slave ethdevs
1070 * c - Verify slave ethdevs MACs are restored
1071 */
1072 rte_eth_dev_stop(bonded_port_id);
1073
1074 for (i = 0; i < BONDED_INIT_MAC_ASSIGNMENT_SLAVE_COUNT; i++) {
1075 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(bonded_port_id,
1076 slave_port_ids[i]),
1077 "Failed to remove slave %d from bonded port (%d).",
1078 slave_port_ids[i], bonded_port_id);
1079 }
1080
1081 slave_count = rte_eth_bond_slaves_get(bonded_port_id, slaves,
1082 RTE_MAX_ETHPORTS);
1083
1084 TEST_ASSERT_EQUAL(slave_count, 0,
1085 "Number of slaves (%d) is great than expected (%d).",
1086 slave_count, 0);
1087
1088 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 0 + 100;
1089 rte_eth_macaddr_get(slave_port_ids[0], &read_mac_addr);
1090 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1091 sizeof(read_mac_addr)),
1092 "slave port 0 mac address not as expected");
1093
1094 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 1 + 100;
1095 rte_eth_macaddr_get(slave_port_ids[1], &read_mac_addr);
1096 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1097 sizeof(read_mac_addr)),
1098 "slave port 1 mac address not as expected");
1099
1100 slave_mac_addr.addr_bytes[ETHER_ADDR_LEN-1] = 2 + 100;
1101 rte_eth_macaddr_get(slave_port_ids[2], &read_mac_addr);
1102 TEST_ASSERT_SUCCESS(memcmp(&slave_mac_addr, &read_mac_addr,
1103 sizeof(read_mac_addr)),
1104 "slave port 2 mac address not as expected");
1105
1106 return 0;
1107 }
1108
1109
1110 static int
1111 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
1112 uint8_t number_of_slaves, uint8_t enable_slave)
1113 {
1114 /* Configure bonded device */
1115 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
1116 bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
1117 "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
1118 number_of_slaves);
1119
1120 /* Add slaves to bonded device */
1121 while (number_of_slaves > test_params->bonded_slave_count)
1122 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
1123 "Failed to add slave (%d to bonding port (%d).",
1124 test_params->bonded_slave_count - 1,
1125 test_params->bonded_port_id);
1126
1127 /* Set link bonding mode */
1128 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
1129 bonding_mode),
1130 "Failed to set link bonding mode on port (%d) to (%d).",
1131 test_params->bonded_port_id, bonding_mode);
1132
1133 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1134 "Failed to start bonded pmd eth device %d.",
1135 test_params->bonded_port_id);
1136
1137 if (enable_slave)
1138 enable_bonded_slaves();
1139
1140 return 0;
1141 }
1142
1143 static int
1144 test_adding_slave_after_bonded_device_started(void)
1145 {
1146 int i;
1147
1148 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1149 BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
1150 "Failed to add slaves to bonded device");
1151
1152 /* Enabled slave devices */
1153 for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
1154 virtual_ethdev_simulate_link_status_interrupt(
1155 test_params->slave_port_ids[i], 1);
1156 }
1157
1158 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1159 test_params->slave_port_ids[test_params->bonded_slave_count]),
1160 "Failed to add slave to bonded port.\n");
1161
1162 rte_eth_stats_reset(
1163 test_params->slave_port_ids[test_params->bonded_slave_count]);
1164
1165 test_params->bonded_slave_count++;
1166
1167 return remove_slaves_and_stop_bonded_device();
1168 }
1169
1170 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT 4
1171 #define TEST_LSC_WAIT_TIMEOUT_MS 500
1172
1173 int test_lsc_interrupt_count;
1174
1175
1176 static void
1177 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1178 enum rte_eth_event_type type __rte_unused, void *param __rte_unused)
1179 {
1180 pthread_mutex_lock(&mutex);
1181 test_lsc_interrupt_count++;
1182
1183 pthread_cond_signal(&cvar);
1184 pthread_mutex_unlock(&mutex);
1185 }
1186
1187 static inline int
1188 lsc_timeout(int wait_us)
1189 {
1190 int retval = 0;
1191
1192 struct timespec ts;
1193 struct timeval tp;
1194
1195 gettimeofday(&tp, NULL);
1196
1197 /* Convert from timeval to timespec */
1198 ts.tv_sec = tp.tv_sec;
1199 ts.tv_nsec = tp.tv_usec * 1000;
1200 ts.tv_nsec += wait_us * 1000;
1201
1202 pthread_mutex_lock(&mutex);
1203 if (test_lsc_interrupt_count < 1)
1204 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1205
1206 pthread_mutex_unlock(&mutex);
1207
1208 if (retval == 0 && test_lsc_interrupt_count < 1)
1209 return -1;
1210
1211 return retval;
1212 }
1213
1214 static int
1215 test_status_interrupt(void)
1216 {
1217 int slave_count;
1218 uint8_t slaves[RTE_MAX_ETHPORTS];
1219
1220 /* initialized bonding device with T slaves */
1221 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1222 BONDING_MODE_ROUND_ROBIN, 1,
1223 TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1224 "Failed to initialise bonded device");
1225
1226 test_lsc_interrupt_count = 0;
1227
1228 /* register link status change interrupt callback */
1229 rte_eth_dev_callback_register(test_params->bonded_port_id,
1230 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1231 &test_params->bonded_port_id);
1232
1233 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1234 slaves, RTE_MAX_ETHPORTS);
1235
1236 TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1237 "Number of active slaves (%d) is not as expected (%d)",
1238 slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1239
1240 /* Bring all 4 slaves link status to down and test that we have received a
1241 * lsc interrupts */
1242 virtual_ethdev_simulate_link_status_interrupt(
1243 test_params->slave_port_ids[0], 0);
1244 virtual_ethdev_simulate_link_status_interrupt(
1245 test_params->slave_port_ids[1], 0);
1246 virtual_ethdev_simulate_link_status_interrupt(
1247 test_params->slave_port_ids[2], 0);
1248
1249 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1250 "Received a link status change interrupt unexpectedly");
1251
1252 virtual_ethdev_simulate_link_status_interrupt(
1253 test_params->slave_port_ids[3], 0);
1254
1255 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1256 "timed out waiting for interrupt");
1257
1258 TEST_ASSERT(test_lsc_interrupt_count > 0,
1259 "Did not receive link status change interrupt");
1260
1261 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1262 slaves, RTE_MAX_ETHPORTS);
1263
1264 TEST_ASSERT_EQUAL(slave_count, 0,
1265 "Number of active slaves (%d) is not as expected (%d)",
1266 slave_count, 0);
1267
1268 /* bring one slave port up so link status will change */
1269 test_lsc_interrupt_count = 0;
1270
1271 virtual_ethdev_simulate_link_status_interrupt(
1272 test_params->slave_port_ids[0], 1);
1273
1274 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1275 "timed out waiting for interrupt");
1276
1277 /* test that we have received another lsc interrupt */
1278 TEST_ASSERT(test_lsc_interrupt_count > 0,
1279 "Did not receive link status change interrupt");
1280
1281 /* Verify that calling the same slave lsc interrupt doesn't cause another
1282 * lsc interrupt from bonded device */
1283 test_lsc_interrupt_count = 0;
1284
1285 virtual_ethdev_simulate_link_status_interrupt(
1286 test_params->slave_port_ids[0], 1);
1287
1288 TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1289 "received unexpected interrupt");
1290
1291 TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1292 "Did not receive link status change interrupt");
1293
1294
1295 /* unregister lsc callback before exiting */
1296 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1297 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1298 &test_params->bonded_port_id);
1299
1300 /* Clean up and remove slaves from bonded device */
1301 return remove_slaves_and_stop_bonded_device();
1302 }
1303
1304 static int
1305 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1306 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1307 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1308 {
1309 uint16_t pktlen, generated_burst_size, ether_type;
1310 void *ip_hdr;
1311
1312 if (ipv4)
1313 ether_type = ETHER_TYPE_IPv4;
1314 else
1315 ether_type = ETHER_TYPE_IPv6;
1316
1317 if (toggle_dst_mac)
1318 initialize_eth_header(test_params->pkt_eth_hdr,
1319 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1320 ether_type, vlan, vlan_id);
1321 else
1322 initialize_eth_header(test_params->pkt_eth_hdr,
1323 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1324 ether_type, vlan, vlan_id);
1325
1326
1327 if (toggle_udp_port)
1328 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1329 dst_port_1, 64);
1330 else
1331 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1332 dst_port_0, 64);
1333
1334 if (ipv4) {
1335 if (toggle_ip_addr)
1336 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1337 dst_addr_1, pktlen);
1338 else
1339 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1340 dst_addr_0, pktlen);
1341
1342 ip_hdr = test_params->pkt_ipv4_hdr;
1343 } else {
1344 if (toggle_ip_addr)
1345 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1346 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1347 pktlen);
1348 else
1349 pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1350 (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1351 pktlen);
1352
1353 ip_hdr = test_params->pkt_ipv6_hdr;
1354 }
1355
1356 /* Generate burst of packets to transmit */
1357 generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1358 pkts_burst, test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1359 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1360 1);
1361 TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1362 "Failed to generate packet burst");
1363
1364 return generated_burst_size;
1365 }
1366
1367 /** Round Robin Mode Tests */
1368
1369 static int
1370 test_roundrobin_tx_burst(void)
1371 {
1372 int i, burst_size;
1373 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1374 struct rte_eth_stats port_stats;
1375
1376 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1377 BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1378 "Failed to intialise bonded device");
1379
1380 burst_size = 20 * test_params->bonded_slave_count;
1381
1382 TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1383 "Burst size specified is greater than supported.");
1384
1385 /* Generate test bursts of packets to transmit */
1386 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1387 burst_size, "failed to generate test burst");
1388
1389 /* Send burst on bonded port */
1390 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1391 test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1392 "tx burst failed");
1393
1394 /* Verify bonded port tx stats */
1395 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1396 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1397 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1398 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1399 burst_size);
1400
1401 /* Verify slave ports tx stats */
1402 for (i = 0; i < test_params->bonded_slave_count; i++) {
1403 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1404 TEST_ASSERT_EQUAL(port_stats.opackets,
1405 (uint64_t)burst_size / test_params->bonded_slave_count,
1406 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1407 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1408 burst_size / test_params->bonded_slave_count);
1409 }
1410
1411 /* Put all slaves down and try and transmit */
1412 for (i = 0; i < test_params->bonded_slave_count; i++) {
1413 virtual_ethdev_simulate_link_status_interrupt(
1414 test_params->slave_port_ids[i], 0);
1415 }
1416
1417 /* Send burst on bonded port */
1418 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1419 pkt_burst, burst_size), 0,
1420 "tx burst return unexpected value");
1421
1422 /* Clean up and remove slaves from bonded device */
1423 return remove_slaves_and_stop_bonded_device();
1424 }
1425
1426 static int
1427 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1428 {
1429 int i, refcnt;
1430
1431 for (i = 0; i < nb_mbufs; i++) {
1432 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1433 TEST_ASSERT_EQUAL(refcnt, val,
1434 "mbuf ref count (%d)is not the expected value (%d)",
1435 refcnt, val);
1436 }
1437 return 0;
1438 }
1439
1440 static void
1441 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1442 {
1443 int i;
1444
1445 for (i = 0; i < nb_mbufs; i++)
1446 rte_pktmbuf_free(mbufs[i]);
1447 }
1448
1449 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT (2)
1450 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE (64)
1451 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT (22)
1452 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1453
1454 static int
1455 test_roundrobin_tx_burst_slave_tx_fail(void)
1456 {
1457 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1458 struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1459
1460 struct rte_eth_stats port_stats;
1461
1462 int i, first_fail_idx, tx_count;
1463
1464 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1465 BONDING_MODE_ROUND_ROBIN, 0,
1466 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1467 "Failed to intialise bonded device");
1468
1469 /* Generate test bursts of packets to transmit */
1470 TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1471 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1472 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1473 "Failed to generate test packet burst");
1474
1475 /* Copy references to packets which we expect not to be transmitted */
1476 first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1477 (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1478 TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1479 TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1480
1481 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1482 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1483 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1484 }
1485
1486 /* Set virtual slave to only fail transmission of
1487 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1488 virtual_ethdev_tx_burst_fn_set_success(
1489 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1490 0);
1491
1492 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1493 test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1494 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1495
1496 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1497 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1498
1499 TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1500 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1501 "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1502 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1503 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1504
1505 /* Verify that failed packet are expected failed packets */
1506 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1507 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1508 "expected mbuf (%d) pointer %p not expected pointer %p",
1509 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1510 }
1511
1512 /* Verify bonded port tx stats */
1513 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1514
1515 TEST_ASSERT_EQUAL(port_stats.opackets,
1516 (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1517 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1518 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1519 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1520 TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1521 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1522
1523 /* Verify slave ports tx stats */
1524 for (i = 0; i < test_params->bonded_slave_count; i++) {
1525 int slave_expected_tx_count;
1526
1527 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1528
1529 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1530 test_params->bonded_slave_count;
1531
1532 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1533 slave_expected_tx_count = slave_expected_tx_count -
1534 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1535
1536 TEST_ASSERT_EQUAL(port_stats.opackets,
1537 (uint64_t)slave_expected_tx_count,
1538 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1539 test_params->slave_port_ids[i],
1540 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1541 }
1542
1543 /* Verify that all mbufs have a ref value of zero */
1544 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1545 TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1546 "mbufs refcnts not as expected");
1547 free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1548
1549 /* Clean up and remove slaves from bonded device */
1550 return remove_slaves_and_stop_bonded_device();
1551 }
1552
1553 static int
1554 test_roundrobin_rx_burst_on_single_slave(void)
1555 {
1556 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1557 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1558
1559 struct rte_eth_stats port_stats;
1560
1561 int i, j, burst_size = 25;
1562
1563 /* Initialize bonded device with 4 slaves in round robin mode */
1564 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1565 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1566 "Failed to initialize bonded device with slaves");
1567
1568 /* Generate test bursts of packets to transmit */
1569 TEST_ASSERT_EQUAL(generate_test_burst(
1570 gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1571 "burst generation failed");
1572
1573 for (i = 0; i < test_params->bonded_slave_count; i++) {
1574 /* Add rx data to slave */
1575 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1576 &gen_pkt_burst[0], burst_size);
1577
1578 /* Call rx burst on bonded device */
1579 /* Send burst on bonded port */
1580 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1581 test_params->bonded_port_id, 0, rx_pkt_burst,
1582 MAX_PKT_BURST), burst_size,
1583 "round-robin rx burst failed");
1584
1585 /* Verify bonded device rx count */
1586 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1587 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1588 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1589 test_params->bonded_port_id,
1590 (unsigned int)port_stats.ipackets, burst_size);
1591
1592
1593
1594 /* Verify bonded slave devices rx count */
1595 /* Verify slave ports tx stats */
1596 for (j = 0; j < test_params->bonded_slave_count; j++) {
1597 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1598
1599 if (i == j) {
1600 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1601 "Slave Port (%d) ipackets value (%u) not as expected"
1602 " (%d)", test_params->slave_port_ids[i],
1603 (unsigned int)port_stats.ipackets, burst_size);
1604 } else {
1605 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1606 "Slave Port (%d) ipackets value (%u) not as expected"
1607 " (%d)", test_params->slave_port_ids[i],
1608 (unsigned int)port_stats.ipackets, 0);
1609 }
1610
1611 /* Reset bonded slaves stats */
1612 rte_eth_stats_reset(test_params->slave_port_ids[j]);
1613 }
1614 /* reset bonded device stats */
1615 rte_eth_stats_reset(test_params->bonded_port_id);
1616 }
1617
1618 /* free mbufs */
1619 for (i = 0; i < MAX_PKT_BURST; i++) {
1620 if (gen_pkt_burst[i] != NULL)
1621 rte_pktmbuf_free(gen_pkt_burst[i]);
1622
1623 if (rx_pkt_burst[i] != NULL)
1624 rte_pktmbuf_free(rx_pkt_burst[i]);
1625 }
1626
1627
1628 /* Clean up and remove slaves from bonded device */
1629 return remove_slaves_and_stop_bonded_device();
1630 }
1631
1632 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1633
1634 static int
1635 test_roundrobin_rx_burst_on_multiple_slaves(void)
1636 {
1637 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1638
1639 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1640 struct rte_eth_stats port_stats;
1641
1642 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1643 int i, nb_rx;
1644
1645 /* Initialize bonded device with 4 slaves in round robin mode */
1646 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1647 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1648 "Failed to initialize bonded device with slaves");
1649
1650 /* Generate test bursts of packets to transmit */
1651 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1652 TEST_ASSERT_EQUAL(generate_test_burst(
1653 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1654 burst_size[i], "burst generation failed");
1655 }
1656
1657 /* Add rx data to slaves */
1658 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1659 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1660 &gen_pkt_burst[i][0], burst_size[i]);
1661 }
1662
1663 /* Call rx burst on bonded device */
1664 /* Send burst on bonded port */
1665 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1666 MAX_PKT_BURST);
1667 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1668 "round-robin rx burst failed (%d != %d)\n", nb_rx,
1669 burst_size[0] + burst_size[1] + burst_size[2]);
1670
1671 /* Verify bonded device rx count */
1672 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1673 TEST_ASSERT_EQUAL(port_stats.ipackets,
1674 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1675 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1676 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1677 burst_size[0] + burst_size[1] + burst_size[2]);
1678
1679 /* Verify bonded slave devices rx counts */
1680 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1681 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1682 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1683 test_params->slave_port_ids[0],
1684 (unsigned int)port_stats.ipackets, burst_size[0]);
1685
1686 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1687 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1688 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1689 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1690 burst_size[1]);
1691
1692 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1693 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1694 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1695 test_params->slave_port_ids[2],
1696 (unsigned int)port_stats.ipackets, burst_size[2]);
1697
1698 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1699 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1700 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1701 test_params->slave_port_ids[3],
1702 (unsigned int)port_stats.ipackets, 0);
1703
1704 /* free mbufs */
1705 for (i = 0; i < MAX_PKT_BURST; i++) {
1706 if (rx_pkt_burst[i] != NULL)
1707 rte_pktmbuf_free(rx_pkt_burst[i]);
1708 }
1709
1710 /* Clean up and remove slaves from bonded device */
1711 return remove_slaves_and_stop_bonded_device();
1712 }
1713
1714 static int
1715 test_roundrobin_verify_mac_assignment(void)
1716 {
1717 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1718
1719 int i;
1720
1721 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1722 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1723
1724 /* Initialize bonded device with 4 slaves in round robin mode */
1725 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1726 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1727 "Failed to initialize bonded device with slaves");
1728
1729 /* Verify that all MACs are the same as first slave added to bonded dev */
1730 for (i = 0; i < test_params->bonded_slave_count; i++) {
1731 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1732 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1733 sizeof(read_mac_addr)),
1734 "slave port (%d) mac address not set to that of primary port",
1735 test_params->slave_port_ids[i]);
1736 }
1737
1738 /* change primary and verify that MAC addresses haven't changed */
1739 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1740 test_params->slave_port_ids[2]),
1741 "Failed to set bonded port (%d) primary port to (%d)",
1742 test_params->bonded_port_id, test_params->slave_port_ids[i]);
1743
1744 for (i = 0; i < test_params->bonded_slave_count; i++) {
1745 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1746 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1747 sizeof(read_mac_addr)),
1748 "slave port (%d) mac address has changed to that of primary"
1749 " port without stop/start toggle of bonded device",
1750 test_params->slave_port_ids[i]);
1751 }
1752
1753 /* stop / start bonded device and verify that primary MAC address is
1754 * propagate to bonded device and slaves */
1755 rte_eth_dev_stop(test_params->bonded_port_id);
1756
1757 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1758 "Failed to start bonded device");
1759
1760 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1761 TEST_ASSERT_SUCCESS(
1762 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1763 "bonded port (%d) mac address not set to that of new primary port",
1764 test_params->slave_port_ids[i]);
1765
1766 for (i = 0; i < test_params->bonded_slave_count; i++) {
1767 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1768 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1769 sizeof(read_mac_addr)),
1770 "slave port (%d) mac address not set to that of new primary"
1771 " port", test_params->slave_port_ids[i]);
1772 }
1773
1774 /* Set explicit MAC address */
1775 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1776 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1777 "Failed to set MAC");
1778
1779 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1780 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1781 sizeof(read_mac_addr)),
1782 "bonded port (%d) mac address not set to that of new primary port",
1783 test_params->slave_port_ids[i]);
1784
1785 for (i = 0; i < test_params->bonded_slave_count; i++) {
1786 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1787 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1788 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1789 " that of new primary port\n", test_params->slave_port_ids[i]);
1790 }
1791
1792 /* Clean up and remove slaves from bonded device */
1793 return remove_slaves_and_stop_bonded_device();
1794 }
1795
1796 static int
1797 test_roundrobin_verify_promiscuous_enable_disable(void)
1798 {
1799 int i, promiscuous_en;
1800
1801 /* Initialize bonded device with 4 slaves in round robin mode */
1802 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1803 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1804 "Failed to initialize bonded device with slaves");
1805
1806 rte_eth_promiscuous_enable(test_params->bonded_port_id);
1807
1808 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1809 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1810 "Port (%d) promiscuous mode not enabled",
1811 test_params->bonded_port_id);
1812
1813 for (i = 0; i < test_params->bonded_slave_count; i++) {
1814 promiscuous_en = rte_eth_promiscuous_get(
1815 test_params->slave_port_ids[i]);
1816 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1817 "slave port (%d) promiscuous mode not enabled",
1818 test_params->slave_port_ids[i]);
1819 }
1820
1821 rte_eth_promiscuous_disable(test_params->bonded_port_id);
1822
1823 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1824 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1825 "Port (%d) promiscuous mode not disabled\n",
1826 test_params->bonded_port_id);
1827
1828 for (i = 0; i < test_params->bonded_slave_count; i++) {
1829 promiscuous_en = rte_eth_promiscuous_get(
1830 test_params->slave_port_ids[i]);
1831 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1832 "Port (%d) promiscuous mode not disabled\n",
1833 test_params->slave_port_ids[i]);
1834 }
1835
1836 /* Clean up and remove slaves from bonded device */
1837 return remove_slaves_and_stop_bonded_device();
1838 }
1839
1840 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1841 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1842
1843 static int
1844 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1845 {
1846 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1847 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1848 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1849
1850 struct rte_eth_stats port_stats;
1851 uint8_t slaves[RTE_MAX_ETHPORTS];
1852
1853 int i, burst_size, slave_count;
1854
1855 /* NULL all pointers in array to simplify cleanup */
1856 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1857
1858 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1859 * in round robin mode */
1860 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1861 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1862 "Failed to initialize bonded device with slaves");
1863
1864 /* Verify Current Slaves Count /Active Slave Count is */
1865 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1866 RTE_MAX_ETHPORTS);
1867 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1868 "Number of slaves (%d) is not as expected (%d).",
1869 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1870
1871 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1872 slaves, RTE_MAX_ETHPORTS);
1873 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1874 "Number of active slaves (%d) is not as expected (%d).",
1875 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1876
1877 /* Set 2 slaves eth_devs link status to down */
1878 virtual_ethdev_simulate_link_status_interrupt(
1879 test_params->slave_port_ids[1], 0);
1880 virtual_ethdev_simulate_link_status_interrupt(
1881 test_params->slave_port_ids[3], 0);
1882
1883 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1884 slaves, RTE_MAX_ETHPORTS);
1885 TEST_ASSERT_EQUAL(slave_count,
1886 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1887 "Number of active slaves (%d) is not as expected (%d).\n",
1888 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1889
1890 burst_size = 20;
1891
1892 /* Verify that pkts are not sent on slaves with link status down:
1893 *
1894 * 1. Generate test burst of traffic
1895 * 2. Transmit burst on bonded eth_dev
1896 * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1897 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1898 */
1899 TEST_ASSERT_EQUAL(
1900 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1901 burst_size, "generate_test_burst failed");
1902
1903 rte_eth_stats_reset(test_params->bonded_port_id);
1904
1905
1906 TEST_ASSERT_EQUAL(
1907 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1908 burst_size), burst_size, "rte_eth_tx_burst failed");
1909
1910 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1911 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1912 "Port (%d) opackets stats (%d) not expected (%d) value",
1913 test_params->bonded_port_id, (int)port_stats.opackets,
1914 burst_size);
1915
1916 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1917 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1918 "Port (%d) opackets stats (%d) not expected (%d) value",
1919 test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1920
1921 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1922 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1923 "Port (%d) opackets stats (%d) not expected (%d) value",
1924 test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1925
1926 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1927 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1928 "Port (%d) opackets stats (%d) not expected (%d) value",
1929 test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1930
1931 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1932 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1933 "Port (%d) opackets stats (%d) not expected (%d) value",
1934 test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1935
1936 /* Verify that pkts are not sent on slaves with link status down:
1937 *
1938 * 1. Generate test bursts of traffic
1939 * 2. Add bursts on to virtual eth_devs
1940 * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1941 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1942 * 4. Verify stats for bonded eth_dev
1943 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1944 */
1945 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1946 TEST_ASSERT_EQUAL(generate_test_burst(
1947 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1948 burst_size, "failed to generate packet burst");
1949
1950 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1951 &gen_pkt_burst[i][0], burst_size);
1952 }
1953
1954 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1955 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1956 burst_size + burst_size,
1957 "rte_eth_rx_burst failed");
1958
1959 /* Verify bonded device rx count */
1960 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1961 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1962 "(%d) port_stats.ipackets not as expected\n",
1963 test_params->bonded_port_id);
1964
1965 /* free mbufs */
1966 for (i = 0; i < MAX_PKT_BURST; i++) {
1967 if (rx_pkt_burst[i] != NULL)
1968 rte_pktmbuf_free(rx_pkt_burst[i]);
1969
1970 if (gen_pkt_burst[1][i] != NULL)
1971 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1972
1973 if (gen_pkt_burst[3][i] != NULL)
1974 rte_pktmbuf_free(gen_pkt_burst[1][i]);
1975 }
1976
1977 /* Clean up and remove slaves from bonded device */
1978 return remove_slaves_and_stop_bonded_device();
1979 }
1980
1981 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1982
1983 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1984
1985
1986 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1987
1988 static int
1989 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1990 {
1991 struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1992 char slave_name[RTE_ETH_NAME_MAX_LEN];
1993
1994 int i;
1995
1996 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1997 /* Generate slave name / MAC address */
1998 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1999 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
2000
2001 /* Create slave devices with no ISR Support */
2002 if (polling_test_slaves[i] == -1) {
2003 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
2004 rte_socket_id(), 0);
2005 TEST_ASSERT(polling_test_slaves[i] >= 0,
2006 "Failed to create virtual virtual ethdev %s\n", slave_name);
2007
2008 /* Configure slave */
2009 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
2010 "Failed to configure virtual ethdev %s(%d)", slave_name,
2011 polling_test_slaves[i]);
2012 }
2013
2014 /* Add slave to bonded device */
2015 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
2016 polling_test_slaves[i]),
2017 "Failed to add slave %s(%d) to bonded device %d",
2018 slave_name, polling_test_slaves[i],
2019 test_params->bonded_port_id);
2020 }
2021
2022 /* Initialize bonded device */
2023 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
2024 "Failed to configure bonded device %d",
2025 test_params->bonded_port_id);
2026
2027
2028 /* Register link status change interrupt callback */
2029 rte_eth_dev_callback_register(test_params->bonded_port_id,
2030 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2031 &test_params->bonded_port_id);
2032
2033 /* link status change callback for first slave link up */
2034 test_lsc_interrupt_count = 0;
2035
2036 virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
2037
2038 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
2039
2040
2041 /* no link status change callback for second slave link up */
2042 test_lsc_interrupt_count = 0;
2043
2044 virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
2045
2046 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
2047
2048 /* link status change callback for both slave links down */
2049 test_lsc_interrupt_count = 0;
2050
2051 virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
2052 virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
2053
2054 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
2055
2056 /* Un-Register link status change interrupt callback */
2057 rte_eth_dev_callback_unregister(test_params->bonded_port_id,
2058 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
2059 &test_params->bonded_port_id);
2060
2061
2062 /* Clean up and remove slaves from bonded device */
2063 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
2064
2065 TEST_ASSERT_SUCCESS(
2066 rte_eth_bond_slave_remove(test_params->bonded_port_id,
2067 polling_test_slaves[i]),
2068 "Failed to remove slave %d from bonded port (%d)",
2069 polling_test_slaves[i], test_params->bonded_port_id);
2070 }
2071
2072 return remove_slaves_and_stop_bonded_device();
2073 }
2074
2075
2076 /** Active Backup Mode Tests */
2077
2078 static int
2079 test_activebackup_tx_burst(void)
2080 {
2081 int i, pktlen, primary_port, burst_size;
2082 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
2083 struct rte_eth_stats port_stats;
2084
2085 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2086 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
2087 "Failed to initialize bonded device with slaves");
2088
2089 initialize_eth_header(test_params->pkt_eth_hdr,
2090 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2091 ETHER_TYPE_IPv4, 0, 0);
2092 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2093 dst_port_0, 16);
2094 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2095 dst_addr_0, pktlen);
2096
2097 burst_size = 20 * test_params->bonded_slave_count;
2098
2099 TEST_ASSERT(burst_size < MAX_PKT_BURST,
2100 "Burst size specified is greater than supported.");
2101
2102 /* Generate a burst of packets to transmit */
2103 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
2104 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2105 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
2106 burst_size, "failed to generate burst correctly");
2107
2108 /* Send burst on bonded port */
2109 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
2110 burst_size), burst_size, "tx burst failed");
2111
2112 /* Verify bonded port tx stats */
2113 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2114 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2115 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2116 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2117 burst_size);
2118
2119 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2120
2121 /* Verify slave ports tx stats */
2122 for (i = 0; i < test_params->bonded_slave_count; i++) {
2123 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
2124 if (test_params->slave_port_ids[i] == primary_port) {
2125 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2126 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2127 test_params->bonded_port_id,
2128 (unsigned int)port_stats.opackets,
2129 burst_size / test_params->bonded_slave_count);
2130 } else {
2131 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2132 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2133 test_params->bonded_port_id,
2134 (unsigned int)port_stats.opackets, 0);
2135 }
2136 }
2137
2138 /* Put all slaves down and try and transmit */
2139 for (i = 0; i < test_params->bonded_slave_count; i++) {
2140 virtual_ethdev_simulate_link_status_interrupt(
2141 test_params->slave_port_ids[i], 0);
2142 }
2143
2144 /* Send burst on bonded port */
2145 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2146 pkts_burst, burst_size), 0, "Sending empty burst failed");
2147
2148 /* Clean up and remove slaves from bonded device */
2149 return remove_slaves_and_stop_bonded_device();
2150 }
2151
2152 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
2153
2154 static int
2155 test_activebackup_rx_burst(void)
2156 {
2157 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
2158 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2159
2160 struct rte_eth_stats port_stats;
2161
2162 int primary_port;
2163
2164 int i, j, burst_size = 17;
2165
2166 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2167 BONDING_MODE_ACTIVE_BACKUP, 0,
2168 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2169 "Failed to initialize bonded device with slaves");
2170
2171 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2172 TEST_ASSERT(primary_port >= 0,
2173 "failed to get primary slave for bonded port (%d)",
2174 test_params->bonded_port_id);
2175
2176 for (i = 0; i < test_params->bonded_slave_count; i++) {
2177 /* Generate test bursts of packets to transmit */
2178 TEST_ASSERT_EQUAL(generate_test_burst(
2179 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2180 burst_size, "burst generation failed");
2181
2182 /* Add rx data to slave */
2183 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2184 &gen_pkt_burst[0], burst_size);
2185
2186 /* Call rx burst on bonded device */
2187 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2188 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2189 "rte_eth_rx_burst failed");
2190
2191 if (test_params->slave_port_ids[i] == primary_port) {
2192 /* Verify bonded device rx count */
2193 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2194 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2195 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2196 test_params->bonded_port_id,
2197 (unsigned int)port_stats.ipackets, burst_size);
2198
2199 /* Verify bonded slave devices rx count */
2200 for (j = 0; j < test_params->bonded_slave_count; j++) {
2201 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2202 if (i == j) {
2203 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2204 "Slave Port (%d) ipackets value (%u) not as "
2205 "expected (%d)", test_params->slave_port_ids[i],
2206 (unsigned int)port_stats.ipackets, burst_size);
2207 } else {
2208 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2209 "Slave Port (%d) ipackets value (%u) not as "
2210 "expected (%d)\n", test_params->slave_port_ids[i],
2211 (unsigned int)port_stats.ipackets, 0);
2212 }
2213 }
2214 } else {
2215 for (j = 0; j < test_params->bonded_slave_count; j++) {
2216 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2217 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2218 "Slave Port (%d) ipackets value (%u) not as expected "
2219 "(%d)", test_params->slave_port_ids[i],
2220 (unsigned int)port_stats.ipackets, 0);
2221 }
2222 }
2223
2224 /* free mbufs */
2225 for (i = 0; i < MAX_PKT_BURST; i++) {
2226 if (rx_pkt_burst[i] != NULL) {
2227 rte_pktmbuf_free(rx_pkt_burst[i]);
2228 rx_pkt_burst[i] = NULL;
2229 }
2230 }
2231
2232 /* reset bonded device stats */
2233 rte_eth_stats_reset(test_params->bonded_port_id);
2234 }
2235
2236 /* Clean up and remove slaves from bonded device */
2237 return remove_slaves_and_stop_bonded_device();
2238 }
2239
2240 static int
2241 test_activebackup_verify_promiscuous_enable_disable(void)
2242 {
2243 int i, primary_port, promiscuous_en;
2244
2245 /* Initialize bonded device with 4 slaves in round robin mode */
2246 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2247 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2248 "Failed to initialize bonded device with slaves");
2249
2250 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2251 TEST_ASSERT(primary_port >= 0,
2252 "failed to get primary slave for bonded port (%d)",
2253 test_params->bonded_port_id);
2254
2255 rte_eth_promiscuous_enable(test_params->bonded_port_id);
2256
2257 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2258 "Port (%d) promiscuous mode not enabled",
2259 test_params->bonded_port_id);
2260
2261 for (i = 0; i < test_params->bonded_slave_count; i++) {
2262 promiscuous_en = rte_eth_promiscuous_get(
2263 test_params->slave_port_ids[i]);
2264 if (primary_port == test_params->slave_port_ids[i]) {
2265 TEST_ASSERT_EQUAL(promiscuous_en, 1,
2266 "slave port (%d) promiscuous mode not enabled",
2267 test_params->slave_port_ids[i]);
2268 } else {
2269 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2270 "slave port (%d) promiscuous mode enabled",
2271 test_params->slave_port_ids[i]);
2272 }
2273
2274 }
2275
2276 rte_eth_promiscuous_disable(test_params->bonded_port_id);
2277
2278 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2279 "Port (%d) promiscuous mode not disabled\n",
2280 test_params->bonded_port_id);
2281
2282 for (i = 0; i < test_params->bonded_slave_count; i++) {
2283 promiscuous_en = rte_eth_promiscuous_get(
2284 test_params->slave_port_ids[i]);
2285 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2286 "slave port (%d) promiscuous mode not disabled\n",
2287 test_params->slave_port_ids[i]);
2288 }
2289
2290 /* Clean up and remove slaves from bonded device */
2291 return remove_slaves_and_stop_bonded_device();
2292 }
2293
2294 static int
2295 test_activebackup_verify_mac_assignment(void)
2296 {
2297 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2298
2299 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2300 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2301
2302 /* Initialize bonded device with 2 slaves in active backup mode */
2303 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2304 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2305 "Failed to initialize bonded device with slaves");
2306
2307 /* Verify that bonded MACs is that of first slave and that the other slave
2308 * MAC hasn't been changed */
2309 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2311 sizeof(read_mac_addr)),
2312 "bonded port (%d) mac address not set to that of primary port",
2313 test_params->bonded_port_id);
2314
2315 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2317 sizeof(read_mac_addr)),
2318 "slave port (%d) mac address not set to that of primary port",
2319 test_params->slave_port_ids[0]);
2320
2321 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2322 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2323 sizeof(read_mac_addr)),
2324 "slave port (%d) mac address not as expected",
2325 test_params->slave_port_ids[1]);
2326
2327 /* change primary and verify that MAC addresses haven't changed */
2328 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2329 test_params->slave_port_ids[1]), 0,
2330 "Failed to set bonded port (%d) primary port to (%d)",
2331 test_params->bonded_port_id, test_params->slave_port_ids[1]);
2332
2333 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2335 sizeof(read_mac_addr)),
2336 "bonded port (%d) mac address not set to that of primary port",
2337 test_params->bonded_port_id);
2338
2339 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2340 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2341 sizeof(read_mac_addr)),
2342 "slave port (%d) mac address not set to that of primary port",
2343 test_params->slave_port_ids[0]);
2344
2345 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2346 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2347 sizeof(read_mac_addr)),
2348 "slave port (%d) mac address not as expected",
2349 test_params->slave_port_ids[1]);
2350
2351 /* stop / start bonded device and verify that primary MAC address is
2352 * propagated to bonded device and slaves */
2353
2354 rte_eth_dev_stop(test_params->bonded_port_id);
2355
2356 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2357 "Failed to start device");
2358
2359 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2361 sizeof(read_mac_addr)),
2362 "bonded port (%d) mac address not set to that of primary port",
2363 test_params->bonded_port_id);
2364
2365 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2367 sizeof(read_mac_addr)),
2368 "slave port (%d) mac address not as expected",
2369 test_params->slave_port_ids[0]);
2370
2371 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2372 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2373 sizeof(read_mac_addr)),
2374 "slave port (%d) mac address not set to that of primary port",
2375 test_params->slave_port_ids[1]);
2376
2377 /* Set explicit MAC address */
2378 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2379 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2380 "failed to set MAC address");
2381
2382 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2383 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2384 sizeof(read_mac_addr)),
2385 "bonded port (%d) mac address not set to that of bonded port",
2386 test_params->bonded_port_id);
2387
2388 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2389 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2390 sizeof(read_mac_addr)),
2391 "slave port (%d) mac address not as expected",
2392 test_params->slave_port_ids[0]);
2393
2394 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2395 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2396 sizeof(read_mac_addr)),
2397 "slave port (%d) mac address not set to that of bonded port",
2398 test_params->slave_port_ids[1]);
2399
2400 /* Clean up and remove slaves from bonded device */
2401 return remove_slaves_and_stop_bonded_device();
2402 }
2403
2404 static int
2405 test_activebackup_verify_slave_link_status_change_failover(void)
2406 {
2407 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2408 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2409 struct rte_eth_stats port_stats;
2410
2411 uint8_t slaves[RTE_MAX_ETHPORTS];
2412
2413 int i, j, burst_size, slave_count, primary_port;
2414
2415 burst_size = 21;
2416
2417 memset(pkt_burst, 0, sizeof(pkt_burst));
2418
2419 /* Generate packet burst for testing */
2420 TEST_ASSERT_EQUAL(generate_test_burst(
2421 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2422 "generate_test_burst failed");
2423
2424 /* Initialize bonded device with 4 slaves in round robin mode */
2425 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2426 BONDING_MODE_ACTIVE_BACKUP, 0,
2427 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2428 "Failed to initialize bonded device with slaves");
2429
2430 /* Verify Current Slaves Count /Active Slave Count is */
2431 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2432 RTE_MAX_ETHPORTS);
2433 TEST_ASSERT_EQUAL(slave_count, 4,
2434 "Number of slaves (%d) is not as expected (%d).",
2435 slave_count, 4);
2436
2437 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2438 slaves, RTE_MAX_ETHPORTS);
2439 TEST_ASSERT_EQUAL(slave_count, 4,
2440 "Number of active slaves (%d) is not as expected (%d).",
2441 slave_count, 4);
2442
2443 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2444 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2445 "Primary port not as expected");
2446
2447 /* Bring 2 slaves down and verify active slave count */
2448 virtual_ethdev_simulate_link_status_interrupt(
2449 test_params->slave_port_ids[1], 0);
2450 virtual_ethdev_simulate_link_status_interrupt(
2451 test_params->slave_port_ids[3], 0);
2452
2453 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2454 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2455 "Number of active slaves (%d) is not as expected (%d).",
2456 slave_count, 2);
2457
2458 virtual_ethdev_simulate_link_status_interrupt(
2459 test_params->slave_port_ids[1], 1);
2460 virtual_ethdev_simulate_link_status_interrupt(
2461 test_params->slave_port_ids[3], 1);
2462
2463
2464 /* Bring primary port down, verify that active slave count is 3 and primary
2465 * has changed */
2466 virtual_ethdev_simulate_link_status_interrupt(
2467 test_params->slave_port_ids[0], 0);
2468
2469 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2470 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2471 3,
2472 "Number of active slaves (%d) is not as expected (%d).",
2473 slave_count, 3);
2474
2475 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2476 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2477 "Primary port not as expected");
2478
2479 /* Verify that pkts are sent on new primary slave */
2480
2481 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2482 test_params->bonded_port_id, 0, &pkt_burst[0][0],
2483 burst_size), burst_size, "rte_eth_tx_burst failed");
2484
2485 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2486 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2487 "(%d) port_stats.opackets not as expected",
2488 test_params->slave_port_ids[2]);
2489
2490 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2491 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2492 "(%d) port_stats.opackets not as expected\n",
2493 test_params->slave_port_ids[0]);
2494
2495 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2496 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2497 "(%d) port_stats.opackets not as expected\n",
2498 test_params->slave_port_ids[1]);
2499
2500 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2501 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2502 "(%d) port_stats.opackets not as expected\n",
2503 test_params->slave_port_ids[3]);
2504
2505 /* Generate packet burst for testing */
2506
2507 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2508 TEST_ASSERT_EQUAL(generate_test_burst(
2509 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2510 "generate_test_burst failed");
2511
2512 virtual_ethdev_add_mbufs_to_rx_queue(
2513 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2514 }
2515
2516 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2517 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2518 burst_size, "rte_eth_rx_burst\n");
2519
2520 /* Verify bonded device rx count */
2521 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2522 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2523 "(%d) port_stats.ipackets not as expected",
2524 test_params->bonded_port_id);
2525
2526 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2527 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2528 "(%d) port_stats.opackets not as expected",
2529 test_params->slave_port_ids[2]);
2530
2531 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2532 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2533 "(%d) port_stats.opackets not as expected",
2534 test_params->slave_port_ids[0]);
2535
2536 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2537 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2538 "(%d) port_stats.opackets not as expected",
2539 test_params->slave_port_ids[1]);
2540
2541 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2542 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2543 "(%d) port_stats.opackets not as expected",
2544 test_params->slave_port_ids[3]);
2545
2546 /* free mbufs */
2547 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2548 for (j = 0; j < MAX_PKT_BURST; j++) {
2549 if (pkt_burst[i][j] != NULL) {
2550 rte_pktmbuf_free(pkt_burst[i][j]);
2551 pkt_burst[i][j] = NULL;
2552 }
2553 }
2554 }
2555
2556 /* Clean up and remove slaves from bonded device */
2557 return remove_slaves_and_stop_bonded_device();
2558 }
2559
2560 /** Balance Mode Tests */
2561
2562 static int
2563 test_balance_xmit_policy_configuration(void)
2564 {
2565 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2566 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2567 "Failed to initialize_bonded_device_with_slaves.");
2568
2569 /* Invalid port id */
2570 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2571 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2572 "Expected call to failed as invalid port specified.");
2573
2574 /* Set xmit policy on non bonded device */
2575 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2576 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2577 "Expected call to failed as invalid port specified.");
2578
2579
2580 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2581 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2582 "Failed to set balance xmit policy.");
2583
2584 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2585 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2586
2587
2588 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2589 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2590 "Failed to set balance xmit policy.");
2591
2592 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2593 BALANCE_XMIT_POLICY_LAYER23,
2594 "balance xmit policy not as expected.");
2595
2596
2597 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2598 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2599 "Failed to set balance xmit policy.");
2600
2601 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2602 BALANCE_XMIT_POLICY_LAYER34,
2603 "balance xmit policy not as expected.");
2604
2605 /* Invalid port id */
2606 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2607 "Expected call to failed as invalid port specified.");
2608
2609 /* Clean up and remove slaves from bonded device */
2610 return remove_slaves_and_stop_bonded_device();
2611 }
2612
2613 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2614
2615 static int
2616 test_balance_l2_tx_burst(void)
2617 {
2618 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2619 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2620
2621 uint16_t pktlen;
2622 int i;
2623 struct rte_eth_stats port_stats;
2624
2625 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2626 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2627 "Failed to initialize_bonded_device_with_slaves.");
2628
2629 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2630 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2631 "Failed to set balance xmit policy.");
2632
2633 initialize_eth_header(test_params->pkt_eth_hdr,
2634 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
2635 ETHER_TYPE_IPv4, 0, 0);
2636 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2637 dst_port_0, 16);
2638 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2639 dst_addr_0, pktlen);
2640
2641 /* Generate a burst 1 of packets to transmit */
2642 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2643 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2644 test_params->pkt_udp_hdr, burst_size[0],
2645 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2646 "failed to generate packet burst");
2647
2648 initialize_eth_header(test_params->pkt_eth_hdr,
2649 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
2650 ETHER_TYPE_IPv4, 0, 0);
2651
2652 /* Generate a burst 2 of packets to transmit */
2653 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2654 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2655 test_params->pkt_udp_hdr, burst_size[1],
2656 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2657 "failed to generate packet burst");
2658
2659 /* Send burst 1 on bonded port */
2660 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2661 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2662 &pkts_burst[i][0], burst_size[i]),
2663 burst_size[i], "Failed to transmit packet burst");
2664 }
2665
2666 /* Verify bonded port tx stats */
2667 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2668 TEST_ASSERT_EQUAL(port_stats.opackets,
2669 (uint64_t)(burst_size[0] + burst_size[1]),
2670 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2671 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2672 burst_size[0] + burst_size[1]);
2673
2674
2675 /* Verify slave ports tx stats */
2676 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2677 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2678 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2679 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2680 burst_size[0]);
2681
2682 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2683 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2684 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2685 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2686 burst_size[1]);
2687
2688 /* Put all slaves down and try and transmit */
2689 for (i = 0; i < test_params->bonded_slave_count; i++) {
2690
2691 virtual_ethdev_simulate_link_status_interrupt(
2692 test_params->slave_port_ids[i], 0);
2693 }
2694
2695 /* Send burst on bonded port */
2696 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2697 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2698 0, "Expected zero packet");
2699
2700 /* Clean up and remove slaves from bonded device */
2701 return remove_slaves_and_stop_bonded_device();
2702 }
2703
2704 static int
2705 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2706 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2707 {
2708 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2709
2710 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2711 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2712
2713 struct rte_eth_stats port_stats;
2714
2715 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2716 BONDING_MODE_BALANCE, 0, 2, 1),
2717 "Failed to initialize_bonded_device_with_slaves.");
2718
2719 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2720 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2721 "Failed to set balance xmit policy.");
2722
2723 burst_size_1 = 20;
2724 burst_size_2 = 10;
2725
2726 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2727 "Burst size specified is greater than supported.");
2728
2729 /* Generate test bursts of packets to transmit */
2730 TEST_ASSERT_EQUAL(generate_test_burst(
2731 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2732 burst_size_1, "failed to generate packet burst");
2733
2734 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2735 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2736 "failed to generate packet burst");
2737
2738 /* Send burst 1 on bonded port */
2739 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2740 burst_size_1);
2741 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2742
2743 /* Send burst 2 on bonded port */
2744 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2745 burst_size_2);
2746 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2747
2748 /* Verify bonded port tx stats */
2749 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2750 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2751 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2752 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2753 nb_tx_1 + nb_tx_2);
2754
2755 /* Verify slave ports tx stats */
2756 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2757 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2758 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2759 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2760 nb_tx_1);
2761
2762 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2763 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2764 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2765 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2766 nb_tx_2);
2767
2768 /* Put all slaves down and try and transmit */
2769 for (i = 0; i < test_params->bonded_slave_count; i++) {
2770
2771 virtual_ethdev_simulate_link_status_interrupt(
2772 test_params->slave_port_ids[i], 0);
2773 }
2774
2775 /* Send burst on bonded port */
2776 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2777 test_params->bonded_port_id, 0, pkts_burst_1,
2778 burst_size_1), 0, "Expected zero packet");
2779
2780
2781 /* Clean up and remove slaves from bonded device */
2782 return remove_slaves_and_stop_bonded_device();
2783 }
2784
2785 static int
2786 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2787 {
2788 return balance_l23_tx_burst(0, 1, 1, 0);
2789 }
2790
2791 static int
2792 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2793 {
2794 return balance_l23_tx_burst(1, 1, 0, 1);
2795 }
2796
2797 static int
2798 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2799 {
2800 return balance_l23_tx_burst(0, 0, 0, 1);
2801 }
2802
2803 static int
2804 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2805 {
2806 return balance_l23_tx_burst(1, 0, 0, 1);
2807 }
2808
2809 static int
2810 test_balance_l23_tx_burst_toggle_mac_addr(void)
2811 {
2812 return balance_l23_tx_burst(0, 0, 1, 0);
2813 }
2814
2815 static int
2816 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2817 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2818 uint8_t toggle_udp_port)
2819 {
2820 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2821
2822 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2823 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2824
2825 struct rte_eth_stats port_stats;
2826
2827 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2828 BONDING_MODE_BALANCE, 0, 2, 1),
2829 "Failed to initialize_bonded_device_with_slaves.");
2830
2831 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2832 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2833 "Failed to set balance xmit policy.");
2834
2835 burst_size_1 = 20;
2836 burst_size_2 = 10;
2837
2838 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2839 "Burst size specified is greater than supported.");
2840
2841 /* Generate test bursts of packets to transmit */
2842 TEST_ASSERT_EQUAL(generate_test_burst(
2843 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2844 burst_size_1, "failed to generate burst");
2845
2846 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2847 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2848 toggle_udp_port), burst_size_2, "failed to generate burst");
2849
2850 /* Send burst 1 on bonded port */
2851 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2852 burst_size_1);
2853 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2854
2855 /* Send burst 2 on bonded port */
2856 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2857 burst_size_2);
2858 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2859
2860
2861 /* Verify bonded port tx stats */
2862 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2863 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2864 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2865 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2866 nb_tx_1 + nb_tx_2);
2867
2868 /* Verify slave ports tx stats */
2869 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2870 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2871 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2872 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2873 nb_tx_1);
2874
2875 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2876 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2877 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2878 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2879 nb_tx_2);
2880
2881 /* Put all slaves down and try and transmit */
2882 for (i = 0; i < test_params->bonded_slave_count; i++) {
2883
2884 virtual_ethdev_simulate_link_status_interrupt(
2885 test_params->slave_port_ids[i], 0);
2886 }
2887
2888 /* Send burst on bonded port */
2889 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2890 test_params->bonded_port_id, 0, pkts_burst_1,
2891 burst_size_1), 0, "Expected zero packet");
2892
2893 /* Clean up and remove slaves from bonded device */
2894 return remove_slaves_and_stop_bonded_device();
2895 }
2896
2897 static int
2898 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2899 {
2900 return balance_l34_tx_burst(0, 1, 0, 1, 0);
2901 }
2902
2903 static int
2904 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2905 {
2906 return balance_l34_tx_burst(0, 1, 0, 0, 1);
2907 }
2908
2909 static int
2910 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2911 {
2912 return balance_l34_tx_burst(1, 1, 0, 1, 0);
2913 }
2914
2915 static int
2916 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2917 {
2918 return balance_l34_tx_burst(0, 0, 0, 1, 0);
2919 }
2920
2921 static int
2922 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2923 {
2924 return balance_l34_tx_burst(1, 0, 0, 1, 0);
2925 }
2926
2927 static int
2928 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2929 {
2930 return balance_l34_tx_burst(0, 0, 0, 0, 1);
2931 }
2932
2933 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2)
2934 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40)
2935 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20)
2936 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25)
2937 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0)
2938
2939 static int
2940 test_balance_tx_burst_slave_tx_fail(void)
2941 {
2942 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2943 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2944
2945 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2946
2947 struct rte_eth_stats port_stats;
2948
2949 int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2950
2951 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2952 BONDING_MODE_BALANCE, 0,
2953 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2954 "Failed to intialise bonded device");
2955
2956 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2957 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2958 "Failed to set balance xmit policy.");
2959
2960
2961 /* Generate test bursts for transmission */
2962 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2963 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2964 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2965 "Failed to generate test packet burst 1");
2966
2967 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2968 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2969
2970 /* copy mbuf referneces for expected transmission failures */
2971 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2972 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2973
2974 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2975 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2976 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2977 "Failed to generate test packet burst 2");
2978
2979
2980 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2981 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2982 virtual_ethdev_tx_burst_fn_set_success(
2983 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2984 0);
2985
2986 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2987 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2988 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2989
2990
2991 /* Transmit burst 1 */
2992 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2993 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2994
2995 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2996 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2997 "Transmitted (%d) packets, expected to transmit (%d) packets",
2998 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2999 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3000
3001 /* Verify that failed packet are expected failed packets */
3002 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
3003 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
3004 "expected mbuf (%d) pointer %p not expected pointer %p",
3005 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
3006 }
3007
3008 /* Transmit burst 2 */
3009 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
3010 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3011
3012 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3013 "Transmitted (%d) packets, expected to transmit (%d) packets",
3014 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3015
3016
3017 /* Verify bonded port tx stats */
3018 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3019
3020 TEST_ASSERT_EQUAL(port_stats.opackets,
3021 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3022 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3023 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
3024 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3025 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3026 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3027 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
3028 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3029
3030 /* Verify slave ports tx stats */
3031
3032 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3033
3034 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
3035 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3036 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
3037 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3038 test_params->slave_port_ids[0],
3039 (unsigned int)port_stats.opackets,
3040 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
3041 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3042
3043
3044
3045
3046 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3047
3048 TEST_ASSERT_EQUAL(port_stats.opackets,
3049 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
3050 "Slave Port (%d) opackets value (%u) not as expected (%d)",
3051 test_params->slave_port_ids[1],
3052 (unsigned int)port_stats.opackets,
3053 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
3054
3055 /* Verify that all mbufs have a ref value of zero */
3056 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
3057 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
3058 "mbufs refcnts not as expected");
3059
3060 free_mbufs(&pkts_burst_1[tx_count_1],
3061 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
3062
3063 /* Clean up and remove slaves from bonded device */
3064 return remove_slaves_and_stop_bonded_device();
3065 }
3066
3067 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
3068
3069 static int
3070 test_balance_rx_burst(void)
3071 {
3072 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
3073
3074 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3075 struct rte_eth_stats port_stats;
3076
3077 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
3078 int i, j;
3079
3080 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3081
3082 /* Initialize bonded device with 4 slaves in round robin mode */
3083 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3084 BONDING_MODE_BALANCE, 0, 3, 1),
3085 "Failed to intialise bonded device");
3086
3087 /* Generate test bursts of packets to transmit */
3088 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3089 TEST_ASSERT_EQUAL(generate_test_burst(
3090 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
3091 0, 0), burst_size[i],
3092 "failed to generate packet burst");
3093 }
3094
3095 /* Add rx data to slaves */
3096 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3097 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3098 &gen_pkt_burst[i][0], burst_size[i]);
3099 }
3100
3101 /* Call rx burst on bonded device */
3102 /* Send burst on bonded port */
3103 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
3104 rx_pkt_burst, MAX_PKT_BURST),
3105 burst_size[0] + burst_size[1] + burst_size[2],
3106 "balance rx burst failed\n");
3107
3108 /* Verify bonded device rx count */
3109 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3110 TEST_ASSERT_EQUAL(port_stats.ipackets,
3111 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3112 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3113 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3114 burst_size[0] + burst_size[1] + burst_size[2]);
3115
3116
3117 /* Verify bonded slave devices rx counts */
3118 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3119 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3120 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3121 test_params->slave_port_ids[0],
3122 (unsigned int)port_stats.ipackets, burst_size[0]);
3123
3124 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3125 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3126 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3127 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
3128 burst_size[1]);
3129
3130 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3131 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3132 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3133 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3134 burst_size[2]);
3135
3136 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3137 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3138 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3139 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3140 0);
3141
3142 /* free mbufs */
3143 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3144 for (j = 0; j < MAX_PKT_BURST; j++) {
3145 if (gen_pkt_burst[i][j] != NULL) {
3146 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3147 gen_pkt_burst[i][j] = NULL;
3148 }
3149 }
3150 }
3151
3152 /* Clean up and remove slaves from bonded device */
3153 return remove_slaves_and_stop_bonded_device();
3154 }
3155
3156 static int
3157 test_balance_verify_promiscuous_enable_disable(void)
3158 {
3159 int i;
3160
3161 /* Initialize bonded device with 4 slaves in round robin mode */
3162 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3163 BONDING_MODE_BALANCE, 0, 4, 1),
3164 "Failed to intialise bonded device");
3165
3166 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3167
3168 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3169 "Port (%d) promiscuous mode not enabled",
3170 test_params->bonded_port_id);
3171
3172 for (i = 0; i < test_params->bonded_slave_count; i++) {
3173 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3174 test_params->slave_port_ids[i]), 1,
3175 "Port (%d) promiscuous mode not enabled",
3176 test_params->slave_port_ids[i]);
3177 }
3178
3179 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3180
3181 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3182 "Port (%d) promiscuous mode not disabled",
3183 test_params->bonded_port_id);
3184
3185 for (i = 0; i < test_params->bonded_slave_count; i++) {
3186 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3187 test_params->slave_port_ids[i]), 0,
3188 "Port (%d) promiscuous mode not disabled",
3189 test_params->slave_port_ids[i]);
3190 }
3191
3192 /* Clean up and remove slaves from bonded device */
3193 return remove_slaves_and_stop_bonded_device();
3194 }
3195
3196 static int
3197 test_balance_verify_mac_assignment(void)
3198 {
3199 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3200
3201 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3202 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3203
3204 /* Initialize bonded device with 2 slaves in active backup mode */
3205 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3206 BONDING_MODE_BALANCE, 0, 2, 1),
3207 "Failed to intialise bonded device");
3208
3209 /* Verify that bonded MACs is that of first slave and that the other slave
3210 * MAC hasn't been changed */
3211 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3212 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3213 sizeof(read_mac_addr)),
3214 "bonded port (%d) mac address not set to that of primary port",
3215 test_params->bonded_port_id);
3216
3217 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3218 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3219 sizeof(read_mac_addr)),
3220 "slave port (%d) mac address not set to that of primary port",
3221 test_params->slave_port_ids[0]);
3222
3223 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3224 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3225 sizeof(read_mac_addr)),
3226 "slave port (%d) mac address not set to that of primary port",
3227 test_params->slave_port_ids[1]);
3228
3229 /* change primary and verify that MAC addresses haven't changed */
3230 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3231 test_params->slave_port_ids[1]),
3232 "Failed to set bonded port (%d) primary port to (%d)\n",
3233 test_params->bonded_port_id, test_params->slave_port_ids[1]);
3234
3235 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3236 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3237 sizeof(read_mac_addr)),
3238 "bonded port (%d) mac address not set to that of primary port",
3239 test_params->bonded_port_id);
3240
3241 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3242 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3243 sizeof(read_mac_addr)),
3244 "slave port (%d) mac address not set to that of primary port",
3245 test_params->slave_port_ids[0]);
3246
3247 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3248 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3249 sizeof(read_mac_addr)),
3250 "slave port (%d) mac address not set to that of primary port",
3251 test_params->slave_port_ids[1]);
3252
3253 /* stop / start bonded device and verify that primary MAC address is
3254 * propagated to bonded device and slaves */
3255
3256 rte_eth_dev_stop(test_params->bonded_port_id);
3257
3258 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3259 "Failed to start bonded device");
3260
3261 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3262 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3263 sizeof(read_mac_addr)),
3264 "bonded port (%d) mac address not set to that of primary port",
3265 test_params->bonded_port_id);
3266
3267 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3268 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3269 sizeof(read_mac_addr)),
3270 "slave port (%d) mac address not set to that of primary port",
3271 test_params->slave_port_ids[0]);
3272
3273 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3274 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3275 sizeof(read_mac_addr)),
3276 "slave port (%d) mac address not set to that of primary port",
3277 test_params->slave_port_ids[1]);
3278
3279 /* Set explicit MAC address */
3280 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3281 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3282 "failed to set MAC");
3283
3284 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3285 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3286 sizeof(read_mac_addr)),
3287 "bonded port (%d) mac address not set to that of bonded port",
3288 test_params->bonded_port_id);
3289
3290 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3291 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3292 sizeof(read_mac_addr)),
3293 "slave port (%d) mac address not as expected\n",
3294 test_params->slave_port_ids[0]);
3295
3296 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3297 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3298 sizeof(read_mac_addr)),
3299 "slave port (%d) mac address not set to that of bonded port",
3300 test_params->slave_port_ids[1]);
3301
3302 /* Clean up and remove slaves from bonded device */
3303 return remove_slaves_and_stop_bonded_device();
3304 }
3305
3306 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3307
3308 static int
3309 test_balance_verify_slave_link_status_change_behaviour(void)
3310 {
3311 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3312 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3313 struct rte_eth_stats port_stats;
3314
3315 uint8_t slaves[RTE_MAX_ETHPORTS];
3316
3317 int i, j, burst_size, slave_count;
3318
3319 memset(pkt_burst, 0, sizeof(pkt_burst));
3320
3321 /* Initialize bonded device with 4 slaves in round robin mode */
3322 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3323 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3324 "Failed to intialise bonded device");
3325
3326 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3327 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3328 "Failed to set balance xmit policy.");
3329
3330
3331 /* Verify Current Slaves Count /Active Slave Count is */
3332 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3333 RTE_MAX_ETHPORTS);
3334 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3335 "Number of slaves (%d) is not as expected (%d).",
3336 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3337
3338 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3339 slaves, RTE_MAX_ETHPORTS);
3340 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3341 "Number of active slaves (%d) is not as expected (%d).",
3342 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3343
3344 /* Set 2 slaves link status to down */
3345 virtual_ethdev_simulate_link_status_interrupt(
3346 test_params->slave_port_ids[1], 0);
3347 virtual_ethdev_simulate_link_status_interrupt(
3348 test_params->slave_port_ids[3], 0);
3349
3350 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3351 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3352 "Number of active slaves (%d) is not as expected (%d).",
3353 slave_count, 2);
3354
3355 /* Send to sets of packet burst and verify that they are balanced across
3356 * slaves */
3357 burst_size = 21;
3358
3359 TEST_ASSERT_EQUAL(generate_test_burst(
3360 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3361 "generate_test_burst failed");
3362
3363 TEST_ASSERT_EQUAL(generate_test_burst(
3364 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3365 "generate_test_burst failed");
3366
3367 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3368 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3369 burst_size, "rte_eth_tx_burst failed");
3370
3371 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3372 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3373 burst_size, "rte_eth_tx_burst failed");
3374
3375
3376 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3377 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3378 "(%d) port_stats.opackets (%d) not as expected (%d).",
3379 test_params->bonded_port_id, (int)port_stats.opackets,
3380 burst_size + burst_size);
3381
3382 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3383 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3384 "(%d) port_stats.opackets (%d) not as expected (%d).",
3385 test_params->slave_port_ids[0], (int)port_stats.opackets,
3386 burst_size);
3387
3388 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3389 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3390 "(%d) port_stats.opackets (%d) not as expected (%d).",
3391 test_params->slave_port_ids[2], (int)port_stats.opackets,
3392 burst_size);
3393
3394 /* verify that all packets get send on primary slave when no other slaves
3395 * are available */
3396 virtual_ethdev_simulate_link_status_interrupt(
3397 test_params->slave_port_ids[2], 0);
3398
3399 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3400 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3401 "Number of active slaves (%d) is not as expected (%d).",
3402 slave_count, 1);
3403
3404 TEST_ASSERT_EQUAL(generate_test_burst(
3405 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3406 "generate_test_burst failed");
3407
3408 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3409 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3410 burst_size, "rte_eth_tx_burst failed");
3411
3412 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3413 TEST_ASSERT_EQUAL(port_stats.opackets,
3414 (uint64_t)(burst_size + burst_size + burst_size),
3415 "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3416 test_params->bonded_port_id, (int)port_stats.opackets,
3417 burst_size + burst_size + burst_size);
3418
3419 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3420 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3421 "(%d) port_stats.opackets (%d) not as expected (%d).",
3422 test_params->slave_port_ids[0], (int)port_stats.opackets,
3423 burst_size + burst_size);
3424
3425 virtual_ethdev_simulate_link_status_interrupt(
3426 test_params->slave_port_ids[0], 0);
3427 virtual_ethdev_simulate_link_status_interrupt(
3428 test_params->slave_port_ids[1], 1);
3429 virtual_ethdev_simulate_link_status_interrupt(
3430 test_params->slave_port_ids[2], 1);
3431 virtual_ethdev_simulate_link_status_interrupt(
3432 test_params->slave_port_ids[3], 1);
3433
3434 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3435 TEST_ASSERT_EQUAL(generate_test_burst(
3436 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3437 "Failed to generate packet burst");
3438
3439 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3440 &pkt_burst[i][0], burst_size);
3441 }
3442
3443 /* Verify that pkts are not received on slaves with link status down */
3444
3445 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3446 MAX_PKT_BURST);
3447
3448 /* Verify bonded device rx count */
3449 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3450 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3451 "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3452 test_params->bonded_port_id, (int)port_stats.ipackets,
3453 burst_size * 3);
3454
3455 /* free mbufs allocate for rx testing */
3456 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3457 for (j = 0; j < MAX_PKT_BURST; j++) {
3458 if (pkt_burst[i][j] != NULL) {
3459 rte_pktmbuf_free(pkt_burst[i][j]);
3460 pkt_burst[i][j] = NULL;
3461 }
3462 }
3463 }
3464
3465 /* Clean up and remove slaves from bonded device */
3466 return remove_slaves_and_stop_bonded_device();
3467 }
3468
3469 static int
3470 test_broadcast_tx_burst(void)
3471 {
3472 int i, pktlen, burst_size;
3473 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3474
3475 struct rte_eth_stats port_stats;
3476
3477 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3478 BONDING_MODE_BROADCAST, 0, 2, 1),
3479 "Failed to intialise bonded device");
3480
3481 initialize_eth_header(test_params->pkt_eth_hdr,
3482 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
3483 ETHER_TYPE_IPv4, 0, 0);
3484
3485 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3486 dst_port_0, 16);
3487 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3488 dst_addr_0, pktlen);
3489
3490 burst_size = 20 * test_params->bonded_slave_count;
3491
3492 TEST_ASSERT(burst_size < MAX_PKT_BURST,
3493 "Burst size specified is greater than supported.");
3494
3495 /* Generate a burst of packets to transmit */
3496 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3497 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3498 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3499 1), burst_size, "Failed to generate packet burst");
3500
3501 /* Send burst on bonded port */
3502 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3503 pkts_burst, burst_size), burst_size,
3504 "Bonded Port (%d) rx burst failed, packets transmitted value "
3505 "not as expected (%d)",
3506 test_params->bonded_port_id, burst_size);
3507
3508 /* Verify bonded port tx stats */
3509 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3510 TEST_ASSERT_EQUAL(port_stats.opackets,
3511 (uint64_t)burst_size * test_params->bonded_slave_count,
3512 "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3513 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3514 burst_size);
3515
3516 /* Verify slave ports tx stats */
3517 for (i = 0; i < test_params->bonded_slave_count; i++) {
3518 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3519 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3520 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3521 test_params->bonded_port_id,
3522 (unsigned int)port_stats.opackets, burst_size);
3523 }
3524
3525 /* Put all slaves down and try and transmit */
3526 for (i = 0; i < test_params->bonded_slave_count; i++) {
3527
3528 virtual_ethdev_simulate_link_status_interrupt(
3529 test_params->slave_port_ids[i], 0);
3530 }
3531
3532 /* Send burst on bonded port */
3533 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3534 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0,
3535 "transmitted an unexpected number of packets");
3536
3537 /* Clean up and remove slaves from bonded device */
3538 return remove_slaves_and_stop_bonded_device();
3539 }
3540
3541
3542 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3)
3543 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40)
3544 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15)
3545 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10)
3546
3547 static int
3548 test_broadcast_tx_burst_slave_tx_fail(void)
3549 {
3550 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3551 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3552
3553 struct rte_eth_stats port_stats;
3554
3555 int i, tx_count;
3556
3557 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3558 BONDING_MODE_BROADCAST, 0,
3559 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3560 "Failed to intialise bonded device");
3561
3562 /* Generate test bursts for transmission */
3563 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3564 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3565 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3566 "Failed to generate test packet burst");
3567
3568 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3569 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3570 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3571 }
3572
3573 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3574 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3575 virtual_ethdev_tx_burst_fn_set_success(
3576 test_params->slave_port_ids[0],
3577 0);
3578 virtual_ethdev_tx_burst_fn_set_success(
3579 test_params->slave_port_ids[1],
3580 0);
3581 virtual_ethdev_tx_burst_fn_set_success(
3582 test_params->slave_port_ids[2],
3583 0);
3584
3585 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3586 test_params->slave_port_ids[0],
3587 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3588
3589 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3590 test_params->slave_port_ids[1],
3591 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3592
3593 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3594 test_params->slave_port_ids[2],
3595 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3596
3597 /* Transmit burst */
3598 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3599 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3600
3601 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3602 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3603 "Transmitted (%d) packets, expected to transmit (%d) packets",
3604 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3605 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3606
3607 /* Verify that failed packet are expected failed packets */
3608 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3609 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3610 "expected mbuf (%d) pointer %p not expected pointer %p",
3611 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3612 }
3613
3614 /* Verify slave ports tx stats */
3615
3616 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3617
3618 TEST_ASSERT_EQUAL(port_stats.opackets,
3619 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3620 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3621 "Port (%d) opackets value (%u) not as expected (%d)",
3622 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3623 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3624 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3625
3626
3627 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3628
3629 TEST_ASSERT_EQUAL(port_stats.opackets,
3630 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3631 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3632 "Port (%d) opackets value (%u) not as expected (%d)",
3633 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3634 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3635 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3636
3637 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3638
3639 TEST_ASSERT_EQUAL(port_stats.opackets,
3640 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3641 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3642 "Port (%d) opackets value (%u) not as expected (%d)",
3643 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3644 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3645 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3646
3647
3648 /* Verify that all mbufs who transmission failed have a ref value of one */
3649 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3650 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3651 "mbufs refcnts not as expected");
3652
3653 free_mbufs(&pkts_burst[tx_count],
3654 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3655
3656 /* Clean up and remove slaves from bonded device */
3657 return remove_slaves_and_stop_bonded_device();
3658 }
3659
3660 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3661
3662 static int
3663 test_broadcast_rx_burst(void)
3664 {
3665 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3666
3667 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3668 struct rte_eth_stats port_stats;
3669
3670 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3671 int i, j;
3672
3673 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3674
3675 /* Initialize bonded device with 4 slaves in round robin mode */
3676 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3677 BONDING_MODE_BROADCAST, 0, 3, 1),
3678 "Failed to intialise bonded device");
3679
3680 /* Generate test bursts of packets to transmit */
3681 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3682 TEST_ASSERT_EQUAL(generate_test_burst(
3683 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3684 burst_size[i], "failed to generate packet burst");
3685 }
3686
3687 /* Add rx data to slave 0 */
3688 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3689 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3690 &gen_pkt_burst[i][0], burst_size[i]);
3691 }
3692
3693
3694 /* Call rx burst on bonded device */
3695 /* Send burst on bonded port */
3696 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3697 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3698 burst_size[0] + burst_size[1] + burst_size[2],
3699 "rx burst failed");
3700
3701 /* Verify bonded device rx count */
3702 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3703 TEST_ASSERT_EQUAL(port_stats.ipackets,
3704 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3705 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3706 test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3707 burst_size[0] + burst_size[1] + burst_size[2]);
3708
3709
3710 /* Verify bonded slave devices rx counts */
3711 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3712 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3713 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3714 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3715 burst_size[0]);
3716
3717 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3718 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3719 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3720 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3721 burst_size[1]);
3722
3723 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3724 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3725 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3726 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3727 burst_size[2]);
3728
3729 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3730 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3731 "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3732 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3733 0);
3734
3735 /* free mbufs allocate for rx testing */
3736 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3737 for (j = 0; j < MAX_PKT_BURST; j++) {
3738 if (gen_pkt_burst[i][j] != NULL) {
3739 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3740 gen_pkt_burst[i][j] = NULL;
3741 }
3742 }
3743 }
3744
3745 /* Clean up and remove slaves from bonded device */
3746 return remove_slaves_and_stop_bonded_device();
3747 }
3748
3749 static int
3750 test_broadcast_verify_promiscuous_enable_disable(void)
3751 {
3752 int i;
3753
3754 /* Initialize bonded device with 4 slaves in round robin mode */
3755 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3756 BONDING_MODE_BROADCAST, 0, 4, 1),
3757 "Failed to intialise bonded device");
3758
3759 rte_eth_promiscuous_enable(test_params->bonded_port_id);
3760
3761
3762 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3763 "Port (%d) promiscuous mode not enabled",
3764 test_params->bonded_port_id);
3765
3766 for (i = 0; i < test_params->bonded_slave_count; i++) {
3767 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3768 test_params->slave_port_ids[i]), 1,
3769 "Port (%d) promiscuous mode not enabled",
3770 test_params->slave_port_ids[i]);
3771 }
3772
3773 rte_eth_promiscuous_disable(test_params->bonded_port_id);
3774
3775 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3776 "Port (%d) promiscuous mode not disabled",
3777 test_params->bonded_port_id);
3778
3779 for (i = 0; i < test_params->bonded_slave_count; i++) {
3780 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3781 test_params->slave_port_ids[i]), 0,
3782 "Port (%d) promiscuous mode not disabled",
3783 test_params->slave_port_ids[i]);
3784 }
3785
3786 /* Clean up and remove slaves from bonded device */
3787 return remove_slaves_and_stop_bonded_device();
3788 }
3789
3790 static int
3791 test_broadcast_verify_mac_assignment(void)
3792 {
3793 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3794
3795 int i;
3796
3797 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3798 rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3799
3800 /* Initialize bonded device with 4 slaves in round robin mode */
3801 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3802 BONDING_MODE_BROADCAST, 0, 4, 1),
3803 "Failed to intialise bonded device");
3804
3805 /* Verify that all MACs are the same as first slave added to bonded
3806 * device */
3807 for (i = 0; i < test_params->bonded_slave_count; i++) {
3808 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3809 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3810 sizeof(read_mac_addr)),
3811 "slave port (%d) mac address not set to that of primary port",
3812 test_params->slave_port_ids[i]);
3813 }
3814
3815 /* change primary and verify that MAC addresses haven't changed */
3816 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3817 test_params->slave_port_ids[2]),
3818 "Failed to set bonded port (%d) primary port to (%d)",
3819 test_params->bonded_port_id, test_params->slave_port_ids[i]);
3820
3821 for (i = 0; i < test_params->bonded_slave_count; i++) {
3822 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3823 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3824 sizeof(read_mac_addr)),
3825 "slave port (%d) mac address has changed to that of primary "
3826 "port without stop/start toggle of bonded device",
3827 test_params->slave_port_ids[i]);
3828 }
3829
3830 /* stop / start bonded device and verify that primary MAC address is
3831 * propagated to bonded device and slaves */
3832
3833 rte_eth_dev_stop(test_params->bonded_port_id);
3834
3835 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3836 "Failed to start bonded device");
3837
3838 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3839 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3840 sizeof(read_mac_addr)),
3841 "bonded port (%d) mac address not set to that of new primary port",
3842 test_params->slave_port_ids[i]);
3843
3844 for (i = 0; i < test_params->bonded_slave_count; i++) {
3845 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3846 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3847 sizeof(read_mac_addr)),
3848 "slave port (%d) mac address not set to that of new primary "
3849 "port", test_params->slave_port_ids[i]);
3850 }
3851
3852 /* Set explicit MAC address */
3853 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3854 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3855 "Failed to set MAC address");
3856
3857 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3858 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3859 sizeof(read_mac_addr)),
3860 "bonded port (%d) mac address not set to that of new primary port",
3861 test_params->slave_port_ids[i]);
3862
3863
3864 for (i = 0; i < test_params->bonded_slave_count; i++) {
3865 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3866 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3867 sizeof(read_mac_addr)),
3868 "slave port (%d) mac address not set to that of new primary "
3869 "port", test_params->slave_port_ids[i]);
3870 }
3871
3872 /* Clean up and remove slaves from bonded device */
3873 return remove_slaves_and_stop_bonded_device();
3874 }
3875
3876 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3877 static int
3878 test_broadcast_verify_slave_link_status_change_behaviour(void)
3879 {
3880 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3881 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3882 struct rte_eth_stats port_stats;
3883
3884 uint8_t slaves[RTE_MAX_ETHPORTS];
3885
3886 int i, j, burst_size, slave_count;
3887
3888 memset(pkt_burst, 0, sizeof(pkt_burst));
3889
3890 /* Initialize bonded device with 4 slaves in round robin mode */
3891 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3892 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3893 1), "Failed to intialise bonded device");
3894
3895 /* Verify Current Slaves Count /Active Slave Count is */
3896 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3897 RTE_MAX_ETHPORTS);
3898 TEST_ASSERT_EQUAL(slave_count, 4,
3899 "Number of slaves (%d) is not as expected (%d).",
3900 slave_count, 4);
3901
3902 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3903 slaves, RTE_MAX_ETHPORTS);
3904 TEST_ASSERT_EQUAL(slave_count, 4,
3905 "Number of active slaves (%d) is not as expected (%d).",
3906 slave_count, 4);
3907
3908 /* Set 2 slaves link status to down */
3909 virtual_ethdev_simulate_link_status_interrupt(
3910 test_params->slave_port_ids[1], 0);
3911 virtual_ethdev_simulate_link_status_interrupt(
3912 test_params->slave_port_ids[3], 0);
3913
3914 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3915 slaves, RTE_MAX_ETHPORTS);
3916 TEST_ASSERT_EQUAL(slave_count, 2,
3917 "Number of active slaves (%d) is not as expected (%d).",
3918 slave_count, 2);
3919
3920 for (i = 0; i < test_params->bonded_slave_count; i++)
3921 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3922
3923 /* Verify that pkts are not sent on slaves with link status down */
3924 burst_size = 21;
3925
3926 TEST_ASSERT_EQUAL(generate_test_burst(
3927 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3928 "generate_test_burst failed");
3929
3930 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3931 &pkt_burst[0][0], burst_size), burst_size,
3932 "rte_eth_tx_burst failed\n");
3933
3934 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3935 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3936 "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3937 test_params->bonded_port_id, (int)port_stats.opackets,
3938 burst_size * slave_count);
3939
3940 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3941 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3942 "(%d) port_stats.opackets not as expected",
3943 test_params->slave_port_ids[0]);
3944
3945 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3946 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3947 "(%d) port_stats.opackets not as expected",
3948 test_params->slave_port_ids[1]);
3949
3950 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3951 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3952 "(%d) port_stats.opackets not as expected",
3953 test_params->slave_port_ids[2]);
3954
3955
3956 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3957 TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3958 "(%d) port_stats.opackets not as expected",
3959 test_params->slave_port_ids[3]);
3960
3961
3962 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3963 TEST_ASSERT_EQUAL(generate_test_burst(
3964 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3965 burst_size, "failed to generate packet burst");
3966
3967 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3968 &pkt_burst[i][0], burst_size);
3969 }
3970
3971 /* Verify that pkts are not received on slaves with link status down */
3972 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3973 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3974 burst_size + burst_size, "rte_eth_rx_burst failed");
3975
3976
3977 /* Verify bonded device rx count */
3978 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3979 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3980 "(%d) port_stats.ipackets not as expected\n",
3981 test_params->bonded_port_id);
3982
3983 /* free mbufs allocate for rx testing */
3984 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3985 for (j = 0; j < MAX_PKT_BURST; j++) {
3986 if (pkt_burst[i][j] != NULL) {
3987 rte_pktmbuf_free(pkt_burst[i][j]);
3988 pkt_burst[i][j] = NULL;
3989 }
3990 }
3991 }
3992
3993 /* Clean up and remove slaves from bonded device */
3994 return remove_slaves_and_stop_bonded_device();
3995 }
3996
3997 static int
3998 test_reconfigure_bonded_device(void)
3999 {
4000 test_params->nb_rx_q = 4;
4001 test_params->nb_tx_q = 4;
4002
4003 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4004 "failed to reconfigure bonded device");
4005
4006 test_params->nb_rx_q = 2;
4007 test_params->nb_tx_q = 2;
4008
4009 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
4010 "failed to reconfigure bonded device with less rx/tx queues");
4011
4012 return 0;
4013 }
4014
4015
4016 static int
4017 test_close_bonded_device(void)
4018 {
4019 rte_eth_dev_close(test_params->bonded_port_id);
4020 return 0;
4021 }
4022
4023 static void
4024 testsuite_teardown(void)
4025 {
4026 free(test_params->pkt_eth_hdr);
4027 test_params->pkt_eth_hdr = NULL;
4028
4029 /* Clean up and remove slaves from bonded device */
4030 remove_slaves_and_stop_bonded_device();
4031 }
4032
4033 static void
4034 free_virtualpmd_tx_queue(void)
4035 {
4036 int i, slave_port, to_free_cnt;
4037 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST];
4038
4039 /* Free tx queue of virtual pmd */
4040 for (slave_port = 0; slave_port < test_params->bonded_slave_count;
4041 slave_port++) {
4042 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue(
4043 test_params->slave_port_ids[slave_port],
4044 pkts_to_free, MAX_PKT_BURST);
4045 for (i = 0; i < to_free_cnt; i++)
4046 rte_pktmbuf_free(pkts_to_free[i]);
4047 }
4048 }
4049
4050 static int
4051 test_tlb_tx_burst(void)
4052 {
4053 int i, burst_size, nb_tx;
4054 uint64_t nb_tx2 = 0;
4055 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4056 struct rte_eth_stats port_stats[32];
4057 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0;
4058 uint16_t pktlen;
4059
4060 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves
4061 (BONDING_MODE_TLB, 1, 3, 1),
4062 "Failed to initialise bonded device");
4063
4064 burst_size = 20 * test_params->bonded_slave_count;
4065
4066 TEST_ASSERT(burst_size < MAX_PKT_BURST,
4067 "Burst size specified is greater than supported.\n");
4068
4069
4070 /* Generate bursts of packets */
4071 for (i = 0; i < 400000; i++) {
4072 /*test two types of mac src own(bonding) and others */
4073 if (i % 2 == 0) {
4074 initialize_eth_header(test_params->pkt_eth_hdr,
4075 (struct ether_addr *)src_mac,
4076 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4077 } else {
4078 initialize_eth_header(test_params->pkt_eth_hdr,
4079 (struct ether_addr *)test_params->default_slave_mac,
4080 (struct ether_addr *)dst_mac_0, ETHER_TYPE_IPv4, 0, 0);
4081 }
4082 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
4083 dst_port_0, 16);
4084 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
4085 dst_addr_0, pktlen);
4086 generate_packet_burst(test_params->mbuf_pool, pkt_burst,
4087 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
4088 1, test_params->pkt_udp_hdr, burst_size, 60, 1);
4089 /* Send burst on bonded port */
4090 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4091 burst_size);
4092 nb_tx2 += nb_tx;
4093
4094 free_virtualpmd_tx_queue();
4095
4096 TEST_ASSERT_EQUAL(nb_tx, burst_size,
4097 "number of packet not equal burst size");
4098
4099 rte_delay_us(5);
4100 }
4101
4102
4103 /* Verify bonded port tx stats */
4104 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]);
4105
4106 all_bond_opackets = port_stats[0].opackets;
4107 all_bond_obytes = port_stats[0].obytes;
4108
4109 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2,
4110 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
4111 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets,
4112 burst_size);
4113
4114
4115 /* Verify slave ports tx stats */
4116 for (i = 0; i < test_params->bonded_slave_count; i++) {
4117 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]);
4118 sum_ports_opackets += port_stats[i].opackets;
4119 }
4120
4121 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets,
4122 "Total packets sent by slaves is not equal to packets sent by bond interface");
4123
4124 /* checking if distribution of packets is balanced over slaves */
4125 for (i = 0; i < test_params->bonded_slave_count; i++) {
4126 TEST_ASSERT(port_stats[i].obytes > 0 &&
4127 port_stats[i].obytes < all_bond_obytes,
4128 "Packets are not balanced over slaves");
4129 }
4130
4131 /* Put all slaves down and try and transmit */
4132 for (i = 0; i < test_params->bonded_slave_count; i++) {
4133 virtual_ethdev_simulate_link_status_interrupt(
4134 test_params->slave_port_ids[i], 0);
4135 }
4136
4137 /* Send burst on bonded port */
4138 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
4139 burst_size);
4140 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst");
4141
4142 /* Clean ugit checkout masterp and remove slaves from bonded device */
4143 return remove_slaves_and_stop_bonded_device();
4144 }
4145
4146 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4)
4147
4148 static int
4149 test_tlb_rx_burst(void)
4150 {
4151 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
4152 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4153
4154 struct rte_eth_stats port_stats;
4155
4156 int primary_port;
4157
4158 uint16_t i, j, nb_rx, burst_size = 17;
4159
4160 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4161 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4162 BONDING_MODE_TLB,
4163 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1),
4164 "Failed to initialize bonded device");
4165
4166
4167 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4168 TEST_ASSERT(primary_port >= 0,
4169 "failed to get primary slave for bonded port (%d)",
4170 test_params->bonded_port_id);
4171
4172 for (i = 0; i < test_params->bonded_slave_count; i++) {
4173 /* Generate test bursts of packets to transmit */
4174 TEST_ASSERT_EQUAL(generate_test_burst(
4175 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size,
4176 "burst generation failed");
4177
4178 /* Add rx data to slave */
4179 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
4180 &gen_pkt_burst[0], burst_size);
4181
4182 /* Call rx burst on bonded device */
4183 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0,
4184 &rx_pkt_burst[0], MAX_PKT_BURST);
4185
4186 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n");
4187
4188 if (test_params->slave_port_ids[i] == primary_port) {
4189 /* Verify bonded device rx count */
4190 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4191 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4192 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n",
4193 test_params->bonded_port_id,
4194 (unsigned int)port_stats.ipackets, burst_size);
4195
4196 /* Verify bonded slave devices rx count */
4197 for (j = 0; j < test_params->bonded_slave_count; j++) {
4198 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4199 if (i == j) {
4200 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4201 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4202 test_params->slave_port_ids[i],
4203 (unsigned int)port_stats.ipackets, burst_size);
4204 } else {
4205 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4206 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4207 test_params->slave_port_ids[i],
4208 (unsigned int)port_stats.ipackets, 0);
4209 }
4210 }
4211 } else {
4212 for (j = 0; j < test_params->bonded_slave_count; j++) {
4213 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
4214 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0,
4215 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n",
4216 test_params->slave_port_ids[i],
4217 (unsigned int)port_stats.ipackets, 0);
4218 }
4219 }
4220
4221 /* free mbufs */
4222 for (i = 0; i < burst_size; i++)
4223 rte_pktmbuf_free(rx_pkt_burst[i]);
4224
4225 /* reset bonded device stats */
4226 rte_eth_stats_reset(test_params->bonded_port_id);
4227 }
4228
4229 /* Clean up and remove slaves from bonded device */
4230 return remove_slaves_and_stop_bonded_device();
4231 }
4232
4233 static int
4234 test_tlb_verify_promiscuous_enable_disable(void)
4235 {
4236 int i, primary_port, promiscuous_en;
4237
4238 /* Initialize bonded device with 4 slaves in transmit load balancing mode */
4239 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves(
4240 BONDING_MODE_TLB, 0, 4, 1),
4241 "Failed to initialize bonded device");
4242
4243 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4244 TEST_ASSERT(primary_port >= 0,
4245 "failed to get primary slave for bonded port (%d)",
4246 test_params->bonded_port_id);
4247
4248 rte_eth_promiscuous_enable(test_params->bonded_port_id);
4249
4250 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4251 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4252 "Port (%d) promiscuous mode not enabled\n",
4253 test_params->bonded_port_id);
4254 for (i = 0; i < test_params->bonded_slave_count; i++) {
4255 promiscuous_en = rte_eth_promiscuous_get(
4256 test_params->slave_port_ids[i]);
4257 if (primary_port == test_params->slave_port_ids[i]) {
4258 TEST_ASSERT_EQUAL(promiscuous_en, (int)1,
4259 "Port (%d) promiscuous mode not enabled\n",
4260 test_params->bonded_port_id);
4261 } else {
4262 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4263 "Port (%d) promiscuous mode enabled\n",
4264 test_params->bonded_port_id);
4265 }
4266
4267 }
4268
4269 rte_eth_promiscuous_disable(test_params->bonded_port_id);
4270
4271 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
4272 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4273 "Port (%d) promiscuous mode not disabled\n",
4274 test_params->bonded_port_id);
4275
4276 for (i = 0; i < test_params->bonded_slave_count; i++) {
4277 promiscuous_en = rte_eth_promiscuous_get(
4278 test_params->slave_port_ids[i]);
4279 TEST_ASSERT_EQUAL(promiscuous_en, (int)0,
4280 "slave port (%d) promiscuous mode not disabled\n",
4281 test_params->slave_port_ids[i]);
4282 }
4283
4284 /* Clean up and remove slaves from bonded device */
4285 return remove_slaves_and_stop_bonded_device();
4286 }
4287
4288 static int
4289 test_tlb_verify_mac_assignment(void)
4290 {
4291 struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
4292
4293 rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
4294 rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
4295
4296 /* Initialize bonded device with 2 slaves in active backup mode */
4297 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4298 BONDING_MODE_TLB, 0, 2, 1),
4299 "Failed to initialize bonded device");
4300
4301 /* Verify that bonded MACs is that of first slave and that the other slave
4302 * MAC hasn't been changed */
4303 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4304 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4305 sizeof(read_mac_addr)),
4306 "bonded port (%d) mac address not set to that of primary port",
4307 test_params->bonded_port_id);
4308
4309 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4310 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4311 sizeof(read_mac_addr)),
4312 "slave port (%d) mac address not set to that of primary port",
4313 test_params->slave_port_ids[0]);
4314
4315 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4316 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4317 sizeof(read_mac_addr)),
4318 "slave port (%d) mac address not as expected",
4319 test_params->slave_port_ids[1]);
4320
4321 /* change primary and verify that MAC addresses haven't changed */
4322 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
4323 test_params->slave_port_ids[1]), 0,
4324 "Failed to set bonded port (%d) primary port to (%d)",
4325 test_params->bonded_port_id, test_params->slave_port_ids[1]);
4326
4327 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4328 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4329 sizeof(read_mac_addr)),
4330 "bonded port (%d) mac address not set to that of primary port",
4331 test_params->bonded_port_id);
4332
4333 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4334 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4335 sizeof(read_mac_addr)),
4336 "slave port (%d) mac address not set to that of primary port",
4337 test_params->slave_port_ids[0]);
4338
4339 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4340 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4341 sizeof(read_mac_addr)),
4342 "slave port (%d) mac address not as expected",
4343 test_params->slave_port_ids[1]);
4344
4345 /* stop / start bonded device and verify that primary MAC address is
4346 * propagated to bonded device and slaves */
4347
4348 rte_eth_dev_stop(test_params->bonded_port_id);
4349
4350 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
4351 "Failed to start device");
4352
4353 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4354 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4355 sizeof(read_mac_addr)),
4356 "bonded port (%d) mac address not set to that of primary port",
4357 test_params->bonded_port_id);
4358
4359 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4360 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4361 sizeof(read_mac_addr)),
4362 "slave port (%d) mac address not as expected",
4363 test_params->slave_port_ids[0]);
4364
4365 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
4367 sizeof(read_mac_addr)),
4368 "slave port (%d) mac address not set to that of primary port",
4369 test_params->slave_port_ids[1]);
4370
4371
4372 /* Set explicit MAC address */
4373 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
4374 test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
4375 "failed to set MAC addres");
4376
4377 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
4378 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4379 sizeof(read_mac_addr)),
4380 "bonded port (%d) mac address not set to that of bonded port",
4381 test_params->bonded_port_id);
4382
4383 rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
4384 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
4385 sizeof(read_mac_addr)),
4386 "slave port (%d) mac address not as expected",
4387 test_params->slave_port_ids[0]);
4388
4389 rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
4390 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
4391 sizeof(read_mac_addr)),
4392 "slave port (%d) mac address not set to that of bonded port",
4393 test_params->slave_port_ids[1]);
4394
4395 /* Clean up and remove slaves from bonded device */
4396 return remove_slaves_and_stop_bonded_device();
4397 }
4398
4399 static int
4400 test_tlb_verify_slave_link_status_change_failover(void)
4401 {
4402 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
4403 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
4404 struct rte_eth_stats port_stats;
4405
4406 uint8_t slaves[RTE_MAX_ETHPORTS];
4407
4408 int i, j, burst_size, slave_count, primary_port;
4409
4410 burst_size = 21;
4411
4412 memset(pkt_burst, 0, sizeof(pkt_burst));
4413
4414
4415
4416 /* Initialize bonded device with 4 slaves in round robin mode */
4417 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
4418 BONDING_MODE_TLB, 0,
4419 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1),
4420 "Failed to initialize bonded device with slaves");
4421
4422 /* Verify Current Slaves Count /Active Slave Count is */
4423 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
4424 RTE_MAX_ETHPORTS);
4425 TEST_ASSERT_EQUAL(slave_count, 4,
4426 "Number of slaves (%d) is not as expected (%d).\n",
4427 slave_count, 4);
4428
4429 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
4430 slaves, RTE_MAX_ETHPORTS);
4431 TEST_ASSERT_EQUAL(slave_count, (int)4,
4432 "Number of slaves (%d) is not as expected (%d).\n",
4433 slave_count, 4);
4434
4435 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4436 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
4437 "Primary port not as expected");
4438
4439 /* Bring 2 slaves down and verify active slave count */
4440 virtual_ethdev_simulate_link_status_interrupt(
4441 test_params->slave_port_ids[1], 0);
4442 virtual_ethdev_simulate_link_status_interrupt(
4443 test_params->slave_port_ids[3], 0);
4444
4445 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4446 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
4447 "Number of active slaves (%d) is not as expected (%d).",
4448 slave_count, 2);
4449
4450 virtual_ethdev_simulate_link_status_interrupt(
4451 test_params->slave_port_ids[1], 1);
4452 virtual_ethdev_simulate_link_status_interrupt(
4453 test_params->slave_port_ids[3], 1);
4454
4455
4456 /* Bring primary port down, verify that active slave count is 3 and primary
4457 * has changed */
4458 virtual_ethdev_simulate_link_status_interrupt(
4459 test_params->slave_port_ids[0], 0);
4460
4461 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
4462 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3,
4463 "Number of active slaves (%d) is not as expected (%d).",
4464 slave_count, 3);
4465
4466 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
4467 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
4468 "Primary port not as expected");
4469 rte_delay_us(500000);
4470 /* Verify that pkts are sent on new primary slave */
4471 for (i = 0; i < 4; i++) {
4472 TEST_ASSERT_EQUAL(generate_test_burst(
4473 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
4474 "generate_test_burst failed\n");
4475 TEST_ASSERT_EQUAL(rte_eth_tx_burst(
4476 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size,
4477 "rte_eth_tx_burst failed\n");
4478 rte_delay_us(11000);
4479 }
4480
4481 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
4482 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0,
4483 "(%d) port_stats.opackets not as expected\n",
4484 test_params->slave_port_ids[0]);
4485
4486 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
4487 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4488 "(%d) port_stats.opackets not as expected\n",
4489 test_params->slave_port_ids[1]);
4490
4491 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
4492 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4493 "(%d) port_stats.opackets not as expected\n",
4494 test_params->slave_port_ids[2]);
4495
4496 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
4497 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0,
4498 "(%d) port_stats.opackets not as expected\n",
4499 test_params->slave_port_ids[3]);
4500
4501
4502 /* Generate packet burst for testing */
4503
4504 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4505 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) !=
4506 burst_size)
4507 return -1;
4508
4509 virtual_ethdev_add_mbufs_to_rx_queue(
4510 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
4511 }
4512
4513 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
4514 MAX_PKT_BURST) != burst_size) {
4515 printf("rte_eth_rx_burst\n");
4516 return -1;
4517
4518 }
4519
4520 /* Verify bonded device rx count */
4521 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
4522 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
4523 "(%d) port_stats.ipackets not as expected\n",
4524 test_params->bonded_port_id);
4525
4526 /* free mbufs */
4527
4528 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) {
4529 for (j = 0; j < MAX_PKT_BURST; j++) {
4530 if (pkt_burst[i][j] != NULL) {
4531 rte_pktmbuf_free(pkt_burst[i][j]);
4532 pkt_burst[i][j] = NULL;
4533 }
4534 }
4535 }
4536
4537
4538 /* Clean up and remove slaves from bonded device */
4539 return remove_slaves_and_stop_bonded_device();
4540 }
4541
4542 #define TEST_ALB_SLAVE_COUNT 2
4543
4544 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1};
4545 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2};
4546 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3};
4547 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4};
4548
4549 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0);
4550 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1);
4551 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2);
4552 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3);
4553 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4);
4554
4555 static int
4556 test_alb_change_mac_in_reply_sent(void)
4557 {
4558 struct rte_mbuf *pkt;
4559 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4560
4561 struct ether_hdr *eth_pkt;
4562 struct arp_hdr *arp_pkt;
4563
4564 int slave_idx, nb_pkts, pkt_idx;
4565 int retval = 0;
4566
4567 struct ether_addr bond_mac, client_mac;
4568 struct ether_addr *slave_mac1, *slave_mac2;
4569
4570 TEST_ASSERT_SUCCESS(
4571 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4572 0, TEST_ALB_SLAVE_COUNT, 1),
4573 "Failed to initialize_bonded_device_with_slaves.");
4574
4575 /* Flush tx queue */
4576 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4577 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count;
4578 slave_idx++) {
4579 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4580 test_params->slave_port_ids[slave_idx], pkts_sent,
4581 MAX_PKT_BURST);
4582 }
4583
4584 ether_addr_copy(
4585 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4586 &bond_mac);
4587
4588 /*
4589 * Generating four packets with different mac and ip addresses and sending
4590 * them through the bonding port.
4591 */
4592 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4593 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4594 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4595 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4596 0);
4597 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4598 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1,
4599 ARP_OP_REPLY);
4600 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4601
4602 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4603 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4604 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4605 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4606 0);
4607 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4608 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2,
4609 ARP_OP_REPLY);
4610 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4611
4612 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4613 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4614 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4615 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4616 0);
4617 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4618 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3,
4619 ARP_OP_REPLY);
4620 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4621
4622 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4623 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4624 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4625 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4626 0);
4627 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4628 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4,
4629 ARP_OP_REPLY);
4630 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1);
4631
4632 slave_mac1 =
4633 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4634 slave_mac2 =
4635 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4636
4637 /*
4638 * Checking if packets are properly distributed on bonding ports. Packets
4639 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1.
4640 */
4641 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4642 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4643 test_params->slave_port_ids[slave_idx], pkts_sent,
4644 MAX_PKT_BURST);
4645
4646 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4647 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4648 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4649
4650 if (slave_idx%2 == 0) {
4651 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4652 retval = -1;
4653 goto test_end;
4654 }
4655 } else {
4656 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4657 retval = -1;
4658 goto test_end;
4659 }
4660 }
4661 }
4662 }
4663
4664 test_end:
4665 retval += remove_slaves_and_stop_bonded_device();
4666 return retval;
4667 }
4668
4669 static int
4670 test_alb_reply_from_client(void)
4671 {
4672 struct ether_hdr *eth_pkt;
4673 struct arp_hdr *arp_pkt;
4674
4675 struct rte_mbuf *pkt;
4676 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4677
4678 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0;
4679 int retval = 0;
4680
4681 struct ether_addr bond_mac, client_mac;
4682 struct ether_addr *slave_mac1, *slave_mac2;
4683
4684 TEST_ASSERT_SUCCESS(
4685 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4686 0, TEST_ALB_SLAVE_COUNT, 1),
4687 "Failed to initialize_bonded_device_with_slaves.");
4688
4689 /* Flush tx queue */
4690 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4691 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4692 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4693 test_params->slave_port_ids[slave_idx], pkts_sent,
4694 MAX_PKT_BURST);
4695 }
4696
4697 ether_addr_copy(
4698 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4699 &bond_mac);
4700
4701 /*
4702 * Generating four packets with different mac and ip addresses and placing
4703 * them in the rx queue to be received by the bonding driver on rx_burst.
4704 */
4705 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4706 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4707 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4708 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4709 0);
4710 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4711 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4712 ARP_OP_REPLY);
4713 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4714 1);
4715
4716 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4717 memcpy(client_mac.addr_bytes, mac_client2, ETHER_ADDR_LEN);
4718 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4719 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4720 0);
4721 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4722 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host,
4723 ARP_OP_REPLY);
4724 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4725 1);
4726
4727 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4728 memcpy(client_mac.addr_bytes, mac_client3, ETHER_ADDR_LEN);
4729 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4730 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4731 0);
4732 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4733 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host,
4734 ARP_OP_REPLY);
4735 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4736 1);
4737
4738 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4739 memcpy(client_mac.addr_bytes, mac_client4, ETHER_ADDR_LEN);
4740 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4741 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_ARP, 0,
4742 0);
4743 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4744 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host,
4745 ARP_OP_REPLY);
4746 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4747 1);
4748
4749 /*
4750 * Issue rx_burst and tx_burst to force bonding driver to send update ARP
4751 * packets to every client in alb table.
4752 */
4753 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4754 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4755
4756 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs;
4757 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs;
4758
4759 /*
4760 * Checking if update ARP packets were properly send on slave ports.
4761 */
4762 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4763 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4764 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST);
4765 nb_pkts_sum += nb_pkts;
4766
4767 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4768 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4769 arp_pkt = (struct arp_hdr *)((char *)eth_pkt + sizeof(struct ether_hdr));
4770
4771 if (slave_idx%2 == 0) {
4772 if (!is_same_ether_addr(slave_mac1, &arp_pkt->arp_data.arp_sha)) {
4773 retval = -1;
4774 goto test_end;
4775 }
4776 } else {
4777 if (!is_same_ether_addr(slave_mac2, &arp_pkt->arp_data.arp_sha)) {
4778 retval = -1;
4779 goto test_end;
4780 }
4781 }
4782 }
4783 }
4784
4785 /* Check if proper number of packets was send */
4786 if (nb_pkts_sum < 4) {
4787 retval = -1;
4788 goto test_end;
4789 }
4790
4791 test_end:
4792 retval += remove_slaves_and_stop_bonded_device();
4793 return retval;
4794 }
4795
4796 static int
4797 test_alb_receive_vlan_reply(void)
4798 {
4799 struct ether_hdr *eth_pkt;
4800 struct vlan_hdr *vlan_pkt;
4801 struct arp_hdr *arp_pkt;
4802
4803 struct rte_mbuf *pkt;
4804 struct rte_mbuf *pkts_sent[MAX_PKT_BURST];
4805
4806 int slave_idx, nb_pkts, pkt_idx;
4807 int retval = 0;
4808
4809 struct ether_addr bond_mac, client_mac;
4810
4811 TEST_ASSERT_SUCCESS(
4812 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4813 0, TEST_ALB_SLAVE_COUNT, 1),
4814 "Failed to initialize_bonded_device_with_slaves.");
4815
4816 /* Flush tx queue */
4817 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4818 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4819 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4820 test_params->slave_port_ids[slave_idx], pkts_sent,
4821 MAX_PKT_BURST);
4822 }
4823
4824 ether_addr_copy(
4825 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs,
4826 &bond_mac);
4827
4828 /*
4829 * Generating packet with double VLAN header and placing it in the rx queue.
4830 */
4831 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool);
4832 memcpy(client_mac.addr_bytes, mac_client1, ETHER_ADDR_LEN);
4833 eth_pkt = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
4834 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, ETHER_TYPE_VLAN, 0,
4835 0);
4836 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4837 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1);
4838 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
4839 vlan_pkt = vlan_pkt+1;
4840 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2);
4841 vlan_pkt->eth_proto = rte_cpu_to_be_16(ETHER_TYPE_ARP);
4842 arp_pkt = (struct arp_hdr *)((char *)(vlan_pkt + 1));
4843 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host,
4844 ARP_OP_REPLY);
4845 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt,
4846 1);
4847
4848 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST);
4849 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0);
4850
4851 /*
4852 * Checking if VLAN headers in generated ARP Update packet are correct.
4853 */
4854 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) {
4855 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue(
4856 test_params->slave_port_ids[slave_idx], pkts_sent,
4857 MAX_PKT_BURST);
4858
4859 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) {
4860 eth_pkt = rte_pktmbuf_mtod(pkts_sent[pkt_idx], struct ether_hdr *);
4861 vlan_pkt = (struct vlan_hdr *)((char *)(eth_pkt + 1));
4862 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) {
4863 retval = -1;
4864 goto test_end;
4865 }
4866 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
4867 retval = -1;
4868 goto test_end;
4869 }
4870 vlan_pkt = vlan_pkt+1;
4871 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) {
4872 retval = -1;
4873 goto test_end;
4874 }
4875 if (vlan_pkt->eth_proto != rte_cpu_to_be_16(ETHER_TYPE_ARP)) {
4876 retval = -1;
4877 goto test_end;
4878 }
4879 }
4880 }
4881
4882 test_end:
4883 retval += remove_slaves_and_stop_bonded_device();
4884 return retval;
4885 }
4886
4887 static int
4888 test_alb_ipv4_tx(void)
4889 {
4890 int burst_size, retval, pkts_send;
4891 struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
4892
4893 retval = 0;
4894
4895 TEST_ASSERT_SUCCESS(
4896 initialize_bonded_device_with_slaves(BONDING_MODE_ALB,
4897 0, TEST_ALB_SLAVE_COUNT, 1),
4898 "Failed to initialize_bonded_device_with_slaves.");
4899
4900 burst_size = 32;
4901
4902 /* Generate test bursts of packets to transmit */
4903 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) {
4904 retval = -1;
4905 goto test_end;
4906 }
4907
4908 /*
4909 * Checking if ipv4 traffic is transmitted via TLB policy.
4910 */
4911 pkts_send = rte_eth_tx_burst(
4912 test_params->bonded_port_id, 0, pkt_burst, burst_size);
4913 if (pkts_send != burst_size) {
4914 retval = -1;
4915 goto test_end;
4916 }
4917
4918 test_end:
4919 retval += remove_slaves_and_stop_bonded_device();
4920 return retval;
4921 }
4922
4923 static struct unit_test_suite link_bonding_test_suite = {
4924 .suite_name = "Link Bonding Unit Test Suite",
4925 .setup = test_setup,
4926 .teardown = testsuite_teardown,
4927 .unit_test_cases = {
4928 TEST_CASE(test_create_bonded_device),
4929 TEST_CASE(test_create_bonded_device_with_invalid_params),
4930 TEST_CASE(test_add_slave_to_bonded_device),
4931 TEST_CASE(test_add_slave_to_invalid_bonded_device),
4932 TEST_CASE(test_remove_slave_from_bonded_device),
4933 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
4934 TEST_CASE(test_get_slaves_from_bonded_device),
4935 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
4936 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
4937 TEST_CASE(test_start_bonded_device),
4938 TEST_CASE(test_stop_bonded_device),
4939 TEST_CASE(test_set_bonding_mode),
4940 TEST_CASE(test_set_primary_slave),
4941 TEST_CASE(test_set_explicit_bonded_mac),
4942 TEST_CASE(test_set_bonded_port_initialization_mac_assignment),
4943 TEST_CASE(test_status_interrupt),
4944 TEST_CASE(test_adding_slave_after_bonded_device_started),
4945 TEST_CASE(test_roundrobin_tx_burst),
4946 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
4947 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
4948 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
4949 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
4950 TEST_CASE(test_roundrobin_verify_mac_assignment),
4951 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
4952 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
4953 TEST_CASE(test_activebackup_tx_burst),
4954 TEST_CASE(test_activebackup_rx_burst),
4955 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
4956 TEST_CASE(test_activebackup_verify_mac_assignment),
4957 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
4958 TEST_CASE(test_balance_xmit_policy_configuration),
4959 TEST_CASE(test_balance_l2_tx_burst),
4960 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
4961 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
4962 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
4963 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
4964 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
4965 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
4966 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
4967 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
4968 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
4969 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
4970 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
4971 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
4972 TEST_CASE(test_balance_rx_burst),
4973 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
4974 TEST_CASE(test_balance_verify_mac_assignment),
4975 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
4976 TEST_CASE(test_tlb_tx_burst),
4977 TEST_CASE(test_tlb_rx_burst),
4978 TEST_CASE(test_tlb_verify_mac_assignment),
4979 TEST_CASE(test_tlb_verify_promiscuous_enable_disable),
4980 TEST_CASE(test_tlb_verify_slave_link_status_change_failover),
4981 TEST_CASE(test_alb_change_mac_in_reply_sent),
4982 TEST_CASE(test_alb_reply_from_client),
4983 TEST_CASE(test_alb_receive_vlan_reply),
4984 TEST_CASE(test_alb_ipv4_tx),
4985 TEST_CASE(test_broadcast_tx_burst),
4986 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
4987 TEST_CASE(test_broadcast_rx_burst),
4988 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
4989 TEST_CASE(test_broadcast_verify_mac_assignment),
4990 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
4991 TEST_CASE(test_reconfigure_bonded_device),
4992 TEST_CASE(test_close_bonded_device),
4993
4994 TEST_CASES_END() /**< NULL terminate unit test array */
4995 }
4996 };
4997
4998
4999 static int
5000 test_link_bonding(void)
5001 {
5002 return unit_test_suite_runner(&link_bonding_test_suite);
5003 }
5004
5005 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding);