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