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