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