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