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