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