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