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