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