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