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