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