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