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