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