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