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