app/test: refactor bonding checks with macros
[dpdk.git] / app / test / test_link_bonding.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "unistd.h"
35 #include <string.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdint.h>
40 #include <inttypes.h>
41 #include <errno.h>
42 #include <sys/queue.h>
43 #include <sys/time.h>
44
45 #include <rte_byteorder.h>
46 #include <rte_common.h>
47 #include <rte_debug.h>
48 #include <rte_ethdev.h>
49 #include <rte_log.h>
50 #include <rte_lcore.h>
51 #include <rte_memory.h>
52 #include <rte_string_fns.h>
53 #include <rte_eth_bond.h>
54
55 #include "virtual_pmd.h"
56 #include "packet_burst_generator.h"
57
58 #include "test.h"
59
60 #define TEST_MAX_NUMBER_OF_PORTS (16)
61
62 #define RX_RING_SIZE 128
63 #define RX_FREE_THRESH 32
64 #define RX_PTHRESH 8
65 #define RX_HTHRESH 8
66 #define RX_WTHRESH 0
67
68 #define TX_RING_SIZE 512
69 #define TX_FREE_THRESH 32
70 #define TX_PTHRESH 32
71 #define TX_HTHRESH 0
72 #define TX_WTHRESH 0
73 #define TX_RSBIT_THRESH 32
74 #define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\
75         ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \
76         ETH_TXQ_FLAGS_NOXSUMTCP)
77
78 #define MBUF_PAYLOAD_SIZE       (2048)
79 #define MBUF_SIZE (MBUF_PAYLOAD_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
80 #define MBUF_CACHE_SIZE (250)
81 #define BURST_SIZE (32)
82
83 #define DEFAULT_MBUF_DATA_SIZE  (2048)
84 #define RTE_TEST_RX_DESC_MAX    (2048)
85 #define RTE_TEST_TX_DESC_MAX    (2048)
86 #define MAX_PKT_BURST                   (512)
87 #define DEF_PKT_BURST                   (16)
88
89 #define BONDED_DEV_NAME                 ("unit_test_bonded_device")
90
91 #define INVALID_SOCKET_ID               (-1)
92 #define INVALID_PORT_ID                 (-1)
93 #define INVALID_BONDING_MODE    (-1)
94
95
96 uint8_t slave_mac[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 };
97 uint8_t bonded_mac[] = {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
98
99 struct link_bonding_unittest_params {
100         int8_t bonded_port_id;
101         int8_t slave_port_ids[TEST_MAX_NUMBER_OF_PORTS];
102         uint8_t bonded_slave_count;
103         uint8_t bonding_mode;
104
105         uint16_t nb_rx_q;
106         uint16_t nb_tx_q;
107
108         struct rte_mempool *mbuf_pool;
109
110         struct ether_addr *default_slave_mac;
111         struct ether_addr *default_bonded_mac;
112
113         /* Packet Headers */
114         struct ether_hdr *pkt_eth_hdr;
115         struct ipv4_hdr *pkt_ipv4_hdr;
116         struct ipv6_hdr *pkt_ipv6_hdr;
117         struct udp_hdr *pkt_udp_hdr;
118
119 };
120
121 static struct ipv4_hdr pkt_ipv4_hdr;
122 static struct ipv6_hdr pkt_ipv6_hdr;
123 static struct udp_hdr pkt_udp_hdr;
124
125 static struct link_bonding_unittest_params default_params  = {
126         .bonded_port_id = -1,
127         .slave_port_ids = { -1 },
128         .bonded_slave_count = 0,
129         .bonding_mode = BONDING_MODE_ROUND_ROBIN,
130
131         .nb_rx_q = 1,
132         .nb_tx_q = 1,
133
134         .mbuf_pool = NULL,
135
136         .default_slave_mac = (struct ether_addr *)slave_mac,
137         .default_bonded_mac = (struct ether_addr *)bonded_mac,
138
139         .pkt_eth_hdr = NULL,
140         .pkt_ipv4_hdr = &pkt_ipv4_hdr,
141         .pkt_ipv6_hdr = &pkt_ipv6_hdr,
142         .pkt_udp_hdr = &pkt_udp_hdr
143
144 };
145
146 static struct link_bonding_unittest_params *test_params = &default_params;
147
148 static uint8_t src_mac[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
149 static uint8_t dst_mac_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
150 static uint8_t dst_mac_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAB };
151
152 static uint32_t src_addr = IPV4_ADDR(192, 168, 1, 98);
153 static uint32_t dst_addr_0 = IPV4_ADDR(192, 168, 1, 98);
154 static uint32_t dst_addr_1 = IPV4_ADDR(193, 166, 10, 97);
155
156 static uint8_t src_ipv6_addr[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
157                 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA  };
158 static uint8_t dst_ipv6_addr_0[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
159                 0xAA, 0xFF, 0xAA,  0xFF, 0xAA , 0xFF, 0xAA, 0xFF, 0xAA  };
160 static uint8_t dst_ipv6_addr_1[] = { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
161                 0xAA, 0xFF, 0xAA, 0xFF, 0xAA , 0xFF, 0xAA , 0xFF, 0xAB  };
162
163 static uint16_t src_port = 1024;
164 static uint16_t dst_port_0 = 1024;
165 static uint16_t dst_port_1 = 2024;
166
167 static uint16_t vlan_id = 0x100;
168
169 struct rte_eth_rxmode rx_mode = {
170         .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
171         .split_hdr_size = 0,
172         .header_split   = 0, /**< Header Split disabled. */
173         .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
174         .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
175         .hw_vlan_strip  = 1, /**< VLAN strip enabled. */
176         .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
177         .jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
178         .hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
179 };
180
181 struct rte_fdir_conf fdir_conf = {
182         .mode = RTE_FDIR_MODE_NONE,
183         .pballoc = RTE_FDIR_PBALLOC_64K,
184         .status = RTE_FDIR_REPORT_STATUS,
185         .flexbytes_offset = 0x6,
186         .drop_queue = 127,
187 };
188
189 static struct rte_eth_conf default_pmd_conf = {
190         .rxmode = {
191                 .mq_mode = ETH_MQ_RX_NONE,
192                 .max_rx_pkt_len = ETHER_MAX_LEN,
193                 .split_hdr_size = 0,
194                 .header_split   = 0, /**< Header Split disabled */
195                 .hw_ip_checksum = 0, /**< IP checksum offload enabled */
196                 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
197                 .jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
198                 .hw_strip_crc   = 0, /**< CRC stripped by hardware */
199         },
200         .txmode = {
201                 .mq_mode = ETH_MQ_TX_NONE,
202         },
203         .lpbk_mode = 0,
204 };
205
206 static const struct rte_eth_rxconf rx_conf_default = {
207         .rx_thresh = {
208                 .pthresh = RX_PTHRESH,
209                 .hthresh = RX_HTHRESH,
210                 .wthresh = RX_WTHRESH,
211         },
212         .rx_free_thresh = RX_FREE_THRESH,
213         .rx_drop_en = 0,
214 };
215
216 static struct rte_eth_txconf tx_conf_default = {
217         .tx_thresh = {
218                 .pthresh = TX_PTHRESH,
219                 .hthresh = TX_HTHRESH,
220                 .wthresh = TX_WTHRESH,
221         },
222         .tx_free_thresh = TX_FREE_THRESH,
223         .tx_rs_thresh = TX_RSBIT_THRESH,
224         .txq_flags = TX_Q_FLAGS
225
226 };
227
228 static int
229 configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
230 {
231         int q_id;
232
233         if (en_isr)
234                 default_pmd_conf.intr_conf.lsc = 1;
235         else
236                 default_pmd_conf.intr_conf.lsc = 0;
237
238         TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
239                         test_params->nb_tx_q, &default_pmd_conf),
240                         "rte_eth_dev_configure for port %d failed", port_id);
241
242         for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
243                 TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
244                                 rte_eth_dev_socket_id(port_id), &rx_conf_default,
245                                 test_params->mbuf_pool) ,
246                                 "rte_eth_rx_queue_setup for port %d failed", port_id);
247
248         for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
249                 TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
250                                 rte_eth_dev_socket_id(port_id), &tx_conf_default),
251                                 "rte_eth_tx_queue_setup for port %d failed", port_id);
252
253         if (start)
254                 TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
255                                 "rte_eth_dev_start for port %d failed", port_id);
256
257         return 0;
258 }
259
260 static int slaves_initialized;
261
262 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
263 static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
264
265
266 static int
267 test_setup(void)
268 {
269         int i, nb_mbuf_per_pool;
270         struct ether_addr *mac_addr = (struct ether_addr *)slave_mac;
271
272         /* Allocate ethernet packet header with space for VLAN header */
273         if (test_params->pkt_eth_hdr == NULL) {
274                 test_params->pkt_eth_hdr = malloc(sizeof(struct ether_hdr) +
275                                 sizeof(struct vlan_hdr));
276
277                 TEST_ASSERT_NOT_NULL(test_params->pkt_eth_hdr,
278                                 "Ethernet header struct allocation failed!");
279         }
280
281         nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + DEF_PKT_BURST +
282                         RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
283         if (test_params->mbuf_pool == NULL) {
284                 test_params->mbuf_pool = rte_mempool_create("MBUF_POOL", nb_mbuf_per_pool,
285                                 MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private),
286                                 rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
287                                 rte_socket_id(), 0);
288                 TEST_ASSERT_NOT_NULL(test_params->mbuf_pool,
289                                 "rte_mempool_create failed");
290         }
291
292         /* Create / Initialize virtual eth devs */
293         if (!slaves_initialized) {
294                 for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++) {
295                         char pmd_name[RTE_ETH_NAME_MAX_LEN];
296
297                         mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
298
299                         snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
300
301                         test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
302                                         mac_addr, rte_socket_id(), 1);
303                         TEST_ASSERT(test_params->slave_port_ids[i] >= 0,
304                                         "Failed to create virtual virtual ethdev %s", pmd_name);
305
306                         TEST_ASSERT_SUCCESS(configure_ethdev(
307                                         test_params->slave_port_ids[i], 1, 0),
308                                         "Failed to configure virtual ethdev %s", pmd_name);
309                 }
310                 slaves_initialized = 1;
311         }
312
313         return 0;
314 }
315
316 static int
317 test_create_bonded_device(void)
318 {
319         int current_slave_count;
320
321         uint8_t slaves[RTE_MAX_ETHPORTS];
322
323         /* Don't try to recreate bonded device if re-running test suite*/
324         if (test_params->bonded_port_id == -1) {
325                 test_params->bonded_port_id = rte_eth_bond_create(BONDED_DEV_NAME,
326                                 test_params->bonding_mode, rte_socket_id());
327
328                 TEST_ASSERT(test_params->bonded_port_id >= 0,
329                                 "Failed to create bonded ethdev %s", BONDED_DEV_NAME);
330
331                 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
332                                 "Failed to configure bonded ethdev %s", BONDED_DEV_NAME);
333         }
334
335         TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
336                         test_params->bonding_mode), "Failed to set ethdev %d to mode %d",
337                         test_params->bonded_port_id, test_params->bonding_mode);
338
339         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
340                         slaves, RTE_MAX_ETHPORTS);
341
342         TEST_ASSERT_EQUAL(current_slave_count, 0,
343                         "Number of slaves %d is great than expected %d.",
344                         current_slave_count, 0);
345
346         current_slave_count = rte_eth_bond_active_slaves_get(
347                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
348
349         TEST_ASSERT_EQUAL(current_slave_count, 0,
350                         "Number of active slaves %d is great than expected %d.",
351                         current_slave_count, 0);
352
353         return 0;
354 }
355
356
357 static int
358 test_create_bonded_device_with_invalid_params(void)
359 {
360         int port_id;
361
362         test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
363
364         /* Invalid name */
365         port_id = rte_eth_bond_create(NULL, test_params->bonding_mode,
366                         rte_socket_id());
367         TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly");
368
369         test_params->bonding_mode = INVALID_BONDING_MODE;
370
371         /* Invalid bonding mode */
372         port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
373                         rte_socket_id());
374         TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
375
376         test_params->bonding_mode = BONDING_MODE_ROUND_ROBIN;
377
378         /* Invalid socket id */
379         port_id = rte_eth_bond_create(BONDED_DEV_NAME, test_params->bonding_mode,
380                         INVALID_SOCKET_ID);
381         TEST_ASSERT(port_id < 0, "Created bonded device unexpectedly.");
382
383         return 0;
384 }
385
386 static int
387 test_add_slave_to_bonded_device(void)
388 {
389         int current_slave_count;
390
391         uint8_t slaves[RTE_MAX_ETHPORTS];
392
393         TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
394                         test_params->slave_port_ids[test_params->bonded_slave_count]),
395                         "Failed to add slave (%d) to bonded port (%d).",
396                         test_params->slave_port_ids[test_params->bonded_slave_count],
397                         test_params->bonded_port_id);
398
399         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
400                         slaves, RTE_MAX_ETHPORTS);
401         TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
402                         "Number of slaves (%d) is greater than expected (%d).",
403                         current_slave_count, test_params->bonded_slave_count + 1);
404
405         current_slave_count = rte_eth_bond_active_slaves_get(
406                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
407         TEST_ASSERT_EQUAL(current_slave_count, 0,
408                                         "Number of active slaves (%d) is not as expected (%d).\n",
409                                         current_slave_count, 0);
410
411         test_params->bonded_slave_count++;
412
413         return 0;
414 }
415
416 static int
417 test_add_slave_to_invalid_bonded_device(void)
418 {
419         /* Invalid port ID */
420         TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->bonded_port_id + 5,
421                         test_params->slave_port_ids[test_params->bonded_slave_count]),
422                         "Expected call to failed as invalid port specified.");
423
424         /* Non bonded device */
425         TEST_ASSERT_FAIL(rte_eth_bond_slave_add(test_params->slave_port_ids[0],
426                         test_params->slave_port_ids[test_params->bonded_slave_count]),
427                         "Expected call to failed as invalid port specified.");
428
429         return 0;
430 }
431
432
433 static int
434 test_remove_slave_from_bonded_device(void)
435 {
436         int current_slave_count;
437         struct ether_addr read_mac_addr, *mac_addr;
438         uint8_t slaves[RTE_MAX_ETHPORTS];
439
440         TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
441                         test_params->slave_port_ids[test_params->bonded_slave_count-1]),
442                         "Failed to remove slave %d from bonded port (%d).",
443                         test_params->slave_port_ids[test_params->bonded_slave_count-1],
444                         test_params->bonded_port_id);
445
446
447         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
448                         slaves, RTE_MAX_ETHPORTS);
449
450         TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
451                         "Number of slaves (%d) is great than expected (%d).\n",
452                         current_slave_count, test_params->bonded_slave_count - 1);
453
454
455         mac_addr = (struct ether_addr *)slave_mac;
456         mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
457                         test_params->slave_port_ids[test_params->bonded_slave_count-1];
458
459         rte_eth_macaddr_get(
460                         test_params->slave_port_ids[test_params->bonded_slave_count-1],
461                         &read_mac_addr);
462         TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
463                         "bonded port mac address not set to that of primary port\n");
464
465         rte_eth_stats_reset(
466                         test_params->slave_port_ids[test_params->bonded_slave_count-1]);
467
468         virtual_ethdev_simulate_link_status_interrupt(test_params->bonded_port_id,
469                         0);
470
471         test_params->bonded_slave_count--;
472
473         return 0;
474 }
475
476 static int
477 test_remove_slave_from_invalid_bonded_device(void)
478 {
479         /* Invalid port ID */
480         TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
481                         test_params->bonded_port_id + 5,
482                         test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
483                         "Expected call to failed as invalid port specified.");
484
485         /* Non bonded device */
486         TEST_ASSERT_FAIL(rte_eth_bond_slave_remove(
487                         test_params->slave_port_ids[0],
488                         test_params->slave_port_ids[test_params->bonded_slave_count - 1]),
489                         "Expected call to failed as invalid port specified.");
490
491         return 0;
492 }
493
494 static int bonded_id = 2;
495
496 static int
497 test_add_already_bonded_slave_to_bonded_device(void)
498 {
499         int port_id, current_slave_count;
500         uint8_t slaves[RTE_MAX_ETHPORTS];
501         char pmd_name[RTE_ETH_NAME_MAX_LEN];
502
503         test_add_slave_to_bonded_device();
504
505         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
506                         slaves, RTE_MAX_ETHPORTS);
507         TEST_ASSERT_EQUAL(current_slave_count, 1,
508                         "Number of slaves (%d) is not that expected (%d).",
509                         current_slave_count, 1);
510
511         snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "%s_%d", BONDED_DEV_NAME, ++bonded_id);
512
513         port_id = rte_eth_bond_create(pmd_name, test_params->bonding_mode,
514                         rte_socket_id());
515         TEST_ASSERT(port_id >= 0, "Failed to create bonded device.");
516
517         TEST_ASSERT(rte_eth_bond_slave_add(port_id,
518                         test_params->slave_port_ids[test_params->bonded_slave_count - 1])
519                         < 0,
520                         "Added slave (%d) to bonded port (%d) unexpectedly.",
521                         test_params->slave_port_ids[test_params->bonded_slave_count-1],
522                         port_id);
523
524         return test_remove_slave_from_bonded_device();
525 }
526
527
528 static int
529 test_get_slaves_from_bonded_device(void)
530 {
531         int current_slave_count;
532         uint8_t slaves[RTE_MAX_ETHPORTS];
533
534         TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
535                         "Failed to add slave to bonded device");
536
537         /* Invalid port id */
538         current_slave_count = rte_eth_bond_slaves_get(INVALID_PORT_ID, slaves,
539                         RTE_MAX_ETHPORTS);
540         TEST_ASSERT(current_slave_count < 0,
541                         "Invalid port id unexpectedly succeeded");
542
543         current_slave_count = rte_eth_bond_active_slaves_get(INVALID_PORT_ID,
544                         slaves, RTE_MAX_ETHPORTS);
545         TEST_ASSERT(current_slave_count < 0,
546                         "Invalid port id unexpectedly succeeded");
547
548         /* Invalid slaves pointer */
549         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
550                         NULL, RTE_MAX_ETHPORTS);
551         TEST_ASSERT(current_slave_count < 0,
552                         "Invalid slave array unexpectedly succeeded");
553
554         current_slave_count = rte_eth_bond_active_slaves_get(
555                         test_params->bonded_port_id, NULL, RTE_MAX_ETHPORTS);
556         TEST_ASSERT(current_slave_count < 0,
557                         "Invalid slave array unexpectedly succeeded");
558
559         /* non bonded device*/
560         current_slave_count = rte_eth_bond_slaves_get(
561                         test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
562         TEST_ASSERT(current_slave_count < 0,
563                         "Invalid port id unexpectedly succeeded");
564
565         current_slave_count = rte_eth_bond_active_slaves_get(
566                         test_params->slave_port_ids[0], NULL, RTE_MAX_ETHPORTS);
567         TEST_ASSERT(current_slave_count < 0,
568                         "Invalid port id unexpectedly succeeded");
569
570         TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
571                         "Failed to remove slaves from bonded device");
572
573         return 0;
574 }
575
576
577 static int
578 test_add_remove_multiple_slaves_to_from_bonded_device(void)
579 {
580         int i;
581
582         for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
583                 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
584                                 "Failed to add slave to bonded device");
585
586         for (i = 0; i < TEST_MAX_NUMBER_OF_PORTS; i++)
587                 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
588                                 "Failed to remove slaves from bonded device");
589
590         return 0;
591 }
592
593 static void
594 enable_bonded_slaves(void)
595 {
596         int i;
597
598         for (i = 0; i < test_params->bonded_slave_count; i++) {
599                 virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
600                                 1);
601
602                 virtual_ethdev_simulate_link_status_interrupt(
603                                 test_params->slave_port_ids[i], 1);
604         }
605 }
606
607 static int
608 test_start_bonded_device(void)
609 {
610         struct rte_eth_link link_status;
611
612         int current_slave_count, current_bonding_mode, primary_port;
613         uint8_t slaves[RTE_MAX_ETHPORTS];
614
615         /* Add slave to bonded device*/
616         TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
617                         "Failed to add slave to bonded device");
618
619         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
620                 "Failed to start bonded pmd eth device %d.",
621                 test_params->bonded_port_id);
622
623         /* Change link status of virtual pmd so it will be added to the active
624          * slave list of the bonded device*/
625         virtual_ethdev_simulate_link_status_interrupt(
626                         test_params->slave_port_ids[test_params->bonded_slave_count-1], 1);
627
628         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
629                         slaves, RTE_MAX_ETHPORTS);
630         TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
631                         "Number of slaves (%d) is not expected value (%d).",
632                         current_slave_count, test_params->bonded_slave_count);
633
634         current_slave_count = rte_eth_bond_active_slaves_get(
635                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
636         TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
637                         "Number of active slaves (%d) is not expected value (%d).",
638                         current_slave_count, test_params->bonded_slave_count);
639
640         current_bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
641         TEST_ASSERT_EQUAL(current_bonding_mode, test_params->bonding_mode,
642                         "Bonded device mode (%d) is not expected value (%d).\n",
643                         current_bonding_mode, test_params->bonding_mode);
644
645         primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
646         TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
647                         "Primary port (%d) is not expected value (%d).",
648                         primary_port, test_params->slave_port_ids[0]);
649
650         rte_eth_link_get(test_params->bonded_port_id, &link_status);
651         TEST_ASSERT_EQUAL(link_status.link_status, 1,
652                         "Bonded port (%d) status (%d) is not expected value (%d).\n",
653                         test_params->bonded_port_id, link_status.link_status, 1);
654
655         return 0;
656 }
657
658 static int
659 test_stop_bonded_device(void)
660 {
661         int current_slave_count;
662         uint8_t slaves[RTE_MAX_ETHPORTS];
663
664         struct rte_eth_link link_status;
665
666         rte_eth_dev_stop(test_params->bonded_port_id);
667
668         rte_eth_link_get(test_params->bonded_port_id, &link_status);
669         TEST_ASSERT_EQUAL(link_status.link_status, 0,
670                         "Bonded port (%d) status (%d) is not expected value (%d).",
671                         test_params->bonded_port_id, link_status.link_status, 0);
672
673         current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
674                         slaves, RTE_MAX_ETHPORTS);
675         TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count,
676                         "Number of slaves (%d) is not expected value (%d).",
677                         current_slave_count, test_params->bonded_slave_count);
678
679         current_slave_count = rte_eth_bond_active_slaves_get(
680                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
681         TEST_ASSERT_EQUAL(current_slave_count, 0,
682                         "Number of active slaves (%d) is not expected value (%d).",
683                         current_slave_count, 0);
684
685         return 0;
686 }
687
688 static int
689 remove_slaves_and_stop_bonded_device(void)
690 {
691         /* Clean up and remove slaves from bonded device */
692         while (test_params->bonded_slave_count > 0)
693                 TEST_ASSERT_SUCCESS(test_remove_slave_from_bonded_device(),
694                                 "test_remove_slave_from_bonded_device failed");
695
696         rte_eth_dev_stop(test_params->bonded_port_id);
697         rte_eth_stats_reset(test_params->bonded_port_id);
698         rte_eth_bond_mac_address_reset(test_params->bonded_port_id);
699
700         return 0;
701 }
702
703 static int
704 test_set_bonding_mode(void)
705 {
706         int i, bonding_mode;
707
708         int bonding_modes[] = { BONDING_MODE_ROUND_ROBIN,
709                                                         BONDING_MODE_ACTIVE_BACKUP,
710                                                         BONDING_MODE_BALANCE,
711 #ifdef RTE_MBUF_REFCNT
712                                                         BONDING_MODE_BROADCAST
713 #endif
714                                                         };
715
716         /* Test supported link bonding modes */
717         for (i = 0; i < (int)RTE_DIM(bonding_modes);    i++) {
718                 /* Invalid port ID */
719                 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(INVALID_PORT_ID,
720                                 bonding_modes[i]),
721                                 "Expected call to failed as invalid port (%d) specified.",
722                                 INVALID_PORT_ID);
723
724                 /* Non bonded device */
725                 TEST_ASSERT_FAIL(rte_eth_bond_mode_set(test_params->slave_port_ids[0],
726                                 bonding_modes[i]),
727                                 "Expected call to failed as invalid port (%d) specified.",
728                                 test_params->slave_port_ids[0]);
729
730                 TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
731                                 bonding_modes[i]),
732                                 "Failed to set link bonding mode on port (%d) to (%d).",
733                                 test_params->bonded_port_id, bonding_modes[i]);
734
735                 bonding_mode = rte_eth_bond_mode_get(test_params->bonded_port_id);
736                 TEST_ASSERT_EQUAL(bonding_mode, bonding_modes[i],
737                                 "Link bonding mode (%d) of port (%d) is not expected value (%d).",
738                                 bonding_mode, test_params->bonded_port_id,
739                                 bonding_modes[i]);
740
741                 /* Invalid port ID */
742                 bonding_mode = rte_eth_bond_mode_get(INVALID_PORT_ID);
743                 TEST_ASSERT(bonding_mode < 0,
744                                 "Expected call to failed as invalid port (%d) specified.",
745                                 INVALID_PORT_ID);
746
747                 /* Non bonded device */
748                 bonding_mode = rte_eth_bond_mode_get(test_params->slave_port_ids[0]);
749                 TEST_ASSERT(bonding_mode < 0,
750                                 "Expected call to failed as invalid port (%d) specified.",
751                                 test_params->slave_port_ids[0]);
752         }
753
754         return remove_slaves_and_stop_bonded_device();
755 }
756
757 static int
758 test_set_primary_slave(void)
759 {
760         int i, j, retval;
761         struct ether_addr read_mac_addr;
762         struct ether_addr *expected_mac_addr;
763
764         /* Add 4 slaves to bonded device */
765         for (i = test_params->bonded_slave_count; i < 4; i++)
766                 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
767                                 "Failed to add slave to bonded device.");
768
769         TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
770                         BONDING_MODE_ROUND_ROBIN),
771                         "Failed to set link bonding mode on port (%d) to (%d).",
772                         test_params->bonded_port_id, BONDING_MODE_ROUND_ROBIN);
773
774         /* Invalid port ID */
775         TEST_ASSERT_FAIL(rte_eth_bond_primary_set(INVALID_PORT_ID,
776                         test_params->slave_port_ids[i]),
777                         "Expected call to failed as invalid port specified.");
778
779         /* Non bonded device */
780         TEST_ASSERT_FAIL(rte_eth_bond_primary_set(test_params->slave_port_ids[i],
781                         test_params->slave_port_ids[i]),
782                         "Expected call to failed as invalid port specified.");
783
784         /* Set slave as primary
785          * Verify slave it is now primary slave
786          * Verify that MAC address of bonded device is that of primary slave
787          * Verify that MAC address of all bonded slaves are that of primary slave
788          */
789         for (i = 0; i < 4; i++) {
790                 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
791                                 test_params->slave_port_ids[i]),
792                                 "Failed to set bonded port (%d) primary port to (%d)",
793                                 test_params->bonded_port_id, test_params->slave_port_ids[i]);
794
795                 retval = rte_eth_bond_primary_get(test_params->bonded_port_id);
796                 TEST_ASSERT(retval >= 0,
797                                 "Failed to read primary port from bonded port (%d)\n",
798                                         test_params->bonded_port_id);
799
800                 TEST_ASSERT_EQUAL(retval, test_params->slave_port_ids[i],
801                                 "Bonded port (%d) primary port (%d) not expected value (%d)\n",
802                                 test_params->bonded_port_id, retval,
803                                 test_params->slave_port_ids[i]);
804
805                 /* stop/start bonded eth dev to apply new MAC */
806                 rte_eth_dev_stop(test_params->bonded_port_id);
807
808                 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
809                                 "Failed to start bonded port %d",
810                                 test_params->bonded_port_id);
811
812                 expected_mac_addr = (struct ether_addr *)&slave_mac;
813                 expected_mac_addr->addr_bytes[ETHER_ADDR_LEN-1] =
814                                 test_params->slave_port_ids[i];
815
816                 /* Check primary slave MAC */
817                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
818                 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
819                                 sizeof(read_mac_addr)),
820                                 "bonded port mac address not set to that of primary port\n");
821
822                 /* Check bonded MAC */
823                 rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
824                 TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
825                                 sizeof(read_mac_addr)),
826                                 "bonded port mac address not set to that of primary port\n");
827
828                 /* Check other slaves MACs */
829                 for (j = 0; j < 4; j++) {
830                         if (j != i) {
831                                 rte_eth_macaddr_get(test_params->slave_port_ids[j],
832                                                 &read_mac_addr);
833                                 TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
834                                                 sizeof(read_mac_addr)),
835                                                 "slave port mac address not set to that of primary "
836                                                 "port");
837                         }
838                 }
839         }
840
841
842         /* Test with none existent port */
843         TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->bonded_port_id + 10),
844                         "read primary port from expectedly");
845
846         /* Test with slave port */
847         TEST_ASSERT_FAIL(rte_eth_bond_primary_get(test_params->slave_port_ids[0]),
848                         "read primary port from expectedly\n");
849
850         TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
851                         "Failed to stop and remove slaves from bonded device");
852
853         /* No slaves  */
854         TEST_ASSERT(rte_eth_bond_primary_get(test_params->bonded_port_id)  < 0,
855                         "read primary port from expectedly\n");
856
857         return 0;
858 }
859
860 static int
861 test_set_explicit_bonded_mac(void)
862 {
863         int i;
864         struct ether_addr read_mac_addr;
865         struct ether_addr *mac_addr;
866
867         uint8_t explicit_bonded_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01 };
868
869         mac_addr = (struct ether_addr *)explicit_bonded_mac;
870
871         /* Invalid port ID */
872         TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(INVALID_PORT_ID, mac_addr),
873                         "Expected call to failed as invalid port specified.");
874
875         /* Non bonded device */
876         TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
877                         test_params->slave_port_ids[0], mac_addr),
878                         "Expected call to failed as invalid port specified.");
879
880         /* NULL MAC address */
881         TEST_ASSERT_FAIL(rte_eth_bond_mac_address_set(
882                         test_params->bonded_port_id, NULL),
883                         "Expected call to failed as NULL MAC specified");
884
885         TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
886                         test_params->bonded_port_id, mac_addr),
887                         "Failed to set MAC address on bonded port (%d)",
888                         test_params->bonded_port_id);
889
890         /* Add 4 slaves to bonded device */
891         for (i = test_params->bonded_slave_count; i < 4; i++) {
892                 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
893                                 "Failed to add slave to bonded device.\n");
894         }
895
896         /* Check bonded MAC */
897         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
898         TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
899                         "bonded port mac address not set to that of primary port");
900
901         /* Check other slaves MACs */
902         for (i = 0; i < 4; i++) {
903                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
904                 TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr,
905                                 sizeof(read_mac_addr)),
906                                 "slave port mac address not set to that of primary port");
907         }
908
909         /* test resetting mac address on bonded device */
910         TEST_ASSERT_SUCCESS(
911                         rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
912                         "Failed to reset MAC address on bonded port (%d)",
913                         test_params->bonded_port_id);
914
915         TEST_ASSERT_FAIL(
916                         rte_eth_bond_mac_address_reset(test_params->slave_port_ids[0]),
917                         "Reset MAC address on bonded port (%d) unexpectedly",
918                         test_params->slave_port_ids[1]);
919
920         /* test resetting mac address on bonded device with no slaves */
921         TEST_ASSERT_SUCCESS(remove_slaves_and_stop_bonded_device(),
922                         "Failed to remove slaves and stop bonded device");
923
924         TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_reset(test_params->bonded_port_id),
925                         "Failed to reset MAC address on bonded port (%d)",
926                                 test_params->bonded_port_id);
927
928         return 0;
929 }
930
931
932 static int
933 initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
934                 uint8_t number_of_slaves, uint8_t enable_slave)
935 {
936         /* Configure bonded device */
937         TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
938                         bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
939                         "with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
940                         number_of_slaves);
941
942         /* Add slaves to bonded device */
943         while (number_of_slaves > test_params->bonded_slave_count)
944                 TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
945                                 "Failed to add slave (%d to  bonding port (%d).",
946                                 test_params->bonded_slave_count - 1,
947                                 test_params->bonded_port_id);
948
949         /* Set link bonding mode  */
950         TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
951                         bonding_mode),
952                         "Failed to set link bonding mode on port (%d) to (%d).",
953                         test_params->bonded_port_id, bonding_mode);
954
955         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
956                 "Failed to start bonded pmd eth device %d.",
957                 test_params->bonded_port_id);
958
959         if (enable_slave)
960                 enable_bonded_slaves();
961
962         return 0;
963 }
964
965 static int
966 test_adding_slave_after_bonded_device_started(void)
967 {
968         int i;
969
970         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
971                         BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
972                         "Failed to add slaves to bonded device");
973
974         /* Enabled slave devices */
975         for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
976                 virtual_ethdev_simulate_link_status_interrupt(
977                                 test_params->slave_port_ids[i], 1);
978         }
979
980         TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
981                         test_params->slave_port_ids[test_params->bonded_slave_count]),
982                         "Failed to add slave to bonded port.\n");
983
984         rte_eth_stats_reset(
985                         test_params->slave_port_ids[test_params->bonded_slave_count]);
986
987         test_params->bonded_slave_count++;
988
989         return remove_slaves_and_stop_bonded_device();
990 }
991
992 #define TEST_STATUS_INTERRUPT_SLAVE_COUNT       4
993 #define TEST_LSC_WAIT_TIMEOUT_MS        500
994
995 int test_lsc_interrupt_count;
996
997
998 static void
999 test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
1000                 enum rte_eth_event_type type  __rte_unused, void *param __rte_unused)
1001 {
1002         pthread_mutex_lock(&mutex);
1003         test_lsc_interrupt_count++;
1004
1005         pthread_cond_signal(&cvar);
1006         pthread_mutex_unlock(&mutex);
1007 }
1008
1009 static inline int
1010 lsc_timeout(int wait_us)
1011 {
1012         int retval = 0;
1013
1014         struct timespec ts;
1015         struct timeval tp;
1016
1017         gettimeofday(&tp, NULL);
1018
1019         /* Convert from timeval to timespec */
1020         ts.tv_sec = tp.tv_sec;
1021         ts.tv_nsec = tp.tv_usec * 1000;
1022         ts.tv_nsec += wait_us * 1000;
1023
1024         pthread_mutex_lock(&mutex);
1025         if (test_lsc_interrupt_count < 1)
1026                 retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
1027
1028         pthread_mutex_unlock(&mutex);
1029
1030         if (retval == 0 && test_lsc_interrupt_count < 1)
1031                 return -1;
1032
1033         return retval;
1034 }
1035
1036 static int
1037 test_status_interrupt(void)
1038 {
1039         int slave_count;
1040         uint8_t slaves[RTE_MAX_ETHPORTS];
1041
1042         /* initialized bonding device with T slaves */
1043         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1044                         BONDING_MODE_ROUND_ROBIN, 1,
1045                         TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1),
1046                         "Failed to initialise bonded device");
1047
1048         test_lsc_interrupt_count = 0;
1049
1050         /* register link status change interrupt callback */
1051         rte_eth_dev_callback_register(test_params->bonded_port_id,
1052                         RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1053                         &test_params->bonded_port_id);
1054
1055         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1056                         slaves, RTE_MAX_ETHPORTS);
1057
1058         TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
1059                         "Number of active slaves (%d) is not as expected (%d)",
1060                         slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
1061
1062         /* Bring all 4 slaves link status to down and test that we have received a
1063          * lsc interrupts */
1064         virtual_ethdev_simulate_link_status_interrupt(
1065                         test_params->slave_port_ids[0], 0);
1066         virtual_ethdev_simulate_link_status_interrupt(
1067                         test_params->slave_port_ids[1], 0);
1068         virtual_ethdev_simulate_link_status_interrupt(
1069                         test_params->slave_port_ids[2], 0);
1070
1071         TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1072                         "Received a link status change interrupt unexpectedly");
1073
1074         virtual_ethdev_simulate_link_status_interrupt(
1075                         test_params->slave_port_ids[3], 0);
1076
1077         TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1078                         "timed out waiting for interrupt");
1079
1080         TEST_ASSERT(test_lsc_interrupt_count > 0,
1081                         "Did not receive link status change interrupt");
1082
1083         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1084                         slaves, RTE_MAX_ETHPORTS);
1085
1086         TEST_ASSERT_EQUAL(slave_count, 0,
1087                         "Number of active slaves (%d) is not as expected (%d)",
1088                         slave_count, 0);
1089
1090         /* bring one slave port up so link status will change */
1091         test_lsc_interrupt_count = 0;
1092
1093         virtual_ethdev_simulate_link_status_interrupt(
1094                         test_params->slave_port_ids[0], 1);
1095
1096         TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
1097                         "timed out waiting for interrupt");
1098
1099         /* test that we have received another lsc interrupt */
1100         TEST_ASSERT(test_lsc_interrupt_count > 0,
1101                         "Did not receive link status change interrupt");
1102
1103         /* Verify that calling the same slave lsc interrupt doesn't cause another
1104          * lsc interrupt from bonded device */
1105         test_lsc_interrupt_count = 0;
1106
1107         virtual_ethdev_simulate_link_status_interrupt(
1108                         test_params->slave_port_ids[0], 1);
1109
1110         TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
1111                         "received unexpected interrupt");
1112
1113         TEST_ASSERT_EQUAL(test_lsc_interrupt_count, 0,
1114                         "Did not receive link status change interrupt");
1115
1116
1117         /* unregister lsc callback before exiting */
1118         rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1119                                 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1120                                 &test_params->bonded_port_id);
1121
1122         /* Clean up and remove slaves from bonded device */
1123         return remove_slaves_and_stop_bonded_device();
1124 }
1125
1126 static int
1127 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
1128                 uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
1129                 uint8_t toggle_ip_addr, uint8_t toggle_udp_port)
1130 {
1131         uint16_t pktlen, generated_burst_size;
1132         void *ip_hdr;
1133
1134         if (toggle_dst_mac)
1135                 initialize_eth_header(test_params->pkt_eth_hdr,
1136                                 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1,
1137                                 vlan, vlan_id);
1138         else
1139                 initialize_eth_header(test_params->pkt_eth_hdr,
1140                                 (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0,
1141                                 vlan, vlan_id);
1142
1143
1144         if (toggle_udp_port)
1145                 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1146                                 dst_port_1, 64);
1147         else
1148                 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1149                                 dst_port_0, 64);
1150
1151         if (ipv4) {
1152                 if (toggle_ip_addr)
1153                         pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1154                                         dst_addr_1, pktlen);
1155                 else
1156                         pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1157                                         dst_addr_0, pktlen);
1158
1159                 ip_hdr = test_params->pkt_ipv4_hdr;
1160         } else {
1161                 if (toggle_ip_addr)
1162                         pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1163                                         (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_1,
1164                                         pktlen);
1165                 else
1166                         pktlen = initialize_ipv6_header(test_params->pkt_ipv6_hdr,
1167                                         (uint8_t *)src_ipv6_addr, (uint8_t *)dst_ipv6_addr_0,
1168                                         pktlen);
1169
1170                 ip_hdr = test_params->pkt_ipv6_hdr;
1171         }
1172
1173         /* Generate burst of packets to transmit */
1174         generated_burst_size = generate_packet_burst(test_params->mbuf_pool,
1175                         pkts_burst,     test_params->pkt_eth_hdr, vlan, ip_hdr, ipv4,
1176                         test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN_128,
1177                         1);
1178         TEST_ASSERT_EQUAL(generated_burst_size, burst_size,
1179                         "Failed to generate packet burst");
1180
1181         return generated_burst_size;
1182 }
1183
1184 /** Round Robin Mode Tests */
1185
1186 static int
1187 test_roundrobin_tx_burst(void)
1188 {
1189         int i, burst_size;
1190         struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1191         struct rte_eth_stats port_stats;
1192
1193         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1194                         BONDING_MODE_ROUND_ROBIN, 0, 2, 1),
1195                         "Failed to intialise bonded device");
1196
1197         burst_size = 20 * test_params->bonded_slave_count;
1198
1199         TEST_ASSERT(burst_size <= MAX_PKT_BURST,
1200                         "Burst size specified is greater than supported.");
1201
1202         /* Generate test bursts of packets to transmit */
1203         TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0),
1204                         burst_size, "failed to generate test burst");
1205
1206         /* Send burst on bonded port */
1207         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
1208                         test_params->bonded_port_id, 0, pkt_burst, burst_size), burst_size,
1209                         "tx burst failed");
1210
1211         /* Verify bonded port tx stats */
1212         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1213         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1214                         "Bonded Port (%d) opackets value (%u) not as expected (%d)\n",
1215                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1216                         burst_size);
1217
1218         /* Verify slave ports tx stats */
1219         for (i = 0; i < test_params->bonded_slave_count; i++) {
1220                 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1221                 TEST_ASSERT_EQUAL(port_stats.opackets,
1222                                 (uint64_t)burst_size / test_params->bonded_slave_count,
1223                                 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
1224                                 test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1225                                 burst_size / test_params->bonded_slave_count);
1226         }
1227
1228         /* Put all slaves down and try and transmit */
1229         for (i = 0; i < test_params->bonded_slave_count; i++) {
1230                 virtual_ethdev_simulate_link_status_interrupt(
1231                                 test_params->slave_port_ids[i], 0);
1232         }
1233
1234         /* Send burst on bonded port */
1235         TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1236                         pkt_burst, burst_size), 0,
1237                         "tx burst return unexpected value");
1238
1239         /* Clean up and remove slaves from bonded device */
1240         return remove_slaves_and_stop_bonded_device();
1241 }
1242
1243 #ifdef RTE_MBUF_REFCNT
1244 static int
1245 verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
1246 {
1247         int i, refcnt;
1248
1249         for (i = 0; i < nb_mbufs; i++) {
1250                 refcnt = rte_mbuf_refcnt_read(mbufs[i]);
1251                 TEST_ASSERT_EQUAL(refcnt, val,
1252                         "mbuf ref count (%d)is not the expected value (%d)",
1253                         refcnt, val);
1254         }
1255         return 0;
1256 }
1257 #endif
1258
1259
1260 static void
1261 free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
1262 {
1263         int i;
1264
1265         for (i = 0; i < nb_mbufs; i++)
1266                 rte_pktmbuf_free(mbufs[i]);
1267 }
1268
1269 #define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT               (2)
1270 #define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE                (64)
1271 #define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT             (22)
1272 #define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (1)
1273
1274 static int
1275 test_roundrobin_tx_burst_slave_tx_fail(void)
1276 {
1277         struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
1278         struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
1279
1280         struct rte_eth_stats port_stats;
1281
1282         int i, first_fail_idx, tx_count;
1283
1284         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1285                         BONDING_MODE_ROUND_ROBIN, 0,
1286                         TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
1287                         "Failed to intialise bonded device");
1288
1289         /* Generate test bursts of packets to transmit */
1290         TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
1291                         TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
1292                         TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
1293                         "Failed to generate test packet burst");
1294
1295         /* Copy references to packets which we expect not to be transmitted */
1296         first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1297                         (TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
1298                         TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
1299                         TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
1300
1301         for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1302                 expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
1303                                 (i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
1304         }
1305
1306         /* Set virtual slave to only fail transmission of
1307          * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
1308         virtual_ethdev_tx_burst_fn_set_success(
1309                         test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1310                         0);
1311
1312         virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
1313                         test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
1314                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1315
1316         tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
1317                         TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
1318
1319         TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1320                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1321                         "Transmitted (%d) an unexpected (%d) number of packets", tx_count,
1322                         TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1323                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1324
1325         /* Verify that failed packet are expected failed packets */
1326         for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
1327                 TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
1328                                 "expected mbuf (%d) pointer %p not expected pointer %p",
1329                                 i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
1330         }
1331
1332         /* Verify bonded port tx stats */
1333         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1334
1335         TEST_ASSERT_EQUAL(port_stats.opackets,
1336                         (uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1337                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
1338                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1339                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1340                         TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
1341                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1342
1343         /* Verify slave ports tx stats */
1344         for (i = 0; i < test_params->bonded_slave_count; i++) {
1345                 int slave_expected_tx_count;
1346
1347                 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1348
1349                 slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
1350                                 test_params->bonded_slave_count;
1351
1352                 if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
1353                         slave_expected_tx_count = slave_expected_tx_count -
1354                                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
1355
1356                 TEST_ASSERT_EQUAL(port_stats.opackets,
1357                                 (uint64_t)slave_expected_tx_count,
1358                                 "Slave Port (%d) opackets value (%u) not as expected (%d)",
1359                                 test_params->slave_port_ids[i],
1360                                 (unsigned int)port_stats.opackets, slave_expected_tx_count);
1361         }
1362
1363 #ifdef RTE_MBUF_REFCNT
1364         /* Verify that all mbufs have a ref value of zero */
1365         TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
1366                         TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
1367                         "mbufs refcnts not as expected");
1368 #endif
1369         free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
1370
1371         /* Clean up and remove slaves from bonded device */
1372         return remove_slaves_and_stop_bonded_device();
1373 }
1374
1375 static int
1376 test_roundrobin_rx_burst_on_single_slave(void)
1377 {
1378         struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1379         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1380
1381         struct rte_eth_stats port_stats;
1382
1383         int i, j, burst_size = 25;
1384
1385         /* Initialize bonded device with 4 slaves in round robin mode */
1386         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1387                         BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1388                         "Failed to initialize bonded device with slaves");
1389
1390         /* Generate test bursts of packets to transmit */
1391         TEST_ASSERT_EQUAL(generate_test_burst(
1392                         gen_pkt_burst, burst_size, 0, 1, 0, 0, 0), burst_size,
1393                         "burst generation failed");
1394
1395         for (i = 0; i < test_params->bonded_slave_count; i++) {
1396                 /* Add rx data to slave */
1397                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1398                                 &gen_pkt_burst[0], burst_size);
1399
1400                 /* Call rx burst on bonded device */
1401                 /* Send burst on bonded port */
1402                 TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1403                                 test_params->bonded_port_id, 0, rx_pkt_burst,
1404                                 MAX_PKT_BURST), burst_size,
1405                                 "round-robin rx burst failed");
1406
1407                 /* Verify bonded device rx count */
1408                 rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1409                 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1410                                 "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1411                                 test_params->bonded_port_id,
1412                                 (unsigned int)port_stats.ipackets, burst_size);
1413
1414
1415
1416                 /* Verify bonded slave devices rx count */
1417                 /* Verify slave ports tx stats */
1418                 for (j = 0; j < test_params->bonded_slave_count; j++) {
1419                         rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
1420
1421                         if (i == j) {
1422                                 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
1423                                                 "Slave Port (%d) ipackets value (%u) not as expected"
1424                                                 " (%d)", test_params->slave_port_ids[i],
1425                                                 (unsigned int)port_stats.ipackets, burst_size);
1426                         } else {
1427                                 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1428                                                 "Slave Port (%d) ipackets value (%u) not as expected"
1429                                                 " (%d)", test_params->slave_port_ids[i],
1430                                                 (unsigned int)port_stats.ipackets, 0);
1431                         }
1432
1433                         /* Reset bonded slaves stats */
1434                         rte_eth_stats_reset(test_params->slave_port_ids[j]);
1435                 }
1436                 /* reset bonded device stats */
1437                 rte_eth_stats_reset(test_params->bonded_port_id);
1438         }
1439
1440         /* free mbufs */
1441         for (i = 0; i < MAX_PKT_BURST; i++) {
1442                 if (gen_pkt_burst[i] != NULL)
1443                         rte_pktmbuf_free(gen_pkt_burst[i]);
1444
1445                 if (rx_pkt_burst[i] != NULL)
1446                         rte_pktmbuf_free(rx_pkt_burst[i]);
1447         }
1448
1449
1450         /* Clean up and remove slaves from bonded device */
1451         return remove_slaves_and_stop_bonded_device();
1452 }
1453
1454 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3)
1455
1456 static int
1457 test_roundrobin_rx_burst_on_multiple_slaves(void)
1458 {
1459         struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
1460
1461         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1462         struct rte_eth_stats port_stats;
1463
1464         int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 };
1465         int i, nb_rx;
1466
1467         /* Initialize bonded device with 4 slaves in round robin mode */
1468         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1469                         BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1470                         "Failed to initialize bonded device with slaves");
1471
1472         /* Generate test bursts of packets to transmit */
1473         for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1474                 TEST_ASSERT_EQUAL(generate_test_burst(
1475                                 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0),
1476                                 burst_size[i], "burst generation failed");
1477         }
1478
1479         /* Add rx data to slaves */
1480         for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) {
1481                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1482                                 &gen_pkt_burst[i][0], burst_size[i]);
1483         }
1484
1485         /* Call rx burst on bonded device */
1486         /* Send burst on bonded port */
1487         nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
1488                         MAX_PKT_BURST);
1489         TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2],
1490                         "round-robin rx burst failed (%d != %d)\n", nb_rx,
1491                         burst_size[0] + burst_size[1] + burst_size[2]);
1492
1493         /* Verify bonded device rx count */
1494         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1495         TEST_ASSERT_EQUAL(port_stats.ipackets,
1496                         (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
1497                         "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
1498                         test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
1499                         burst_size[0] + burst_size[1] + burst_size[2]);
1500
1501         /* Verify bonded slave devices rx counts */
1502         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1503         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
1504                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1505                         test_params->slave_port_ids[0],
1506                         (unsigned int)port_stats.ipackets, burst_size[0]);
1507
1508         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1509         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
1510                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1511                         test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
1512                         burst_size[1]);
1513
1514         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1515         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
1516                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1517                                 test_params->slave_port_ids[2],
1518                                 (unsigned int)port_stats.ipackets, burst_size[2]);
1519
1520         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1521         TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
1522                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
1523                         test_params->slave_port_ids[3],
1524                         (unsigned int)port_stats.ipackets, 0);
1525
1526         /* free mbufs */
1527         for (i = 0; i < MAX_PKT_BURST; i++) {
1528                 if (rx_pkt_burst[i] != NULL)
1529                         rte_pktmbuf_free(rx_pkt_burst[i]);
1530         }
1531
1532         /* Clean up and remove slaves from bonded device */
1533         return remove_slaves_and_stop_bonded_device();
1534 }
1535
1536 static int
1537 test_roundrobin_verify_mac_assignment(void)
1538 {
1539         struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_2;
1540
1541         int i;
1542
1543         rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
1544         rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2);
1545
1546         /* Initialize bonded device with 4 slaves in round robin mode */
1547         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1548                                 BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1549                                 "Failed to initialize bonded device with slaves");
1550
1551         /* Verify that all MACs are the same as first slave added to bonded dev */
1552         for (i = 0; i < test_params->bonded_slave_count; i++) {
1553                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1554                 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1555                                 sizeof(read_mac_addr)),
1556                                 "slave port (%d) mac address not set to that of primary port",
1557                                 test_params->slave_port_ids[i]);
1558         }
1559
1560         /* change primary and verify that MAC addresses haven't changed */
1561         TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
1562                         test_params->slave_port_ids[2]),
1563                         "Failed to set bonded port (%d) primary port to (%d)",
1564                         test_params->bonded_port_id, test_params->slave_port_ids[i]);
1565
1566         for (i = 0; i < test_params->bonded_slave_count; i++) {
1567                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1568                 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
1569                                 sizeof(read_mac_addr)),
1570                                 "slave port (%d) mac address has changed to that of primary"
1571                                 " port without stop/start toggle of bonded device",
1572                                 test_params->slave_port_ids[i]);
1573         }
1574
1575         /* stop / start bonded device and verify that primary MAC address is
1576          * propagate to bonded device and slaves */
1577         rte_eth_dev_stop(test_params->bonded_port_id);
1578
1579         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
1580                         "Failed to start bonded device");
1581
1582         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1583         TEST_ASSERT_SUCCESS(
1584                         memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)),
1585                         "bonded port (%d) mac address not set to that of new primary port",
1586                         test_params->slave_port_ids[i]);
1587
1588         for (i = 0; i < test_params->bonded_slave_count; i++) {
1589                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1590                 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr,
1591                                 sizeof(read_mac_addr)),
1592                                 "slave port (%d) mac address not set to that of new primary"
1593                                 " port", test_params->slave_port_ids[i]);
1594         }
1595
1596         /* Set explicit MAC address */
1597         TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
1598                         test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
1599                         "Failed to set MAC");
1600
1601         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
1602         TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1603                         sizeof(read_mac_addr)),
1604                         "bonded port (%d) mac address not set to that of new primary port",
1605                                 test_params->slave_port_ids[i]);
1606
1607         for (i = 0; i < test_params->bonded_slave_count; i++) {
1608                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
1609                 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
1610                                 sizeof(read_mac_addr)), "slave port (%d) mac address not set to"
1611                                 " that of new primary port\n", test_params->slave_port_ids[i]);
1612         }
1613
1614         /* Clean up and remove slaves from bonded device */
1615         return remove_slaves_and_stop_bonded_device();
1616 }
1617
1618 static int
1619 test_roundrobin_verify_promiscuous_enable_disable(void)
1620 {
1621         int i, promiscuous_en;
1622
1623         /* Initialize bonded device with 4 slaves in round robin mode */
1624         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1625                         BONDING_MODE_ROUND_ROBIN, 0, 4, 1),
1626                         "Failed to initialize bonded device with slaves");
1627
1628         rte_eth_promiscuous_enable(test_params->bonded_port_id);
1629
1630         promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1631         TEST_ASSERT_EQUAL(promiscuous_en, 1,
1632                         "Port (%d) promiscuous mode not enabled",
1633                         test_params->bonded_port_id);
1634
1635         for (i = 0; i < test_params->bonded_slave_count; i++) {
1636                 promiscuous_en = rte_eth_promiscuous_get(
1637                                 test_params->slave_port_ids[i]);
1638                 TEST_ASSERT_EQUAL(promiscuous_en, 1,
1639                                 "slave port (%d) promiscuous mode not enabled",
1640                                 test_params->slave_port_ids[i]);
1641         }
1642
1643         rte_eth_promiscuous_disable(test_params->bonded_port_id);
1644
1645         promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id);
1646         TEST_ASSERT_EQUAL(promiscuous_en, 0,
1647                         "Port (%d) promiscuous mode not disabled\n",
1648                         test_params->bonded_port_id);
1649
1650         for (i = 0; i < test_params->bonded_slave_count; i++) {
1651                 promiscuous_en = rte_eth_promiscuous_get(
1652                                 test_params->slave_port_ids[i]);
1653                 TEST_ASSERT_EQUAL(promiscuous_en, 0,
1654                                 "Port (%d) promiscuous mode not disabled\n",
1655                                 test_params->slave_port_ids[i]);
1656         }
1657
1658         /* Clean up and remove slaves from bonded device */
1659         return remove_slaves_and_stop_bonded_device();
1660 }
1661
1662 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4)
1663 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2)
1664
1665 static int
1666 test_roundrobin_verify_slave_link_status_change_behaviour(void)
1667 {
1668         struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL };
1669         struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
1670         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1671
1672         struct rte_eth_stats port_stats;
1673         uint8_t slaves[RTE_MAX_ETHPORTS];
1674
1675         int i, burst_size, slave_count;
1676
1677         /* NULL all pointers in array to simplify cleanup */
1678         memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
1679
1680         /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
1681          * in round robin mode */
1682         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1683                         BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1),
1684                         "Failed to initialize bonded device with slaves");
1685
1686         /* Verify Current Slaves Count /Active Slave Count is */
1687         slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
1688                         RTE_MAX_ETHPORTS);
1689         TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1690                         "Number of slaves (%d) is not as expected (%d).",
1691                         slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1692
1693         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1694                         slaves, RTE_MAX_ETHPORTS);
1695         TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT,
1696                         "Number of active slaves (%d) is not as expected (%d).",
1697                         slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT);
1698
1699         /* Set 2 slaves eth_devs link status to down */
1700         virtual_ethdev_simulate_link_status_interrupt(
1701                         test_params->slave_port_ids[1], 0);
1702         virtual_ethdev_simulate_link_status_interrupt(
1703                         test_params->slave_port_ids[3], 0);
1704
1705         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
1706                         slaves, RTE_MAX_ETHPORTS);
1707         TEST_ASSERT_EQUAL(slave_count,
1708                         TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT,
1709                         "Number of active slaves (%d) is not as expected (%d).\n",
1710                         slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT);
1711
1712         burst_size = 20;
1713
1714         /* Verify that pkts are not sent on slaves with link status down:
1715          *
1716          * 1. Generate test burst of traffic
1717          * 2. Transmit burst on bonded eth_dev
1718          * 3. Verify stats for bonded eth_dev (opackets = burst_size)
1719          * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1720          */
1721         TEST_ASSERT_EQUAL(
1722                         generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0),
1723                         burst_size, "generate_test_burst failed");
1724
1725         rte_eth_stats_reset(test_params->bonded_port_id);
1726
1727
1728         TEST_ASSERT_EQUAL(
1729                         rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst,
1730                         burst_size), burst_size, "rte_eth_tx_burst failed");
1731
1732         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1733         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1734                         "Port (%d) opackets stats (%d) not expected (%d) value",
1735                         test_params->bonded_port_id, (int)port_stats.opackets,
1736                         burst_size);
1737
1738         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
1739         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1740                         "Port (%d) opackets stats (%d) not expected (%d) value",
1741                         test_params->slave_port_ids[0], (int)port_stats.opackets, 10);
1742
1743         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
1744         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1745                         "Port (%d) opackets stats (%d) not expected (%d) value",
1746                         test_params->slave_port_ids[1], (int)port_stats.opackets, 0);
1747
1748         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
1749         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10,
1750                         "Port (%d) opackets stats (%d) not expected (%d) value",
1751                         test_params->slave_port_ids[2], (int)port_stats.opackets, 10);
1752
1753         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
1754         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0,
1755                         "Port (%d) opackets stats (%d) not expected (%d) value",
1756                         test_params->slave_port_ids[3], (int)port_stats.opackets, 0);
1757
1758         /* Verify that pkts are not sent on slaves with link status down:
1759          *
1760          * 1. Generate test bursts of traffic
1761          * 2. Add bursts on to virtual eth_devs
1762          * 3. Rx burst on bonded eth_dev, expected (burst_ size *
1763          *    TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received
1764          * 4. Verify stats for bonded eth_dev
1765          * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0)
1766          */
1767         for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) {
1768                 TEST_ASSERT_EQUAL(generate_test_burst(
1769                                 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0),
1770                                 burst_size, "failed to generate packet burst");
1771
1772                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
1773                                 &gen_pkt_burst[i][0], burst_size);
1774         }
1775
1776         TEST_ASSERT_EQUAL(rte_eth_rx_burst(
1777                         test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
1778                         burst_size + burst_size,
1779                         "rte_eth_rx_burst failed");
1780
1781         /* Verify bonded device rx count */
1782         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1783         TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size),
1784                         "(%d) port_stats.ipackets not as expected\n",
1785                         test_params->bonded_port_id);
1786
1787         /* free mbufs */
1788         for (i = 0; i < MAX_PKT_BURST; i++) {
1789                 if (rx_pkt_burst[i] != NULL)
1790                         rte_pktmbuf_free(rx_pkt_burst[i]);
1791
1792                 if (gen_pkt_burst[1][i] != NULL)
1793                         rte_pktmbuf_free(gen_pkt_burst[1][i]);
1794
1795                 if (gen_pkt_burst[3][i] != NULL)
1796                         rte_pktmbuf_free(gen_pkt_burst[1][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_POLLING_LINK_STATUS_SLAVE_COUNT (2)
1804
1805 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
1806
1807
1808 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
1809
1810 static int
1811 test_roundrobin_verfiy_polling_slave_link_status_change(void)
1812 {
1813         struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
1814         char slave_name[RTE_ETH_NAME_MAX_LEN];
1815
1816         int i;
1817
1818         for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1819                 /* Generate slave name / MAC address */
1820                 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
1821                 mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
1822
1823                 /* Create slave devices with no ISR Support */
1824                 if (polling_test_slaves[i] == -1) {
1825                         polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
1826                                         rte_socket_id(), 0);
1827                         TEST_ASSERT(polling_test_slaves[i] >= 0,
1828                                         "Failed to create virtual virtual ethdev %s\n", slave_name);
1829
1830                         /* Configure slave */
1831                         TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
1832                                         "Failed to configure virtual ethdev %s(%d)", slave_name,
1833                                         polling_test_slaves[i]);
1834                 }
1835
1836                 /* Add slave to bonded device */
1837                 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
1838                                 polling_test_slaves[i]),
1839                                 "Failed to add slave %s(%d) to bonded device %d",
1840                                 slave_name, polling_test_slaves[i],
1841                                 test_params->bonded_port_id);
1842         }
1843
1844         /* Initialize bonded device */
1845         TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
1846                         "Failed to configure bonded device %d",
1847                         test_params->bonded_port_id);
1848
1849
1850         /* Register link status change interrupt callback */
1851         rte_eth_dev_callback_register(test_params->bonded_port_id,
1852                         RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1853                         &test_params->bonded_port_id);
1854
1855         /* link status change callback for first slave link up */
1856         test_lsc_interrupt_count = 0;
1857
1858         virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
1859
1860         TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
1861
1862
1863         /* no link status change callback for second slave link up */
1864         test_lsc_interrupt_count = 0;
1865
1866         virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
1867
1868         TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
1869
1870         /* link status change callback for both slave links down */
1871         test_lsc_interrupt_count = 0;
1872
1873         virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
1874         virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
1875
1876         TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
1877
1878         /* Un-Register link status change interrupt callback */
1879         rte_eth_dev_callback_unregister(test_params->bonded_port_id,
1880                         RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
1881                         &test_params->bonded_port_id);
1882
1883
1884         /* Clean up and remove slaves from bonded device */
1885         for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
1886
1887                 TEST_ASSERT_SUCCESS(
1888                                 rte_eth_bond_slave_remove(test_params->bonded_port_id,
1889                                                 polling_test_slaves[i]),
1890                                 "Failed to remove slave %d from bonded port (%d)",
1891                                 polling_test_slaves[i], test_params->bonded_port_id);
1892         }
1893
1894         return remove_slaves_and_stop_bonded_device();
1895 }
1896
1897
1898 /** Active Backup Mode Tests */
1899
1900 static int
1901 test_activebackup_tx_burst(void)
1902 {
1903         int i, pktlen, primary_port, burst_size;
1904         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1905         struct rte_eth_stats port_stats;
1906
1907         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1908                         BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1),
1909                         "Failed to initialize bonded device with slaves");
1910
1911         initialize_eth_header(test_params->pkt_eth_hdr,
1912                         (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
1913         pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
1914                         dst_port_0, 16);
1915         pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
1916                         dst_addr_0, pktlen);
1917
1918         burst_size = 20 * test_params->bonded_slave_count;
1919
1920         TEST_ASSERT(burst_size < MAX_PKT_BURST,
1921                         "Burst size specified is greater than supported.");
1922
1923         /* Generate a burst of packets to transmit */
1924         TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst,
1925                         test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
1926                         test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1),
1927                         burst_size,     "failed to generate burst correctly");
1928
1929         /* Send burst on bonded port */
1930         TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
1931                         burst_size),  burst_size, "tx burst failed");
1932
1933         /* Verify bonded port tx stats */
1934         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
1935         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1936                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
1937                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
1938                         burst_size);
1939
1940         primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1941
1942         /* Verify slave ports tx stats */
1943         for (i = 0; i < test_params->bonded_slave_count; i++) {
1944                 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
1945                 if (test_params->slave_port_ids[i] == primary_port) {
1946                         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
1947                                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
1948                                         test_params->bonded_port_id,
1949                                         (unsigned int)port_stats.opackets,
1950                                         burst_size / test_params->bonded_slave_count);
1951                 } else {
1952                         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
1953                                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
1954                                         test_params->bonded_port_id,
1955                                         (unsigned int)port_stats.opackets, 0);
1956                 }
1957         }
1958
1959         /* Put all slaves down and try and transmit */
1960         for (i = 0; i < test_params->bonded_slave_count; i++) {
1961                 virtual_ethdev_simulate_link_status_interrupt(
1962                                 test_params->slave_port_ids[i], 0);
1963         }
1964
1965         /* Send burst on bonded port */
1966         TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
1967                         pkts_burst, burst_size), 0, "Sending empty burst failed");
1968
1969         /* Clean up and remove slaves from bonded device */
1970         return remove_slaves_and_stop_bonded_device();
1971 }
1972
1973 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4)
1974
1975 static int
1976 test_activebackup_rx_burst(void)
1977 {
1978         struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
1979         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
1980
1981         struct rte_eth_stats port_stats;
1982
1983         int primary_port;
1984
1985         int i, j, burst_size = 17;
1986
1987         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
1988                         BONDING_MODE_ACTIVE_BACKUP, 0,
1989                         TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
1990                         "Failed to initialize bonded device with slaves");
1991
1992         primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
1993         TEST_ASSERT(primary_port >= 0,
1994                         "failed to get primary slave for bonded port (%d)",
1995                         test_params->bonded_port_id);
1996
1997         for (i = 0; i < test_params->bonded_slave_count; i++) {
1998                 /* Generate test bursts of packets to transmit */
1999                 TEST_ASSERT_EQUAL(generate_test_burst(
2000                                 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0),
2001                                 burst_size, "burst generation failed");
2002
2003                 /* Add rx data to slave */
2004                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2005                                 &gen_pkt_burst[0], burst_size);
2006
2007                 /* Call rx burst on bonded device */
2008                 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2009                                 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size,
2010                                 "rte_eth_rx_burst failed");
2011
2012                 if (test_params->slave_port_ids[i] == primary_port) {
2013                         /* Verify bonded device rx count */
2014                         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2015                         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2016                                         "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2017                                         test_params->bonded_port_id,
2018                                         (unsigned int)port_stats.ipackets, burst_size);
2019
2020                         /* Verify bonded slave devices rx count */
2021                         for (j = 0; j < test_params->bonded_slave_count; j++) {
2022                                 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2023                                 if (i == j) {
2024                                         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2025                                                         "Slave Port (%d) ipackets value (%u) not as "
2026                                                         "expected (%d)", test_params->slave_port_ids[i],
2027                                                         (unsigned int)port_stats.ipackets, burst_size);
2028                                 } else {
2029                                         TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2030                                                         "Slave Port (%d) ipackets value (%u) not as "
2031                                                         "expected (%d)\n", test_params->slave_port_ids[i],
2032                                                         (unsigned int)port_stats.ipackets, 0);
2033                                 }
2034                         }
2035                 } else {
2036                         for (j = 0; j < test_params->bonded_slave_count; j++) {
2037                                 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats);
2038                                 TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2039                                                 "Slave Port (%d) ipackets value (%u) not as expected "
2040                                                 "(%d)", test_params->slave_port_ids[i],
2041                                                 (unsigned int)port_stats.ipackets, 0);
2042                         }
2043                 }
2044
2045                 /* free mbufs */
2046                 for (i = 0; i < MAX_PKT_BURST; i++) {
2047                         if (rx_pkt_burst[i] != NULL) {
2048                                 rte_pktmbuf_free(rx_pkt_burst[i]);
2049                                 rx_pkt_burst[i] = NULL;
2050                         }
2051                 }
2052
2053                 /* reset bonded device stats */
2054                 rte_eth_stats_reset(test_params->bonded_port_id);
2055         }
2056
2057         /* Clean up and remove slaves from bonded device */
2058         return remove_slaves_and_stop_bonded_device();
2059 }
2060
2061 static int
2062 test_activebackup_verify_promiscuous_enable_disable(void)
2063 {
2064         int i, primary_port, promiscuous_en;
2065
2066         /* Initialize bonded device with 4 slaves in round robin mode */
2067         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2068                         BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1),
2069                         "Failed to initialize bonded device with slaves");
2070
2071         primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2072         TEST_ASSERT(primary_port >= 0,
2073                         "failed to get primary slave for bonded port (%d)",
2074                         test_params->bonded_port_id);
2075
2076         rte_eth_promiscuous_enable(test_params->bonded_port_id);
2077
2078         TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2079                         "Port (%d) promiscuous mode not enabled",
2080                         test_params->bonded_port_id);
2081
2082         for (i = 0; i < test_params->bonded_slave_count; i++) {
2083                 promiscuous_en = rte_eth_promiscuous_get(
2084                                 test_params->slave_port_ids[i]);
2085                 if (primary_port == test_params->slave_port_ids[i]) {
2086                         TEST_ASSERT_EQUAL(promiscuous_en, 1,
2087                                         "slave port (%d) promiscuous mode not enabled",
2088                                         test_params->slave_port_ids[i]);
2089                 } else {
2090                         TEST_ASSERT_EQUAL(promiscuous_en, 0,
2091                                         "slave port (%d) promiscuous mode enabled",
2092                                         test_params->slave_port_ids[i]);
2093                 }
2094
2095         }
2096
2097         rte_eth_promiscuous_disable(test_params->bonded_port_id);
2098
2099         TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
2100                         "Port (%d) promiscuous mode not disabled\n",
2101                         test_params->bonded_port_id);
2102
2103         for (i = 0; i < test_params->bonded_slave_count; i++) {
2104                 promiscuous_en = rte_eth_promiscuous_get(
2105                                 test_params->slave_port_ids[i]);
2106                 TEST_ASSERT_EQUAL(promiscuous_en, 0,
2107                                 "slave port (%d) promiscuous mode not disabled\n",
2108                                 test_params->slave_port_ids[i]);
2109         }
2110
2111         /* Clean up and remove slaves from bonded device */
2112         return remove_slaves_and_stop_bonded_device();
2113 }
2114
2115 static int
2116 test_activebackup_verify_mac_assignment(void)
2117 {
2118         struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
2119
2120         rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
2121         rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
2122
2123         /* Initialize bonded device with 2 slaves in active backup mode */
2124         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2125                         BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2126                         "Failed to initialize bonded device with slaves");
2127
2128         /* Verify that bonded MACs is that of first slave and that the other slave
2129          * MAC hasn't been changed */
2130         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2131         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2132                         sizeof(read_mac_addr)),
2133                         "bonded port (%d) mac address not set to that of primary port",
2134                         test_params->bonded_port_id);
2135
2136         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2137         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2138                         sizeof(read_mac_addr)),
2139                         "slave port (%d) mac address not set to that of primary port",
2140                         test_params->slave_port_ids[0]);
2141
2142         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2143         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2144                         sizeof(read_mac_addr)),
2145                         "slave port (%d) mac address not as expected",
2146                         test_params->slave_port_ids[1]);
2147
2148         /* change primary and verify that MAC addresses haven't changed */
2149         TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id,
2150                         test_params->slave_port_ids[1]), 0,
2151                         "Failed to set bonded port (%d) primary port to (%d)",
2152                         test_params->bonded_port_id, test_params->slave_port_ids[1]);
2153
2154         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2155         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2156                         sizeof(read_mac_addr)),
2157                         "bonded port (%d) mac address not set to that of primary port",
2158                         test_params->bonded_port_id);
2159
2160         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2161         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2162                         sizeof(read_mac_addr)),
2163                         "slave port (%d) mac address not set to that of primary port",
2164                         test_params->slave_port_ids[0]);
2165
2166         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2167         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2168                         sizeof(read_mac_addr)),
2169                         "slave port (%d) mac address not as expected",
2170                         test_params->slave_port_ids[1]);
2171
2172         /* stop / start bonded device and verify that primary MAC address is
2173          * propagated to bonded device and slaves */
2174
2175         rte_eth_dev_stop(test_params->bonded_port_id);
2176
2177         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
2178                         "Failed to start device");
2179
2180         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2181         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2182                         sizeof(read_mac_addr)),
2183                         "bonded port (%d) mac address not set to that of primary port",
2184                         test_params->bonded_port_id);
2185
2186         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2187         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2188                         sizeof(read_mac_addr)),
2189                         "slave port (%d) mac address not as expected",
2190                         test_params->slave_port_ids[0]);
2191
2192         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2193         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
2194                         sizeof(read_mac_addr)),
2195                         "slave port (%d) mac address not set to that of primary port",
2196                         test_params->slave_port_ids[1]);
2197
2198         /* Set explicit MAC address */
2199         TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
2200                         test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
2201                         "failed to set MAC address");
2202
2203         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
2204         TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2205                         sizeof(read_mac_addr)),
2206                         "bonded port (%d) mac address not set to that of bonded port",
2207                         test_params->bonded_port_id);
2208
2209         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
2210         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
2211                         sizeof(read_mac_addr)),
2212                         "slave port (%d) mac address not as expected",
2213                         test_params->slave_port_ids[0]);
2214
2215         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
2216         TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
2217                         sizeof(read_mac_addr)),
2218                         "slave port (%d) mac address not set to that of bonded port",
2219                         test_params->slave_port_ids[1]);
2220
2221         /* Clean up and remove slaves from bonded device */
2222         return remove_slaves_and_stop_bonded_device();
2223 }
2224
2225 static int
2226 test_activebackup_verify_slave_link_status_change_failover(void)
2227 {
2228         struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2229         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2230         struct rte_eth_stats port_stats;
2231
2232         uint8_t slaves[RTE_MAX_ETHPORTS];
2233
2234         int i, j, burst_size, slave_count, primary_port;
2235
2236         burst_size = 21;
2237
2238         memset(pkt_burst, 0, sizeof(pkt_burst));
2239
2240         /* Generate packet burst for testing */
2241         TEST_ASSERT_EQUAL(generate_test_burst(
2242                         &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2243                         "generate_test_burst failed");
2244
2245         /* Initialize bonded device with 4 slaves in round robin mode */
2246         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2247                         BONDING_MODE_ACTIVE_BACKUP, 0,
2248                         TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1),
2249                         "Failed to initialize bonded device with slaves");
2250
2251         /* Verify Current Slaves Count /Active Slave Count is */
2252         slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
2253                         RTE_MAX_ETHPORTS);
2254         TEST_ASSERT_EQUAL(slave_count, 4,
2255                         "Number of slaves (%d) is not as expected (%d).",
2256                         slave_count, 4);
2257
2258         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
2259                         slaves, RTE_MAX_ETHPORTS);
2260         TEST_ASSERT_EQUAL(slave_count, 4,
2261                         "Number of active slaves (%d) is not as expected (%d).",
2262                         slave_count, 4);
2263
2264         primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2265         TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0],
2266                         "Primary port not as expected");
2267
2268         /* Bring 2 slaves down and verify active slave count */
2269         virtual_ethdev_simulate_link_status_interrupt(
2270                         test_params->slave_port_ids[1], 0);
2271         virtual_ethdev_simulate_link_status_interrupt(
2272                         test_params->slave_port_ids[3], 0);
2273
2274         TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2275                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
2276                         "Number of active slaves (%d) is not as expected (%d).",
2277                         slave_count, 2);
2278
2279         virtual_ethdev_simulate_link_status_interrupt(
2280                         test_params->slave_port_ids[1], 1);
2281         virtual_ethdev_simulate_link_status_interrupt(
2282                         test_params->slave_port_ids[3], 1);
2283
2284
2285         /* Bring primary port down, verify that active slave count is 3 and primary
2286          *  has changed */
2287         virtual_ethdev_simulate_link_status_interrupt(
2288                         test_params->slave_port_ids[0], 0);
2289
2290         TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
2291                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS),
2292                         3,
2293                         "Number of active slaves (%d) is not as expected (%d).",
2294                         slave_count, 3);
2295
2296         primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id);
2297         TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2],
2298                         "Primary port not as expected");
2299
2300         /* Verify that pkts are sent on new primary slave */
2301
2302         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2303                         test_params->bonded_port_id, 0, &pkt_burst[0][0],
2304                         burst_size), burst_size, "rte_eth_tx_burst failed");
2305
2306         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2307         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2308                         "(%d) port_stats.opackets not as expected",
2309                         test_params->slave_port_ids[2]);
2310
2311         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2312         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2313                         "(%d) port_stats.opackets not as expected\n",
2314                         test_params->slave_port_ids[0]);
2315
2316         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2317         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2318                         "(%d) port_stats.opackets not as expected\n",
2319                         test_params->slave_port_ids[1]);
2320
2321         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2322         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2323                         "(%d) port_stats.opackets not as expected\n",
2324                         test_params->slave_port_ids[3]);
2325
2326         /* Generate packet burst for testing */
2327
2328         for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2329                 TEST_ASSERT_EQUAL(generate_test_burst(
2330                                 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
2331                                 "generate_test_burst failed");
2332
2333                 virtual_ethdev_add_mbufs_to_rx_queue(
2334                         test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size);
2335         }
2336
2337         TEST_ASSERT_EQUAL(rte_eth_rx_burst(
2338                         test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
2339                         burst_size, "rte_eth_rx_burst\n");
2340
2341         /* Verify bonded device rx count */
2342         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2343         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size,
2344                         "(%d) port_stats.ipackets not as expected",
2345                         test_params->bonded_port_id);
2346
2347         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2348         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
2349                         "(%d) port_stats.opackets not as expected",
2350                         test_params->slave_port_ids[2]);
2351
2352         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2353         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2354                         "(%d) port_stats.opackets not as expected",
2355                         test_params->slave_port_ids[0]);
2356
2357         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2358         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2359                         "(%d) port_stats.opackets not as expected",
2360                         test_params->slave_port_ids[1]);
2361
2362         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2363         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
2364                         "(%d) port_stats.opackets not as expected",
2365                         test_params->slave_port_ids[3]);
2366
2367         /* free mbufs */
2368         for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) {
2369                 for (j = 0; j < MAX_PKT_BURST; j++) {
2370                         if (pkt_burst[i][j] != NULL) {
2371                                 rte_pktmbuf_free(pkt_burst[i][j]);
2372                                 pkt_burst[i][j] = NULL;
2373                         }
2374                 }
2375         }
2376
2377         /* Clean up and remove slaves from bonded device */
2378         return remove_slaves_and_stop_bonded_device();
2379 }
2380
2381 /** Balance Mode Tests */
2382
2383 static int
2384 test_balance_xmit_policy_configuration(void)
2385 {
2386         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2387                         BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1),
2388                         "Failed to initialize_bonded_device_with_slaves.");
2389
2390         /* Invalid port id */
2391         TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2392                         INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2),
2393                         "Expected call to failed as invalid port specified.");
2394
2395         /* Set xmit policy on non bonded device */
2396         TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set(
2397                         test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2),
2398                         "Expected call to failed as invalid port specified.");
2399
2400
2401         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2402                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2403                         "Failed to set balance xmit policy.");
2404
2405         TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2406                         BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected.");
2407
2408
2409         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2410                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2411                         "Failed to set balance xmit policy.");
2412
2413         TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2414                         BALANCE_XMIT_POLICY_LAYER23,
2415                         "balance xmit policy not as expected.");
2416
2417
2418         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2419                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2420                         "Failed to set balance xmit policy.");
2421
2422         TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id),
2423                         BALANCE_XMIT_POLICY_LAYER34,
2424                         "balance xmit policy not as expected.");
2425
2426         /* Invalid port id */
2427         TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID),
2428                         "Expected call to failed as invalid port specified.");
2429
2430         /* Clean up and remove slaves from bonded device */
2431         return remove_slaves_and_stop_bonded_device();
2432 }
2433
2434 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2)
2435
2436 static int
2437 test_balance_l2_tx_burst(void)
2438 {
2439         struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2440         int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 };
2441
2442         uint16_t pktlen;
2443         int i;
2444         struct rte_eth_stats port_stats;
2445
2446         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2447                         BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1),
2448                         "Failed to initialize_bonded_device_with_slaves.");
2449
2450         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2451                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2452                         "Failed to set balance xmit policy.");
2453
2454         initialize_eth_header(test_params->pkt_eth_hdr,
2455                         (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
2456         pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
2457                         dst_port_0, 16);
2458         pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
2459                         dst_addr_0, pktlen);
2460
2461         /* Generate a burst 1 of packets to transmit */
2462         TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0],
2463                         test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2464                         test_params->pkt_udp_hdr, burst_size[0],
2465                         PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0],
2466                         "failed to generate packet burst");
2467
2468         initialize_eth_header(test_params->pkt_eth_hdr,
2469                         (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_1, 0, 0);
2470
2471         /* Generate a burst 2 of packets to transmit */
2472         TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0],
2473                         test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1,
2474                         test_params->pkt_udp_hdr, burst_size[1],
2475                         PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1],
2476                         "failed to generate packet burst");
2477
2478         /* Send burst 1 on bonded port */
2479         for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) {
2480                 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
2481                                 &pkts_burst[i][0], burst_size[i]),
2482                                 burst_size[i], "Failed to transmit packet burst");
2483         }
2484
2485         /* Verify bonded port tx stats */
2486         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2487         TEST_ASSERT_EQUAL(port_stats.opackets,
2488                         (uint64_t)(burst_size[0] + burst_size[1]),
2489                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2490                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2491                         burst_size[0] + burst_size[1]);
2492
2493
2494         /* Verify slave ports tx stats */
2495         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2496         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0],
2497                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
2498                         test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2499                         burst_size[0]);
2500
2501         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2502         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1],
2503                         "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
2504                         test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2505                         burst_size[1]);
2506
2507         /* Put all slaves down and try and transmit */
2508         for (i = 0; i < test_params->bonded_slave_count; i++) {
2509
2510                 virtual_ethdev_simulate_link_status_interrupt(
2511                                 test_params->slave_port_ids[i], 0);
2512         }
2513
2514         /* Send burst on bonded port */
2515         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2516                         test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]),
2517                         0, "Expected zero packet");
2518
2519         /* Clean up and remove slaves from bonded device */
2520         return remove_slaves_and_stop_bonded_device();
2521 }
2522
2523 static int
2524 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2525                 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr)
2526 {
2527         int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2528
2529         struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2530         struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2531
2532         struct rte_eth_stats port_stats;
2533
2534         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2535                         BONDING_MODE_BALANCE, 0, 2, 1),
2536                         "Failed to initialize_bonded_device_with_slaves.");
2537
2538         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2539                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23),
2540                         "Failed to set balance xmit policy.");
2541
2542         burst_size_1 = 20;
2543         burst_size_2 = 10;
2544
2545         TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2546                         "Burst size specified is greater than supported.");
2547
2548         /* Generate test bursts of packets to transmit */
2549         TEST_ASSERT_EQUAL(generate_test_burst(
2550                         pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2551                         burst_size_1, "failed to generate packet burst");
2552
2553         TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4,
2554                         toggle_mac_addr, toggle_ip_addr, 0), burst_size_2,
2555                         "failed to generate packet burst");
2556
2557         /* Send burst 1 on bonded port */
2558         nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2559                         burst_size_1);
2560         TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2561
2562         /* Send burst 2 on bonded port */
2563         nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2564                         burst_size_2);
2565         TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2566
2567         /* Verify bonded port tx stats */
2568         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2569         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2570                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2571                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2572                         nb_tx_1 + nb_tx_2);
2573
2574         /* Verify slave ports tx stats */
2575         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2576         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2577                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
2578                         test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2579                         nb_tx_1);
2580
2581         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2582         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2583                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
2584                         test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2585                         nb_tx_2);
2586
2587         /* Put all slaves down and try and transmit */
2588         for (i = 0; i < test_params->bonded_slave_count; i++) {
2589
2590                 virtual_ethdev_simulate_link_status_interrupt(
2591                                 test_params->slave_port_ids[i], 0);
2592         }
2593
2594         /* Send burst on bonded port */
2595         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2596                         test_params->bonded_port_id, 0, pkts_burst_1,
2597                         burst_size_1), 0, "Expected zero packet");
2598
2599
2600         /* Clean up and remove slaves from bonded device */
2601         return remove_slaves_and_stop_bonded_device();
2602 }
2603
2604 static int
2605 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void)
2606 {
2607         return balance_l23_tx_burst(0, 1, 1, 0);
2608 }
2609
2610 static int
2611 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2612 {
2613         return balance_l23_tx_burst(1, 1, 0, 1);
2614 }
2615
2616 static int
2617 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void)
2618 {
2619         return balance_l23_tx_burst(0, 0, 0, 1);
2620 }
2621
2622 static int
2623 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2624 {
2625         return balance_l23_tx_burst(1, 0, 0, 1);
2626 }
2627
2628 static int
2629 test_balance_l23_tx_burst_toggle_mac_addr(void)
2630 {
2631         return balance_l23_tx_burst(0, 0, 1, 0);
2632 }
2633
2634 static int
2635 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,
2636                 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr,
2637                 uint8_t toggle_udp_port)
2638 {
2639         int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2;
2640
2641         struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST];
2642         struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST];
2643
2644         struct rte_eth_stats port_stats;
2645
2646         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2647                         BONDING_MODE_BALANCE, 0, 2, 1),
2648                         "Failed to initialize_bonded_device_with_slaves.");
2649
2650         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2651                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34),
2652                         "Failed to set balance xmit policy.");
2653
2654         burst_size_1 = 20;
2655         burst_size_2 = 10;
2656
2657         TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST,
2658                         "Burst size specified is greater than supported.");
2659
2660         /* Generate test bursts of packets to transmit */
2661         TEST_ASSERT_EQUAL(generate_test_burst(
2662                         pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0),
2663                         burst_size_1, "failed to generate burst");
2664
2665         TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2,
2666                         vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr,
2667                         toggle_udp_port), burst_size_2, "failed to generate burst");
2668
2669         /* Send burst 1 on bonded port */
2670         nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2671                         burst_size_1);
2672         TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed");
2673
2674         /* Send burst 2 on bonded port */
2675         nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2676                         burst_size_2);
2677         TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed");
2678
2679
2680         /* Verify bonded port tx stats */
2681         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2682         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2),
2683                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2684                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2685                         nb_tx_1 + nb_tx_2);
2686
2687         /* Verify slave ports tx stats */
2688         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2689         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1,
2690                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
2691                         test_params->slave_port_ids[0], (unsigned int)port_stats.opackets,
2692                         nb_tx_1);
2693
2694         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2695         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2,
2696                         "Slave Port (%d) opackets value (%u) not as expected (%d)",
2697                         test_params->slave_port_ids[1], (unsigned int)port_stats.opackets,
2698                         nb_tx_2);
2699
2700         /* Put all slaves down and try and transmit */
2701         for (i = 0; i < test_params->bonded_slave_count; i++) {
2702
2703                 virtual_ethdev_simulate_link_status_interrupt(
2704                                 test_params->slave_port_ids[i], 0);
2705         }
2706
2707         /* Send burst on bonded port */
2708         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
2709                         test_params->bonded_port_id, 0, pkts_burst_1,
2710                         burst_size_1), 0, "Expected zero packet");
2711
2712         /* Clean up and remove slaves from bonded device */
2713         return remove_slaves_and_stop_bonded_device();
2714 }
2715
2716 static int
2717 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void)
2718 {
2719         return balance_l34_tx_burst(0, 1, 0, 1, 0);
2720 }
2721
2722 static int
2723 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void)
2724 {
2725         return balance_l34_tx_burst(0, 1, 0, 0, 1);
2726 }
2727
2728 static int
2729 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void)
2730 {
2731         return balance_l34_tx_burst(1, 1, 0, 1, 0);
2732 }
2733
2734 static int
2735 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void)
2736 {
2737         return balance_l34_tx_burst(0, 0, 0, 1, 0);
2738 }
2739
2740 static int
2741 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void)
2742 {
2743         return balance_l34_tx_burst(1, 0, 0, 1, 0);
2744 }
2745
2746 static int
2747 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
2748 {
2749         return balance_l34_tx_burst(0, 0, 0, 0, 1);
2750 }
2751
2752 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT                      (2)
2753 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1                     (40)
2754 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2                     (20)
2755 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT            (25)
2756 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX        (0)
2757
2758 static int
2759 test_balance_tx_burst_slave_tx_fail(void)
2760 {
2761         struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
2762         struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
2763
2764         struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
2765
2766         struct rte_eth_stats port_stats;
2767
2768         int i, first_tx_fail_idx, tx_count_1, tx_count_2;
2769
2770         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2771                         BONDING_MODE_BALANCE, 0,
2772                         TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
2773                         "Failed to intialise bonded device");
2774
2775         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
2776                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
2777                         "Failed to set balance xmit policy.");
2778
2779
2780         /* Generate test bursts for transmission */
2781         TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
2782                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
2783                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
2784                         "Failed to generate test packet burst 1");
2785
2786         first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2787                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
2788
2789         /* copy mbuf referneces for expected transmission failures */
2790         for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++)
2791                 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
2792
2793         TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
2794                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
2795                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2796                         "Failed to generate test packet burst 2");
2797
2798
2799         /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
2800          * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
2801         virtual_ethdev_tx_burst_fn_set_success(
2802                         test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2803                         0);
2804
2805         virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
2806                         test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
2807                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2808
2809
2810         /* Transmit burst 1 */
2811         tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
2812                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
2813
2814         TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2815                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2816                         "Transmitted (%d) packets, expected to transmit (%d) packets",
2817                         tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2818                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2819
2820         /* Verify that failed packet are expected failed packets */
2821         for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
2822                 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
2823                                 "expected mbuf (%d) pointer %p not expected pointer %p",
2824                                 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
2825         }
2826
2827         /* Transmit burst 2 */
2828         tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
2829                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2830
2831         TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2832                         "Transmitted (%d) packets, expected to transmit (%d) packets",
2833                         tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2834
2835
2836         /* Verify bonded port tx stats */
2837         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2838
2839         TEST_ASSERT_EQUAL(port_stats.opackets,
2840                         (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2841                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2842                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
2843                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
2844                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
2845                         (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2846                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
2847                         TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2848
2849         /* Verify slave ports tx stats */
2850
2851         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2852
2853         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
2854                                 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2855                                 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
2856                                 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2857                                 test_params->slave_port_ids[0],
2858                                 (unsigned int)port_stats.opackets,
2859                                 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
2860                                 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2861
2862
2863
2864
2865         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2866
2867         TEST_ASSERT_EQUAL(port_stats.opackets,
2868                                 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
2869                                 "Slave Port (%d) opackets value (%u) not as expected (%d)",
2870                                 test_params->slave_port_ids[1],
2871                                 (unsigned int)port_stats.opackets,
2872                                 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
2873
2874 #ifdef RTE_MBUF_REFCNT
2875         /* Verify that all mbufs have a ref value of zero */
2876         TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
2877                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
2878                         "mbufs refcnts not as expected");
2879 #endif
2880
2881         free_mbufs(&pkts_burst_1[tx_count_1],
2882                         TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
2883
2884         /* Clean up and remove slaves from bonded device */
2885         return remove_slaves_and_stop_bonded_device();
2886 }
2887
2888 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
2889
2890 static int
2891 test_balance_rx_burst(void)
2892 {
2893         struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST];
2894
2895         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
2896         struct rte_eth_stats port_stats;
2897
2898         int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 };
2899         int i, j;
2900
2901         memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
2902
2903         /* Initialize bonded device with 4 slaves in round robin mode */
2904         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2905                         BONDING_MODE_BALANCE, 0, 3, 1),
2906                         "Failed to intialise bonded device");
2907
2908         /* Generate test bursts of packets to transmit */
2909         for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2910                 TEST_ASSERT_EQUAL(generate_test_burst(
2911                                 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1,
2912                                 0, 0), burst_size[i],
2913                                 "failed to generate packet burst");
2914         }
2915
2916         /* Add rx data to slaves */
2917         for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2918                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
2919                                 &gen_pkt_burst[i][0], burst_size[i]);
2920         }
2921
2922         /* Call rx burst on bonded device */
2923         /* Send burst on bonded port */
2924         TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0,
2925                         rx_pkt_burst, MAX_PKT_BURST),
2926                         burst_size[0] + burst_size[1] + burst_size[2],
2927                         "balance rx burst failed\n");
2928
2929         /* Verify bonded device rx count */
2930         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
2931         TEST_ASSERT_EQUAL(port_stats.ipackets,
2932                         (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
2933                         "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
2934                         test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
2935                         burst_size[0] + burst_size[1] + burst_size[2]);
2936
2937
2938         /* Verify bonded slave devices rx counts */
2939         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
2940         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
2941                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2942                                 test_params->slave_port_ids[0],
2943                                 (unsigned int)port_stats.ipackets, burst_size[0]);
2944
2945         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
2946         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
2947                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2948                         test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets,
2949                         burst_size[1]);
2950
2951         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
2952         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
2953                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2954                         test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
2955                         burst_size[2]);
2956
2957         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
2958         TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
2959                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
2960                         test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
2961                         0);
2962
2963         /* free mbufs */
2964         for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
2965                 for (j = 0; j < MAX_PKT_BURST; j++) {
2966                         if (gen_pkt_burst[i][j] != NULL) {
2967                                 rte_pktmbuf_free(gen_pkt_burst[i][j]);
2968                                 gen_pkt_burst[i][j] = NULL;
2969                         }
2970                 }
2971         }
2972
2973         /* Clean up and remove slaves from bonded device */
2974         return remove_slaves_and_stop_bonded_device();
2975 }
2976
2977 static int
2978 test_balance_verify_promiscuous_enable_disable(void)
2979 {
2980         int i;
2981
2982         /* Initialize bonded device with 4 slaves in round robin mode */
2983         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
2984                         BONDING_MODE_BALANCE, 0, 4, 1),
2985                         "Failed to intialise bonded device");
2986
2987         rte_eth_promiscuous_enable(test_params->bonded_port_id);
2988
2989         TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
2990                         "Port (%d) promiscuous mode not enabled",
2991                         test_params->bonded_port_id);
2992
2993         for (i = 0; i < test_params->bonded_slave_count; i++) {
2994                 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
2995                                 test_params->slave_port_ids[i]), 1,
2996                                 "Port (%d) promiscuous mode not enabled",
2997                                 test_params->slave_port_ids[i]);
2998         }
2999
3000         rte_eth_promiscuous_disable(test_params->bonded_port_id);
3001
3002         TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3003                         "Port (%d) promiscuous mode not disabled",
3004                         test_params->bonded_port_id);
3005
3006         for (i = 0; i < test_params->bonded_slave_count; i++) {
3007                 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3008                                 test_params->slave_port_ids[i]), 0,
3009                                 "Port (%d) promiscuous mode not disabled",
3010                                 test_params->slave_port_ids[i]);
3011         }
3012
3013         /* Clean up and remove slaves from bonded device */
3014         return remove_slaves_and_stop_bonded_device();
3015 }
3016
3017 static int
3018 test_balance_verify_mac_assignment(void)
3019 {
3020         struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3021
3022         rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3023         rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1);
3024
3025         /* Initialize bonded device with 2 slaves in active backup mode */
3026         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3027                         BONDING_MODE_BALANCE, 0, 2, 1),
3028                         "Failed to intialise bonded device");
3029
3030         /* Verify that bonded MACs is that of first slave and that the other slave
3031          * MAC hasn't been changed */
3032         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3033         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3034                         sizeof(read_mac_addr)),
3035                         "bonded port (%d) mac address not set to that of primary port",
3036                         test_params->bonded_port_id);
3037
3038         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3039         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3040                         sizeof(read_mac_addr)),
3041                         "slave port (%d) mac address not set to that of primary port",
3042                         test_params->slave_port_ids[0]);
3043
3044         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3045         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3046                         sizeof(read_mac_addr)),
3047                         "slave port (%d) mac address not set to that of primary port",
3048                         test_params->slave_port_ids[1]);
3049
3050         /* change primary and verify that MAC addresses haven't changed */
3051         TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3052                         test_params->slave_port_ids[1]),
3053                         "Failed to set bonded port (%d) primary port to (%d)\n",
3054                         test_params->bonded_port_id, test_params->slave_port_ids[1]);
3055
3056         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3057         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3058                         sizeof(read_mac_addr)),
3059                         "bonded port (%d) mac address not set to that of primary port",
3060                         test_params->bonded_port_id);
3061
3062         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3063         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3064                         sizeof(read_mac_addr)),
3065                         "slave port (%d) mac address not set to that of primary port",
3066                         test_params->slave_port_ids[0]);
3067
3068         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3069         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3070                         sizeof(read_mac_addr)),
3071                         "slave port (%d) mac address not set to that of primary port",
3072                         test_params->slave_port_ids[1]);
3073
3074         /* stop / start bonded device and verify that primary MAC address is
3075          * propagated to bonded device and slaves */
3076
3077         rte_eth_dev_stop(test_params->bonded_port_id);
3078
3079         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3080                         "Failed to start bonded device");
3081
3082         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3083         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3084                         sizeof(read_mac_addr)),
3085                         "bonded port (%d) mac address not set to that of primary port",
3086                         test_params->bonded_port_id);
3087
3088         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3089         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3090                         sizeof(read_mac_addr)),
3091                         "slave port (%d) mac address not set to that of primary port",
3092                         test_params->slave_port_ids[0]);
3093
3094         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3095         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3096                         sizeof(read_mac_addr)),
3097                         "slave port (%d) mac address not set to that of primary port",
3098                         test_params->slave_port_ids[1]);
3099
3100         /* Set explicit MAC address */
3101         TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3102                         test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3103                         "failed to set MAC");
3104
3105         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3106         TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3107                         sizeof(read_mac_addr)),
3108                         "bonded port (%d) mac address not set to that of bonded port",
3109                         test_params->bonded_port_id);
3110
3111         rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr);
3112         TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3113                         sizeof(read_mac_addr)),
3114                         "slave port (%d) mac address not as expected\n",
3115                                 test_params->slave_port_ids[0]);
3116
3117         rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr);
3118         TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr,
3119                         sizeof(read_mac_addr)),
3120                         "slave port (%d) mac address not set to that of bonded port",
3121                         test_params->slave_port_ids[1]);
3122
3123         /* Clean up and remove slaves from bonded device */
3124         return remove_slaves_and_stop_bonded_device();
3125 }
3126
3127 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4)
3128
3129 static int
3130 test_balance_verify_slave_link_status_change_behaviour(void)
3131 {
3132         struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST];
3133         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3134         struct rte_eth_stats port_stats;
3135
3136         uint8_t slaves[RTE_MAX_ETHPORTS];
3137
3138         int i, j, burst_size, slave_count;
3139
3140         memset(pkt_burst, 0, sizeof(pkt_burst));
3141
3142         /* Initialize bonded device with 4 slaves in round robin mode */
3143         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3144                         BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1),
3145                         "Failed to intialise bonded device");
3146
3147         TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
3148                         test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
3149                         "Failed to set balance xmit policy.");
3150
3151
3152         /* Verify Current Slaves Count /Active Slave Count is */
3153         slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3154                         RTE_MAX_ETHPORTS);
3155         TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3156                         "Number of slaves (%d) is not as expected (%d).",
3157                         slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3158
3159         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3160                         slaves, RTE_MAX_ETHPORTS);
3161         TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT,
3162                         "Number of active slaves (%d) is not as expected (%d).",
3163                         slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT);
3164
3165         /* Set 2 slaves link status to down */
3166         virtual_ethdev_simulate_link_status_interrupt(
3167                         test_params->slave_port_ids[1], 0);
3168         virtual_ethdev_simulate_link_status_interrupt(
3169                         test_params->slave_port_ids[3], 0);
3170
3171         TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3172                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2,
3173                         "Number of active slaves (%d) is not as expected (%d).",
3174                         slave_count, 2);
3175
3176         /* Send to sets of packet burst and verify that they are balanced across
3177          *  slaves */
3178         burst_size = 21;
3179
3180         TEST_ASSERT_EQUAL(generate_test_burst(
3181                         &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3182                         "generate_test_burst failed");
3183
3184         TEST_ASSERT_EQUAL(generate_test_burst(
3185                         &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3186                         "generate_test_burst failed");
3187
3188         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3189                         test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size),
3190                         burst_size, "rte_eth_tx_burst failed");
3191
3192         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3193                         test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3194                         burst_size, "rte_eth_tx_burst failed");
3195
3196
3197         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3198         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3199                         "(%d) port_stats.opackets (%d) not as expected (%d).",
3200                         test_params->bonded_port_id, (int)port_stats.opackets,
3201                         burst_size + burst_size);
3202
3203         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3204         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3205                         "(%d) port_stats.opackets (%d) not as expected (%d).",
3206                         test_params->slave_port_ids[0], (int)port_stats.opackets,
3207                         burst_size);
3208
3209         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3210         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3211                         "(%d) port_stats.opackets (%d) not as expected (%d).",
3212                         test_params->slave_port_ids[2], (int)port_stats.opackets,
3213                         burst_size);
3214
3215         /* verify that all packets get send on primary slave when no other slaves
3216          * are available */
3217         virtual_ethdev_simulate_link_status_interrupt(
3218                         test_params->slave_port_ids[2], 0);
3219
3220         TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get(
3221                         test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1,
3222                         "Number of active slaves (%d) is not as expected (%d).",
3223                         slave_count, 1);
3224
3225         TEST_ASSERT_EQUAL(generate_test_burst(
3226                         &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size,
3227                         "generate_test_burst failed");
3228
3229         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3230                         test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size),
3231                         burst_size, "rte_eth_tx_burst failed");
3232
3233         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3234         TEST_ASSERT_EQUAL(port_stats.opackets,
3235                         (uint64_t)(burst_size + burst_size + burst_size),
3236                         "(%d) port_stats.opackets (%d) not as expected (%d).\n",
3237                         test_params->bonded_port_id, (int)port_stats.opackets,
3238                         burst_size + burst_size + burst_size);
3239
3240         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3241         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size),
3242                         "(%d) port_stats.opackets (%d) not as expected (%d).",
3243                         test_params->slave_port_ids[0], (int)port_stats.opackets,
3244                         burst_size + burst_size);
3245
3246         virtual_ethdev_simulate_link_status_interrupt(
3247                         test_params->slave_port_ids[0], 0);
3248         virtual_ethdev_simulate_link_status_interrupt(
3249                         test_params->slave_port_ids[1], 1);
3250         virtual_ethdev_simulate_link_status_interrupt(
3251                         test_params->slave_port_ids[2], 1);
3252         virtual_ethdev_simulate_link_status_interrupt(
3253                         test_params->slave_port_ids[3], 1);
3254
3255         for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) {
3256                 TEST_ASSERT_EQUAL(generate_test_burst(
3257                                 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size,
3258                                 "Failed to generate packet burst");
3259
3260                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3261                                 &pkt_burst[i][0], burst_size);
3262         }
3263
3264         /* Verify that pkts are not received on slaves with link status down */
3265
3266         rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst,
3267                         MAX_PKT_BURST);
3268
3269         /* Verify bonded device rx count */
3270         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3271         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3),
3272                         "(%d) port_stats.ipackets (%d) not as expected (%d)\n",
3273                         test_params->bonded_port_id, (int)port_stats.ipackets,
3274                         burst_size * 3);
3275
3276         /* free mbufs allocate for rx testing */
3277         for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) {
3278                 for (j = 0; j < MAX_PKT_BURST; j++) {
3279                         if (pkt_burst[i][j] != NULL) {
3280                                 rte_pktmbuf_free(pkt_burst[i][j]);
3281                                 pkt_burst[i][j] = NULL;
3282                         }
3283                 }
3284         }
3285
3286         /* Clean up and remove slaves from bonded device */
3287         return remove_slaves_and_stop_bonded_device();
3288 }
3289
3290 #ifdef RTE_MBUF_REFCNT
3291 /** Broadcast Mode Tests */
3292
3293 static int
3294 test_broadcast_tx_burst(void)
3295 {
3296         int i, pktlen, burst_size;
3297         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
3298
3299         struct rte_eth_stats port_stats;
3300
3301         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3302                         BONDING_MODE_BROADCAST, 0, 2, 1),
3303                         "Failed to intialise bonded device");
3304
3305         initialize_eth_header(test_params->pkt_eth_hdr,
3306                         (struct ether_addr *)src_mac, (struct ether_addr *)dst_mac_0, 0, 0);
3307
3308         pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port,
3309                         dst_port_0, 16);
3310         pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr,
3311                         dst_addr_0, pktlen);
3312
3313         burst_size = 20 * test_params->bonded_slave_count;
3314
3315         TEST_ASSERT(burst_size < MAX_PKT_BURST,
3316                         "Burst size specified is greater than supported.");
3317
3318         /* Generate a burst of packets to transmit */
3319         TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool,
3320                         pkts_burst,     test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr,
3321                         1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN,
3322                         1), burst_size, "Failed to generate packet burst");
3323
3324         /* Send burst on bonded port */
3325         TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3326                         pkts_burst, burst_size), burst_size,
3327                         "Bonded Port (%d) rx burst failed, packets transmitted value "
3328                         "not as expected (%d)",
3329                         test_params->bonded_port_id, burst_size);
3330
3331         /* Verify bonded port tx stats */
3332         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3333         TEST_ASSERT_EQUAL(port_stats.opackets,
3334                         (uint64_t)burst_size * test_params->bonded_slave_count,
3335                         "Bonded Port (%d) opackets value (%u) not as expected (%d)",
3336                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3337                         burst_size);
3338
3339         /* Verify slave ports tx stats */
3340         for (i = 0; i < test_params->bonded_slave_count; i++) {
3341                 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
3342                 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3343                                 "Slave Port (%d) opackets value (%u) not as expected (%d)\n",
3344                                 test_params->bonded_port_id,
3345                                 (unsigned int)port_stats.opackets, burst_size);
3346         }
3347
3348         /* Put all slaves down and try and transmit */
3349         for (i = 0; i < test_params->bonded_slave_count; i++) {
3350
3351                 virtual_ethdev_simulate_link_status_interrupt(
3352                                 test_params->slave_port_ids[i], 0);
3353         }
3354
3355         /* Send burst on bonded port */
3356         TEST_ASSERT_EQUAL(rte_eth_tx_burst(
3357                         test_params->bonded_port_id, 0, pkts_burst, burst_size),  0,
3358                         "transmitted an unexpected number of packets");
3359
3360         /* Clean up and remove slaves from bonded device */
3361         return remove_slaves_and_stop_bonded_device();
3362 }
3363
3364
3365 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT            (3)
3366 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE                     (40)
3367 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT      (15)
3368 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT      (10)
3369
3370 static int
3371 test_broadcast_tx_burst_slave_tx_fail(void)
3372 {
3373         struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
3374         struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
3375
3376         struct rte_eth_stats port_stats;
3377
3378         int i, tx_count;
3379
3380         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3381                         BONDING_MODE_BROADCAST, 0,
3382                         TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
3383                         "Failed to intialise bonded device");
3384
3385         /* Generate test bursts for transmission */
3386         TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
3387                         TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
3388                         TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
3389                         "Failed to generate test packet burst");
3390
3391         for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3392                 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3393                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
3394         }
3395
3396         /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
3397          * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
3398         virtual_ethdev_tx_burst_fn_set_success(
3399                         test_params->slave_port_ids[0],
3400                         0);
3401         virtual_ethdev_tx_burst_fn_set_success(
3402                         test_params->slave_port_ids[1],
3403                         0);
3404         virtual_ethdev_tx_burst_fn_set_success(
3405                         test_params->slave_port_ids[2],
3406                         0);
3407
3408         virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3409                         test_params->slave_port_ids[0],
3410                         TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3411
3412         virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3413                         test_params->slave_port_ids[1],
3414                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3415
3416         virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
3417                         test_params->slave_port_ids[2],
3418                         TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3419
3420         /* Transmit burst */
3421         tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
3422                         TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
3423
3424         TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3425                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3426                         "Transmitted (%d) packets, expected to transmit (%d) packets",
3427                         tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3428                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3429
3430         /* Verify that failed packet are expected failed packets */
3431         for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
3432                 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
3433                                 "expected mbuf (%d) pointer %p not expected pointer %p",
3434                                 i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
3435         }
3436
3437         /* Verify slave ports tx stats */
3438
3439         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3440
3441         TEST_ASSERT_EQUAL(port_stats.opackets,
3442                         (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3443                         TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3444                         "Port (%d) opackets value (%u) not as expected (%d)",
3445                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3446                         TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3447                         TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3448
3449
3450         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3451
3452         TEST_ASSERT_EQUAL(port_stats.opackets,
3453                         (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3454                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
3455                         "Port (%d) opackets value (%u) not as expected (%d)",
3456                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3457                         TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3458                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3459
3460         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3461
3462         TEST_ASSERT_EQUAL(port_stats.opackets,
3463                         (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3464                         TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
3465                         "Port (%d) opackets value (%u) not as expected (%d)",
3466                         test_params->bonded_port_id, (unsigned int)port_stats.opackets,
3467                         TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
3468                         TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
3469
3470
3471         /* Verify that all mbufs who transmission failed have a ref value of one */
3472         TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
3473                         TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
3474                         "mbufs refcnts not as expected");
3475
3476         free_mbufs(&pkts_burst[tx_count],
3477                 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
3478
3479         /* Clean up and remove slaves from bonded device */
3480         return remove_slaves_and_stop_bonded_device();
3481 }
3482
3483 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
3484
3485 static int
3486 test_broadcast_rx_burst(void)
3487 {
3488         struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST];
3489
3490         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3491         struct rte_eth_stats port_stats;
3492
3493         int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 };
3494         int i, j;
3495
3496         memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));
3497
3498         /* Initialize bonded device with 4 slaves in round robin mode */
3499         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3500                         BONDING_MODE_BROADCAST, 0, 3, 1),
3501                         "Failed to intialise bonded device");
3502
3503         /* Generate test bursts of packets to transmit */
3504         for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3505                 TEST_ASSERT_EQUAL(generate_test_burst(
3506                                 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0),
3507                                 burst_size[i], "failed to generate packet burst");
3508         }
3509
3510         /* Add rx data to slave 0 */
3511         for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3512                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3513                                 &gen_pkt_burst[i][0], burst_size[i]);
3514         }
3515
3516
3517         /* Call rx burst on bonded device */
3518         /* Send burst on bonded port */
3519         TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3520                         test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3521                         burst_size[0] + burst_size[1] + burst_size[2],
3522                         "rx burst failed");
3523
3524         /* Verify bonded device rx count */
3525         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3526         TEST_ASSERT_EQUAL(port_stats.ipackets,
3527                         (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]),
3528                         "Bonded Port (%d) ipackets value (%u) not as expected (%d)",
3529                         test_params->bonded_port_id, (unsigned int)port_stats.ipackets,
3530                         burst_size[0] + burst_size[1] + burst_size[2]);
3531
3532
3533         /* Verify bonded slave devices rx counts */
3534         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3535         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0],
3536                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3537                         test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3538                         burst_size[0]);
3539
3540         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3541         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1],
3542                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3543                         test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets,
3544                         burst_size[1]);
3545
3546         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3547         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2],
3548                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3549                         test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets,
3550                         burst_size[2]);
3551
3552         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3553         TEST_ASSERT_EQUAL(port_stats.ipackets, 0,
3554                         "Slave Port (%d) ipackets value (%u) not as expected (%d)",
3555                         test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets,
3556                         0);
3557
3558         /* free mbufs allocate for rx testing */
3559         for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) {
3560                 for (j = 0; j < MAX_PKT_BURST; j++) {
3561                         if (gen_pkt_burst[i][j] != NULL) {
3562                                 rte_pktmbuf_free(gen_pkt_burst[i][j]);
3563                                 gen_pkt_burst[i][j] = NULL;
3564                         }
3565                 }
3566         }
3567
3568         /* Clean up and remove slaves from bonded device */
3569         return remove_slaves_and_stop_bonded_device();
3570 }
3571
3572 static int
3573 test_broadcast_verify_promiscuous_enable_disable(void)
3574 {
3575         int i;
3576
3577         /* Initialize bonded device with 4 slaves in round robin mode */
3578         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3579                         BONDING_MODE_BROADCAST, 0, 4, 1),
3580                         "Failed to intialise bonded device");
3581
3582         rte_eth_promiscuous_enable(test_params->bonded_port_id);
3583
3584
3585         TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1,
3586                         "Port (%d) promiscuous mode not enabled",
3587                         test_params->bonded_port_id);
3588
3589         for (i = 0; i < test_params->bonded_slave_count; i++) {
3590                 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3591                                 test_params->slave_port_ids[i]), 1,
3592                                 "Port (%d) promiscuous mode not enabled",
3593                                 test_params->slave_port_ids[i]);
3594         }
3595
3596         rte_eth_promiscuous_disable(test_params->bonded_port_id);
3597
3598         TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0,
3599                         "Port (%d) promiscuous mode not disabled",
3600                         test_params->bonded_port_id);
3601
3602         for (i = 0; i < test_params->bonded_slave_count; i++) {
3603                 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(
3604                                 test_params->slave_port_ids[i]), 0,
3605                                 "Port (%d) promiscuous mode not disabled",
3606                                 test_params->slave_port_ids[i]);
3607         }
3608
3609         /* Clean up and remove slaves from bonded device */
3610         return remove_slaves_and_stop_bonded_device();
3611 }
3612
3613 static int
3614 test_broadcast_verify_mac_assignment(void)
3615 {
3616         struct ether_addr read_mac_addr, expected_mac_addr_0, expected_mac_addr_1;
3617
3618         int i;
3619
3620         rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0);
3621         rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1);
3622
3623         /* Initialize bonded device with 4 slaves in round robin mode */
3624         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3625                         BONDING_MODE_BROADCAST, 0, 4, 1),
3626                         "Failed to intialise bonded device");
3627
3628         /* Verify that all MACs are the same as first slave added to bonded
3629          * device */
3630         for (i = 0; i < test_params->bonded_slave_count; i++) {
3631                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3632                 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3633                                 sizeof(read_mac_addr)),
3634                                 "slave port (%d) mac address not set to that of primary port",
3635                                 test_params->slave_port_ids[i]);
3636         }
3637
3638         /* change primary and verify that MAC addresses haven't changed */
3639         TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id,
3640                         test_params->slave_port_ids[2]),
3641                         "Failed to set bonded port (%d) primary port to (%d)",
3642                         test_params->bonded_port_id, test_params->slave_port_ids[i]);
3643
3644         for (i = 0; i < test_params->bonded_slave_count; i++) {
3645                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3646                 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr,
3647                                 sizeof(read_mac_addr)),
3648                                 "slave port (%d) mac address has changed to that of primary "
3649                                 "port without stop/start toggle of bonded device",
3650                                 test_params->slave_port_ids[i]);
3651         }
3652
3653         /* stop / start bonded device and verify that primary MAC address is
3654          * propagated to bonded device and slaves */
3655
3656         rte_eth_dev_stop(test_params->bonded_port_id);
3657
3658         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id),
3659                         "Failed to start bonded device");
3660
3661         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3662         TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3663                         sizeof(read_mac_addr)),
3664                         "bonded port (%d) mac address not set to that of new primary  port",
3665                         test_params->slave_port_ids[i]);
3666
3667         for (i = 0; i < test_params->bonded_slave_count; i++) {
3668                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3669                 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr,
3670                                 sizeof(read_mac_addr)),
3671                                 "slave port (%d) mac address not set to that of new primary "
3672                                 "port", test_params->slave_port_ids[i]);
3673         }
3674
3675         /* Set explicit MAC address */
3676         TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set(
3677                         test_params->bonded_port_id, (struct ether_addr *)bonded_mac),
3678                         "Failed to set MAC address");
3679
3680         rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr);
3681         TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3682                         sizeof(read_mac_addr)),
3683                         "bonded port (%d) mac address not set to that of new primary port",
3684                         test_params->slave_port_ids[i]);
3685
3686
3687         for (i = 0; i < test_params->bonded_slave_count; i++) {
3688                 rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr);
3689                 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr,
3690                                 sizeof(read_mac_addr)),
3691                                 "slave port (%d) mac address not set to that of new primary "
3692                                 "port", test_params->slave_port_ids[i]);
3693         }
3694
3695         /* Clean up and remove slaves from bonded device */
3696         return remove_slaves_and_stop_bonded_device();
3697 }
3698
3699 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4)
3700 static int
3701 test_broadcast_verify_slave_link_status_change_behaviour(void)
3702 {
3703         struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST];
3704         struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL };
3705         struct rte_eth_stats port_stats;
3706
3707         uint8_t slaves[RTE_MAX_ETHPORTS];
3708
3709         int i, j, burst_size, slave_count;
3710
3711         memset(pkt_burst, 0, sizeof(pkt_burst));
3712
3713         /* Initialize bonded device with 4 slaves in round robin mode */
3714         TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
3715                                 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES,
3716                                 1), "Failed to intialise bonded device");
3717
3718         /* Verify Current Slaves Count /Active Slave Count is */
3719         slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves,
3720                         RTE_MAX_ETHPORTS);
3721         TEST_ASSERT_EQUAL(slave_count, 4,
3722                         "Number of slaves (%d) is not as expected (%d).",
3723                         slave_count, 4);
3724
3725         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3726                         slaves, RTE_MAX_ETHPORTS);
3727         TEST_ASSERT_EQUAL(slave_count, 4,
3728                         "Number of active slaves (%d) is not as expected (%d).",
3729                         slave_count, 4);
3730
3731         /* Set 2 slaves link status to down */
3732         virtual_ethdev_simulate_link_status_interrupt(
3733                         test_params->slave_port_ids[1], 0);
3734         virtual_ethdev_simulate_link_status_interrupt(
3735                         test_params->slave_port_ids[3], 0);
3736
3737         slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
3738                         slaves, RTE_MAX_ETHPORTS);
3739         TEST_ASSERT_EQUAL(slave_count, 2,
3740                         "Number of active slaves (%d) is not as expected (%d).",
3741                         slave_count, 2);
3742
3743         for (i = 0; i < test_params->bonded_slave_count; i++)
3744                 rte_eth_stats_reset(test_params->slave_port_ids[i]);
3745
3746         /* Verify that pkts are not sent on slaves with link status down */
3747         burst_size = 21;
3748
3749         TEST_ASSERT_EQUAL(generate_test_burst(
3750                         &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size,
3751                         "generate_test_burst failed");
3752
3753         TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0,
3754                         &pkt_burst[0][0], burst_size), burst_size,
3755                         "rte_eth_tx_burst failed\n");
3756
3757         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3758         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count),
3759                         "(%d) port_stats.opackets (%d) not as expected (%d)\n",
3760                         test_params->bonded_port_id, (int)port_stats.opackets,
3761                         burst_size * slave_count);
3762
3763         rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
3764         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3765                         "(%d) port_stats.opackets not as expected",
3766                         test_params->slave_port_ids[0]);
3767
3768         rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
3769         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3770                         "(%d) port_stats.opackets not as expected",
3771                                 test_params->slave_port_ids[1]);
3772
3773         rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
3774         TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size,
3775                         "(%d) port_stats.opackets not as expected",
3776                                 test_params->slave_port_ids[2]);
3777
3778
3779         rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats);
3780         TEST_ASSERT_EQUAL(port_stats.opackets, 0,
3781                         "(%d) port_stats.opackets not as expected",
3782                         test_params->slave_port_ids[3]);
3783
3784
3785         for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3786                 TEST_ASSERT_EQUAL(generate_test_burst(
3787                                 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0),
3788                                 burst_size, "failed to generate packet burst");
3789
3790                 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i],
3791                                 &pkt_burst[i][0], burst_size);
3792         }
3793
3794         /* Verify that pkts are not received on slaves with link status down */
3795         TEST_ASSERT_EQUAL(rte_eth_rx_burst(
3796                         test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST),
3797                         burst_size + burst_size, "rte_eth_rx_burst failed");
3798
3799
3800         /* Verify bonded device rx count */
3801         rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
3802         TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size),
3803                         "(%d) port_stats.ipackets not as expected\n",
3804                         test_params->bonded_port_id);
3805
3806         /* free mbufs allocate for rx testing */
3807         for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) {
3808                 for (j = 0; j < MAX_PKT_BURST; j++) {
3809                         if (pkt_burst[i][j] != NULL) {
3810                                 rte_pktmbuf_free(pkt_burst[i][j]);
3811                                 pkt_burst[i][j] = NULL;
3812                         }
3813                 }
3814         }
3815
3816         /* Clean up and remove slaves from bonded device */
3817         return remove_slaves_and_stop_bonded_device();
3818 }
3819 #endif
3820
3821 static int
3822 test_reconfigure_bonded_device(void)
3823 {
3824         test_params->nb_rx_q = 4;
3825         test_params->nb_tx_q = 4;
3826
3827         TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3828                         "failed to reconfigure bonded device");
3829
3830         test_params->nb_rx_q = 2;
3831         test_params->nb_tx_q = 2;
3832
3833         TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
3834                         "failed to reconfigure bonded device with less rx/tx queues");
3835
3836         return 0;
3837 }
3838
3839
3840 static int
3841 test_close_bonded_device(void)
3842 {
3843         rte_eth_dev_close(test_params->bonded_port_id);
3844         return 0;
3845 }
3846
3847 static int
3848 testsuite_teardown(void)
3849 {
3850         if (test_params->pkt_eth_hdr != NULL) {
3851                 free(test_params->pkt_eth_hdr);
3852                 test_params->pkt_eth_hdr = NULL;
3853         }
3854
3855         /* Clean up and remove slaves from bonded device */
3856         return remove_slaves_and_stop_bonded_device();
3857 }
3858
3859
3860 static struct unit_test_suite link_bonding_test_suite  = {
3861         .suite_name = "Link Bonding Unit Test Suite",
3862         .setup = test_setup,
3863         .teardown = testsuite_teardown,
3864         .unit_test_cases = {
3865                 TEST_CASE(test_create_bonded_device),
3866                 TEST_CASE(test_create_bonded_device_with_invalid_params),
3867                 TEST_CASE(test_add_slave_to_bonded_device),
3868                 TEST_CASE(test_add_slave_to_invalid_bonded_device),
3869                 TEST_CASE(test_remove_slave_from_bonded_device),
3870                 TEST_CASE(test_remove_slave_from_invalid_bonded_device),
3871                 TEST_CASE(test_get_slaves_from_bonded_device),
3872                 TEST_CASE(test_add_already_bonded_slave_to_bonded_device),
3873                 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device),
3874                 TEST_CASE(test_start_bonded_device),
3875                 TEST_CASE(test_stop_bonded_device),
3876                 TEST_CASE(test_set_bonding_mode),
3877                 TEST_CASE(test_set_primary_slave),
3878                 TEST_CASE(test_set_explicit_bonded_mac),
3879                 TEST_CASE(test_status_interrupt),
3880                 TEST_CASE(test_adding_slave_after_bonded_device_started),
3881                 TEST_CASE(test_roundrobin_tx_burst),
3882                 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
3883                 TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
3884                 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
3885                 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
3886                 TEST_CASE(test_roundrobin_verify_mac_assignment),
3887                 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
3888                 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
3889                 TEST_CASE(test_activebackup_tx_burst),
3890                 TEST_CASE(test_activebackup_rx_burst),
3891                 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
3892                 TEST_CASE(test_activebackup_verify_mac_assignment),
3893                 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover),
3894                 TEST_CASE(test_balance_xmit_policy_configuration),
3895                 TEST_CASE(test_balance_l2_tx_burst),
3896                 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr),
3897                 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr),
3898                 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr),
3899                 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr),
3900                 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr),
3901                 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr),
3902                 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port),
3903                 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr),
3904                 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
3905                 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
3906                 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
3907                 TEST_CASE(test_balance_tx_burst_slave_tx_fail),
3908                 TEST_CASE(test_balance_rx_burst),
3909                 TEST_CASE(test_balance_verify_promiscuous_enable_disable),
3910                 TEST_CASE(test_balance_verify_mac_assignment),
3911                 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
3912 #ifdef RTE_MBUF_REFCNT
3913                 TEST_CASE(test_broadcast_tx_burst),
3914                 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
3915                 TEST_CASE(test_broadcast_rx_burst),
3916                 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
3917                 TEST_CASE(test_broadcast_verify_mac_assignment),
3918                 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour),
3919 #endif
3920                 TEST_CASE(test_reconfigure_bonded_device),
3921                 TEST_CASE(test_close_bonded_device),
3922
3923                 { NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
3924         }
3925 };
3926
3927
3928 static int
3929 test_link_bonding(void)
3930 {
3931         return unit_test_suite_runner(&link_bonding_test_suite);
3932 }
3933
3934 static struct test_command link_bonding_cmd = {
3935         .command = "link_bonding_autotest",
3936         .callback = test_link_bonding,
3937 };
3938 REGISTER_TEST_COMMAND(link_bonding_cmd);