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