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