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