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