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