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