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