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