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