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