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 if (rx_pkt_burst[i] != NULL) 1643 rte_pktmbuf_free(rx_pkt_burst[i]); 1644 } 1645 1646 1647 /* Clean up and remove slaves from bonded device */ 1648 return remove_slaves_and_stop_bonded_device(); 1649 } 1650 1651 #define TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT (3) 1652 1653 static int 1654 test_roundrobin_rx_burst_on_multiple_slaves(void) 1655 { 1656 struct rte_mbuf *gen_pkt_burst[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; 1657 1658 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 1659 struct rte_eth_stats port_stats; 1660 1661 int burst_size[TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT] = { 15, 13, 36 }; 1662 int i, nb_rx; 1663 1664 /* Initialize bonded device with 4 slaves in round robin mode */ 1665 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 1666 BONDING_MODE_ROUND_ROBIN, 0, 4, 1), 1667 "Failed to initialize bonded device with slaves"); 1668 1669 /* Generate test bursts of packets to transmit */ 1670 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) { 1671 TEST_ASSERT_EQUAL(generate_test_burst( 1672 &gen_pkt_burst[i][0], burst_size[i], 0, 1, 0, 0, 0), 1673 burst_size[i], "burst generation failed"); 1674 } 1675 1676 /* Add rx data to slaves */ 1677 for (i = 0; i < TEST_ROUNDROBIN_TX_BURST_SLAVE_COUNT; i++) { 1678 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 1679 &gen_pkt_burst[i][0], burst_size[i]); 1680 } 1681 1682 /* Call rx burst on bonded device */ 1683 /* Send burst on bonded port */ 1684 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, 1685 MAX_PKT_BURST); 1686 TEST_ASSERT_EQUAL(nb_rx , burst_size[0] + burst_size[1] + burst_size[2], 1687 "round-robin rx burst failed (%d != %d)\n", nb_rx, 1688 burst_size[0] + burst_size[1] + burst_size[2]); 1689 1690 /* Verify bonded device rx count */ 1691 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 1692 TEST_ASSERT_EQUAL(port_stats.ipackets, 1693 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), 1694 "Bonded Port (%d) ipackets value (%u) not as expected (%d)", 1695 test_params->bonded_port_id, (unsigned int)port_stats.ipackets, 1696 burst_size[0] + burst_size[1] + burst_size[2]); 1697 1698 /* Verify bonded slave devices rx counts */ 1699 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 1700 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], 1701 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 1702 test_params->slave_port_ids[0], 1703 (unsigned int)port_stats.ipackets, burst_size[0]); 1704 1705 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 1706 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], 1707 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 1708 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets, 1709 burst_size[1]); 1710 1711 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 1712 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], 1713 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 1714 test_params->slave_port_ids[2], 1715 (unsigned int)port_stats.ipackets, burst_size[2]); 1716 1717 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 1718 TEST_ASSERT_EQUAL(port_stats.ipackets, 0, 1719 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 1720 test_params->slave_port_ids[3], 1721 (unsigned int)port_stats.ipackets, 0); 1722 1723 /* free mbufs */ 1724 for (i = 0; i < MAX_PKT_BURST; i++) { 1725 if (rx_pkt_burst[i] != NULL) 1726 rte_pktmbuf_free(rx_pkt_burst[i]); 1727 } 1728 1729 /* Clean up and remove slaves from bonded device */ 1730 return remove_slaves_and_stop_bonded_device(); 1731 } 1732 1733 static int 1734 test_roundrobin_verify_mac_assignment(void) 1735 { 1736 struct rte_ether_addr read_mac_addr; 1737 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_2; 1738 1739 int i; 1740 1741 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0), 1742 "Failed to get mac address (port %d)", 1743 test_params->slave_port_ids[0]); 1744 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_2), 1745 "Failed to get mac address (port %d)", 1746 test_params->slave_port_ids[2]); 1747 1748 /* Initialize bonded device with 4 slaves in round robin mode */ 1749 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 1750 BONDING_MODE_ROUND_ROBIN, 0, 4, 1), 1751 "Failed to initialize bonded device with slaves"); 1752 1753 /* Verify that all MACs are the same as first slave added to bonded dev */ 1754 for (i = 0; i < test_params->bonded_slave_count; i++) { 1755 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 1756 "Failed to get mac address (port %d)", 1757 test_params->slave_port_ids[i]); 1758 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 1759 sizeof(read_mac_addr)), 1760 "slave port (%d) mac address not set to that of primary port", 1761 test_params->slave_port_ids[i]); 1762 } 1763 1764 /* change primary and verify that MAC addresses haven't changed */ 1765 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, 1766 test_params->slave_port_ids[2]), 1767 "Failed to set bonded port (%d) primary port to (%d)", 1768 test_params->bonded_port_id, test_params->slave_port_ids[i]); 1769 1770 for (i = 0; i < test_params->bonded_slave_count; i++) { 1771 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 1772 "Failed to get mac address (port %d)", 1773 test_params->slave_port_ids[i]); 1774 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 1775 sizeof(read_mac_addr)), 1776 "slave port (%d) mac address has changed to that of primary" 1777 " port without stop/start toggle of bonded device", 1778 test_params->slave_port_ids[i]); 1779 } 1780 1781 /* stop / start bonded device and verify that primary MAC address is 1782 * propagate to bonded device and slaves */ 1783 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id), 1784 "Failed to stop bonded port %u", 1785 test_params->bonded_port_id); 1786 1787 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), 1788 "Failed to start bonded device"); 1789 1790 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 1791 "Failed to get mac address (port %d)", 1792 test_params->bonded_port_id); 1793 TEST_ASSERT_SUCCESS( 1794 memcmp(&expected_mac_addr_2, &read_mac_addr, sizeof(read_mac_addr)), 1795 "bonded port (%d) mac address not set to that of new primary port", 1796 test_params->slave_port_ids[i]); 1797 1798 for (i = 0; i < test_params->bonded_slave_count; i++) { 1799 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 1800 "Failed to get mac address (port %d)", 1801 test_params->slave_port_ids[i]); 1802 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_2, &read_mac_addr, 1803 sizeof(read_mac_addr)), 1804 "slave port (%d) mac address not set to that of new primary" 1805 " port", test_params->slave_port_ids[i]); 1806 } 1807 1808 /* Set explicit MAC address */ 1809 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( 1810 test_params->bonded_port_id, 1811 (struct rte_ether_addr *)bonded_mac), 1812 "Failed to set MAC"); 1813 1814 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 1815 "Failed to get mac address (port %d)", 1816 test_params->bonded_port_id); 1817 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, 1818 sizeof(read_mac_addr)), 1819 "bonded port (%d) mac address not set to that of new primary port", 1820 test_params->slave_port_ids[i]); 1821 1822 for (i = 0; i < test_params->bonded_slave_count; i++) { 1823 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 1824 "Failed to get mac address (port %d)", 1825 test_params->slave_port_ids[i]); 1826 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, 1827 sizeof(read_mac_addr)), "slave port (%d) mac address not set to" 1828 " that of new primary port\n", test_params->slave_port_ids[i]); 1829 } 1830 1831 /* Clean up and remove slaves from bonded device */ 1832 return remove_slaves_and_stop_bonded_device(); 1833 } 1834 1835 static int 1836 test_roundrobin_verify_promiscuous_enable_disable(void) 1837 { 1838 int i, promiscuous_en; 1839 int ret; 1840 1841 /* Initialize bonded device with 4 slaves in round robin mode */ 1842 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 1843 BONDING_MODE_ROUND_ROBIN, 0, 4, 1), 1844 "Failed to initialize bonded device with slaves"); 1845 1846 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id); 1847 TEST_ASSERT_SUCCESS(ret, 1848 "Failed to enable promiscuous mode for port %d: %s", 1849 test_params->bonded_port_id, rte_strerror(-ret)); 1850 1851 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); 1852 TEST_ASSERT_EQUAL(promiscuous_en, 1, 1853 "Port (%d) promiscuous mode not enabled", 1854 test_params->bonded_port_id); 1855 1856 for (i = 0; i < test_params->bonded_slave_count; i++) { 1857 promiscuous_en = rte_eth_promiscuous_get( 1858 test_params->slave_port_ids[i]); 1859 TEST_ASSERT_EQUAL(promiscuous_en, 1, 1860 "slave port (%d) promiscuous mode not enabled", 1861 test_params->slave_port_ids[i]); 1862 } 1863 1864 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id); 1865 TEST_ASSERT_SUCCESS(ret, 1866 "Failed to disable promiscuous mode for port %d: %s", 1867 test_params->bonded_port_id, rte_strerror(-ret)); 1868 1869 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); 1870 TEST_ASSERT_EQUAL(promiscuous_en, 0, 1871 "Port (%d) promiscuous mode not disabled\n", 1872 test_params->bonded_port_id); 1873 1874 for (i = 0; i < test_params->bonded_slave_count; i++) { 1875 promiscuous_en = rte_eth_promiscuous_get( 1876 test_params->slave_port_ids[i]); 1877 TEST_ASSERT_EQUAL(promiscuous_en, 0, 1878 "Port (%d) promiscuous mode not disabled\n", 1879 test_params->slave_port_ids[i]); 1880 } 1881 1882 /* Clean up and remove slaves from bonded device */ 1883 return remove_slaves_and_stop_bonded_device(); 1884 } 1885 1886 #define TEST_RR_LINK_STATUS_SLAVE_COUNT (4) 1887 #define TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT (2) 1888 1889 static int 1890 test_roundrobin_verify_slave_link_status_change_behaviour(void) 1891 { 1892 struct rte_mbuf *tx_pkt_burst[MAX_PKT_BURST] = { NULL }; 1893 struct rte_mbuf *gen_pkt_burst[TEST_RR_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST]; 1894 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 1895 1896 struct rte_eth_stats port_stats; 1897 uint16_t slaves[RTE_MAX_ETHPORTS]; 1898 1899 int i, burst_size, slave_count; 1900 1901 /* NULL all pointers in array to simplify cleanup */ 1902 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); 1903 1904 /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves 1905 * in round robin mode */ 1906 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 1907 BONDING_MODE_ROUND_ROBIN, 0, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1), 1908 "Failed to initialize bonded device with slaves"); 1909 1910 /* Verify Current Slaves Count /Active Slave Count is */ 1911 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, 1912 RTE_MAX_ETHPORTS); 1913 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1914 "Number of slaves (%d) is not as expected (%d).", 1915 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT); 1916 1917 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 1918 slaves, RTE_MAX_ETHPORTS); 1919 TEST_ASSERT_EQUAL(slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT, 1920 "Number of active slaves (%d) is not as expected (%d).", 1921 slave_count, TEST_RR_LINK_STATUS_SLAVE_COUNT); 1922 1923 /* Set 2 slaves eth_devs link status to down */ 1924 virtual_ethdev_simulate_link_status_interrupt( 1925 test_params->slave_port_ids[1], 0); 1926 virtual_ethdev_simulate_link_status_interrupt( 1927 test_params->slave_port_ids[3], 0); 1928 1929 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 1930 slaves, RTE_MAX_ETHPORTS); 1931 TEST_ASSERT_EQUAL(slave_count, 1932 TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT, 1933 "Number of active slaves (%d) is not as expected (%d).\n", 1934 slave_count, TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT); 1935 1936 burst_size = 20; 1937 1938 /* Verify that pkts are not sent on slaves with link status down: 1939 * 1940 * 1. Generate test burst of traffic 1941 * 2. Transmit burst on bonded eth_dev 1942 * 3. Verify stats for bonded eth_dev (opackets = burst_size) 1943 * 4. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0) 1944 */ 1945 TEST_ASSERT_EQUAL( 1946 generate_test_burst(tx_pkt_burst, burst_size, 0, 1, 0, 0, 0), 1947 burst_size, "generate_test_burst failed"); 1948 1949 rte_eth_stats_reset(test_params->bonded_port_id); 1950 1951 1952 TEST_ASSERT_EQUAL( 1953 rte_eth_tx_burst(test_params->bonded_port_id, 0, tx_pkt_burst, 1954 burst_size), burst_size, "rte_eth_tx_burst failed"); 1955 1956 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 1957 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 1958 "Port (%d) opackets stats (%d) not expected (%d) value", 1959 test_params->bonded_port_id, (int)port_stats.opackets, 1960 burst_size); 1961 1962 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 1963 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10, 1964 "Port (%d) opackets stats (%d) not expected (%d) value", 1965 test_params->slave_port_ids[0], (int)port_stats.opackets, 10); 1966 1967 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 1968 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0, 1969 "Port (%d) opackets stats (%d) not expected (%d) value", 1970 test_params->slave_port_ids[1], (int)port_stats.opackets, 0); 1971 1972 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 1973 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)10, 1974 "Port (%d) opackets stats (%d) not expected (%d) value", 1975 test_params->slave_port_ids[2], (int)port_stats.opackets, 10); 1976 1977 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 1978 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)0, 1979 "Port (%d) opackets stats (%d) not expected (%d) value", 1980 test_params->slave_port_ids[3], (int)port_stats.opackets, 0); 1981 1982 /* Verify that pkts are not sent on slaves with link status down: 1983 * 1984 * 1. Generate test bursts of traffic 1985 * 2. Add bursts on to virtual eth_devs 1986 * 3. Rx burst on bonded eth_dev, expected (burst_ size * 1987 * TEST_RR_LINK_STATUS_EXPECTED_ACTIVE_SLAVE_COUNT) received 1988 * 4. Verify stats for bonded eth_dev 1989 * 6. Verify stats for slave eth_devs (s0 = 10, s1 = 0, s2 = 10, s3 = 0) 1990 */ 1991 for (i = 0; i < TEST_RR_LINK_STATUS_SLAVE_COUNT; i++) { 1992 TEST_ASSERT_EQUAL(generate_test_burst( 1993 &gen_pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), 1994 burst_size, "failed to generate packet burst"); 1995 1996 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 1997 &gen_pkt_burst[i][0], burst_size); 1998 } 1999 2000 TEST_ASSERT_EQUAL(rte_eth_rx_burst( 2001 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), 2002 burst_size + burst_size, 2003 "rte_eth_rx_burst failed"); 2004 2005 /* Verify bonded device rx count */ 2006 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2007 TEST_ASSERT_EQUAL(port_stats.ipackets , (uint64_t)(burst_size + burst_size), 2008 "(%d) port_stats.ipackets not as expected\n", 2009 test_params->bonded_port_id); 2010 2011 /* free mbufs */ 2012 for (i = 0; i < MAX_PKT_BURST; i++) { 2013 if (rx_pkt_burst[i] != NULL) 2014 rte_pktmbuf_free(rx_pkt_burst[i]); 2015 } 2016 2017 /* Clean up and remove slaves from bonded device */ 2018 return remove_slaves_and_stop_bonded_device(); 2019 } 2020 2021 #define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2) 2022 2023 uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 }; 2024 2025 2026 int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 }; 2027 2028 static int 2029 test_roundrobin_verfiy_polling_slave_link_status_change(void) 2030 { 2031 struct rte_ether_addr *mac_addr = 2032 (struct rte_ether_addr *)polling_slave_mac; 2033 char slave_name[RTE_ETH_NAME_MAX_LEN]; 2034 2035 int i; 2036 2037 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) { 2038 /* Generate slave name / MAC address */ 2039 snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i); 2040 mac_addr->addr_bytes[RTE_ETHER_ADDR_LEN-1] = i; 2041 2042 /* Create slave devices with no ISR Support */ 2043 if (polling_test_slaves[i] == -1) { 2044 polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr, 2045 rte_socket_id(), 0); 2046 TEST_ASSERT(polling_test_slaves[i] >= 0, 2047 "Failed to create virtual virtual ethdev %s\n", slave_name); 2048 2049 /* Configure slave */ 2050 TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0), 2051 "Failed to configure virtual ethdev %s(%d)", slave_name, 2052 polling_test_slaves[i]); 2053 } 2054 2055 /* Add slave to bonded device */ 2056 TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id, 2057 polling_test_slaves[i]), 2058 "Failed to add slave %s(%d) to bonded device %d", 2059 slave_name, polling_test_slaves[i], 2060 test_params->bonded_port_id); 2061 } 2062 2063 /* Initialize bonded device */ 2064 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1), 2065 "Failed to configure bonded device %d", 2066 test_params->bonded_port_id); 2067 2068 2069 /* Register link status change interrupt callback */ 2070 rte_eth_dev_callback_register(test_params->bonded_port_id, 2071 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, 2072 &test_params->bonded_port_id); 2073 2074 /* link status change callback for first slave link up */ 2075 test_lsc_interrupt_count = 0; 2076 2077 virtual_ethdev_set_link_status(polling_test_slaves[0], 1); 2078 2079 TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt"); 2080 2081 2082 /* no link status change callback for second slave link up */ 2083 test_lsc_interrupt_count = 0; 2084 2085 virtual_ethdev_set_link_status(polling_test_slaves[1], 1); 2086 2087 TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded"); 2088 2089 /* link status change callback for both slave links down */ 2090 test_lsc_interrupt_count = 0; 2091 2092 virtual_ethdev_set_link_status(polling_test_slaves[0], 0); 2093 virtual_ethdev_set_link_status(polling_test_slaves[1], 0); 2094 2095 TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt"); 2096 2097 /* Un-Register link status change interrupt callback */ 2098 rte_eth_dev_callback_unregister(test_params->bonded_port_id, 2099 RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback, 2100 &test_params->bonded_port_id); 2101 2102 2103 /* Clean up and remove slaves from bonded device */ 2104 for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) { 2105 2106 TEST_ASSERT_SUCCESS( 2107 rte_eth_bond_slave_remove(test_params->bonded_port_id, 2108 polling_test_slaves[i]), 2109 "Failed to remove slave %d from bonded port (%d)", 2110 polling_test_slaves[i], test_params->bonded_port_id); 2111 } 2112 2113 return remove_slaves_and_stop_bonded_device(); 2114 } 2115 2116 2117 /** Active Backup Mode Tests */ 2118 2119 static int 2120 test_activebackup_tx_burst(void) 2121 { 2122 int i, pktlen, primary_port, burst_size; 2123 struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 2124 struct rte_eth_stats port_stats; 2125 2126 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2127 BONDING_MODE_ACTIVE_BACKUP, 0, 1, 1), 2128 "Failed to initialize bonded device with slaves"); 2129 2130 initialize_eth_header(test_params->pkt_eth_hdr, 2131 (struct rte_ether_addr *)src_mac, 2132 (struct rte_ether_addr *)dst_mac_0, 2133 RTE_ETHER_TYPE_IPV4, 0, 0); 2134 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, 2135 dst_port_0, 16); 2136 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, 2137 dst_addr_0, pktlen); 2138 2139 burst_size = 20 * test_params->bonded_slave_count; 2140 2141 TEST_ASSERT(burst_size < MAX_PKT_BURST, 2142 "Burst size specified is greater than supported."); 2143 2144 /* Generate a burst of packets to transmit */ 2145 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, pkts_burst, 2146 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, 2147 test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 1), 2148 burst_size, "failed to generate burst correctly"); 2149 2150 /* Send burst on bonded port */ 2151 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst, 2152 burst_size), burst_size, "tx burst failed"); 2153 2154 /* Verify bonded port tx stats */ 2155 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2156 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 2157 "Bonded Port (%d) opackets value (%u) not as expected (%d)", 2158 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 2159 burst_size); 2160 2161 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 2162 2163 /* Verify slave ports tx stats */ 2164 for (i = 0; i < test_params->bonded_slave_count; i++) { 2165 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); 2166 if (test_params->slave_port_ids[i] == primary_port) { 2167 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 2168 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2169 test_params->bonded_port_id, 2170 (unsigned int)port_stats.opackets, 2171 burst_size / test_params->bonded_slave_count); 2172 } else { 2173 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2174 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2175 test_params->bonded_port_id, 2176 (unsigned int)port_stats.opackets, 0); 2177 } 2178 } 2179 2180 /* Put all slaves down and try and transmit */ 2181 for (i = 0; i < test_params->bonded_slave_count; i++) { 2182 virtual_ethdev_simulate_link_status_interrupt( 2183 test_params->slave_port_ids[i], 0); 2184 } 2185 2186 /* Send burst on bonded port */ 2187 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, 2188 pkts_burst, burst_size), 0, "Sending empty burst failed"); 2189 2190 /* Clean up and remove slaves from bonded device */ 2191 return remove_slaves_and_stop_bonded_device(); 2192 } 2193 2194 #define TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT (4) 2195 2196 static int 2197 test_activebackup_rx_burst(void) 2198 { 2199 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; 2200 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 2201 2202 struct rte_eth_stats port_stats; 2203 2204 int primary_port; 2205 2206 int i, j, burst_size = 17; 2207 2208 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2209 BONDING_MODE_ACTIVE_BACKUP, 0, 2210 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1), 2211 "Failed to initialize bonded device with slaves"); 2212 2213 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 2214 TEST_ASSERT(primary_port >= 0, 2215 "failed to get primary slave for bonded port (%d)", 2216 test_params->bonded_port_id); 2217 2218 for (i = 0; i < test_params->bonded_slave_count; i++) { 2219 /* Generate test bursts of packets to transmit */ 2220 TEST_ASSERT_EQUAL(generate_test_burst( 2221 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), 2222 burst_size, "burst generation failed"); 2223 2224 /* Add rx data to slave */ 2225 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 2226 &gen_pkt_burst[0], burst_size); 2227 2228 /* Call rx burst on bonded device */ 2229 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0, 2230 &rx_pkt_burst[0], MAX_PKT_BURST), burst_size, 2231 "rte_eth_rx_burst failed"); 2232 2233 if (test_params->slave_port_ids[i] == primary_port) { 2234 /* Verify bonded device rx count */ 2235 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2236 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, 2237 "Bonded Port (%d) ipackets value (%u) not as expected (%d)", 2238 test_params->bonded_port_id, 2239 (unsigned int)port_stats.ipackets, burst_size); 2240 2241 /* Verify bonded slave devices rx count */ 2242 for (j = 0; j < test_params->bonded_slave_count; j++) { 2243 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); 2244 if (i == j) { 2245 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, 2246 "Slave Port (%d) ipackets value (%u) not as " 2247 "expected (%d)", test_params->slave_port_ids[i], 2248 (unsigned int)port_stats.ipackets, burst_size); 2249 } else { 2250 TEST_ASSERT_EQUAL(port_stats.ipackets, 0, 2251 "Slave Port (%d) ipackets value (%u) not as " 2252 "expected (%d)\n", test_params->slave_port_ids[i], 2253 (unsigned int)port_stats.ipackets, 0); 2254 } 2255 } 2256 } else { 2257 for (j = 0; j < test_params->bonded_slave_count; j++) { 2258 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); 2259 TEST_ASSERT_EQUAL(port_stats.ipackets, 0, 2260 "Slave Port (%d) ipackets value (%u) not as expected " 2261 "(%d)", test_params->slave_port_ids[i], 2262 (unsigned int)port_stats.ipackets, 0); 2263 } 2264 } 2265 2266 /* free mbufs */ 2267 for (i = 0; i < MAX_PKT_BURST; i++) { 2268 if (rx_pkt_burst[i] != NULL) { 2269 rte_pktmbuf_free(rx_pkt_burst[i]); 2270 rx_pkt_burst[i] = NULL; 2271 } 2272 } 2273 2274 /* reset bonded device stats */ 2275 rte_eth_stats_reset(test_params->bonded_port_id); 2276 } 2277 2278 /* Clean up and remove slaves from bonded device */ 2279 return remove_slaves_and_stop_bonded_device(); 2280 } 2281 2282 static int 2283 test_activebackup_verify_promiscuous_enable_disable(void) 2284 { 2285 int i, primary_port, promiscuous_en; 2286 int ret; 2287 2288 /* Initialize bonded device with 4 slaves in round robin mode */ 2289 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2290 BONDING_MODE_ACTIVE_BACKUP, 0, 4, 1), 2291 "Failed to initialize bonded device with slaves"); 2292 2293 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 2294 TEST_ASSERT(primary_port >= 0, 2295 "failed to get primary slave for bonded port (%d)", 2296 test_params->bonded_port_id); 2297 2298 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id); 2299 TEST_ASSERT_SUCCESS(ret, 2300 "Failed to enable promiscuous mode for port %d: %s", 2301 test_params->bonded_port_id, rte_strerror(-ret)); 2302 2303 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, 2304 "Port (%d) promiscuous mode not enabled", 2305 test_params->bonded_port_id); 2306 2307 for (i = 0; i < test_params->bonded_slave_count; i++) { 2308 promiscuous_en = rte_eth_promiscuous_get( 2309 test_params->slave_port_ids[i]); 2310 if (primary_port == test_params->slave_port_ids[i]) { 2311 TEST_ASSERT_EQUAL(promiscuous_en, 1, 2312 "slave port (%d) promiscuous mode not enabled", 2313 test_params->slave_port_ids[i]); 2314 } else { 2315 TEST_ASSERT_EQUAL(promiscuous_en, 0, 2316 "slave port (%d) promiscuous mode enabled", 2317 test_params->slave_port_ids[i]); 2318 } 2319 2320 } 2321 2322 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id); 2323 TEST_ASSERT_SUCCESS(ret, 2324 "Failed to disable promiscuous mode for port %d: %s", 2325 test_params->bonded_port_id, rte_strerror(-ret)); 2326 2327 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, 2328 "Port (%d) promiscuous mode not disabled\n", 2329 test_params->bonded_port_id); 2330 2331 for (i = 0; i < test_params->bonded_slave_count; i++) { 2332 promiscuous_en = rte_eth_promiscuous_get( 2333 test_params->slave_port_ids[i]); 2334 TEST_ASSERT_EQUAL(promiscuous_en, 0, 2335 "slave port (%d) promiscuous mode not disabled\n", 2336 test_params->slave_port_ids[i]); 2337 } 2338 2339 /* Clean up and remove slaves from bonded device */ 2340 return remove_slaves_and_stop_bonded_device(); 2341 } 2342 2343 static int 2344 test_activebackup_verify_mac_assignment(void) 2345 { 2346 struct rte_ether_addr read_mac_addr; 2347 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1; 2348 2349 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0), 2350 "Failed to get mac address (port %d)", 2351 test_params->slave_port_ids[0]); 2352 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1), 2353 "Failed to get mac address (port %d)", 2354 test_params->slave_port_ids[1]); 2355 2356 /* Initialize bonded device with 2 slaves in active backup mode */ 2357 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2358 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1), 2359 "Failed to initialize bonded device with slaves"); 2360 2361 /* Verify that bonded MACs is that of first slave and that the other slave 2362 * MAC hasn't been changed */ 2363 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 2364 "Failed to get mac address (port %d)", 2365 test_params->bonded_port_id); 2366 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 2367 sizeof(read_mac_addr)), 2368 "bonded port (%d) mac address not set to that of primary port", 2369 test_params->bonded_port_id); 2370 2371 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 2372 "Failed to get mac address (port %d)", 2373 test_params->slave_port_ids[0]); 2374 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 2375 sizeof(read_mac_addr)), 2376 "slave port (%d) mac address not set to that of primary port", 2377 test_params->slave_port_ids[0]); 2378 2379 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 2380 "Failed to get mac address (port %d)", 2381 test_params->slave_port_ids[1]); 2382 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 2383 sizeof(read_mac_addr)), 2384 "slave port (%d) mac address not as expected", 2385 test_params->slave_port_ids[1]); 2386 2387 /* change primary and verify that MAC addresses haven't changed */ 2388 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id, 2389 test_params->slave_port_ids[1]), 0, 2390 "Failed to set bonded port (%d) primary port to (%d)", 2391 test_params->bonded_port_id, test_params->slave_port_ids[1]); 2392 2393 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 2394 "Failed to get mac address (port %d)", 2395 test_params->bonded_port_id); 2396 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 2397 sizeof(read_mac_addr)), 2398 "bonded port (%d) mac address not set to that of primary port", 2399 test_params->bonded_port_id); 2400 2401 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 2402 "Failed to get mac address (port %d)", 2403 test_params->slave_port_ids[0]); 2404 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 2405 sizeof(read_mac_addr)), 2406 "slave port (%d) mac address not set to that of primary port", 2407 test_params->slave_port_ids[0]); 2408 2409 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 2410 "Failed to get mac address (port %d)", 2411 test_params->slave_port_ids[1]); 2412 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 2413 sizeof(read_mac_addr)), 2414 "slave port (%d) mac address not as expected", 2415 test_params->slave_port_ids[1]); 2416 2417 /* stop / start bonded device and verify that primary MAC address is 2418 * propagated to bonded device and slaves */ 2419 2420 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id), 2421 "Failed to stop bonded port %u", 2422 test_params->bonded_port_id); 2423 2424 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), 2425 "Failed to start device"); 2426 2427 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 2428 "Failed to get mac address (port %d)", 2429 test_params->bonded_port_id); 2430 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 2431 sizeof(read_mac_addr)), 2432 "bonded port (%d) mac address not set to that of primary port", 2433 test_params->bonded_port_id); 2434 2435 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 2436 "Failed to get mac address (port %d)", 2437 test_params->slave_port_ids[0]); 2438 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 2439 sizeof(read_mac_addr)), 2440 "slave port (%d) mac address not as expected", 2441 test_params->slave_port_ids[0]); 2442 2443 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 2444 "Failed to get mac address (port %d)", 2445 test_params->slave_port_ids[1]); 2446 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 2447 sizeof(read_mac_addr)), 2448 "slave port (%d) mac address not set to that of primary port", 2449 test_params->slave_port_ids[1]); 2450 2451 /* Set explicit MAC address */ 2452 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( 2453 test_params->bonded_port_id, 2454 (struct rte_ether_addr *)bonded_mac), 2455 "failed to set MAC address"); 2456 2457 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 2458 "Failed to get mac address (port %d)", 2459 test_params->bonded_port_id); 2460 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 2461 sizeof(read_mac_addr)), 2462 "bonded port (%d) mac address not set to that of bonded port", 2463 test_params->bonded_port_id); 2464 2465 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 2466 "Failed to get mac address (port %d)", 2467 test_params->slave_port_ids[0]); 2468 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 2469 sizeof(read_mac_addr)), 2470 "slave port (%d) mac address not as expected", 2471 test_params->slave_port_ids[0]); 2472 2473 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 2474 "Failed to get mac address (port %d)", 2475 test_params->slave_port_ids[1]); 2476 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 2477 sizeof(read_mac_addr)), 2478 "slave port (%d) mac address not set to that of bonded port", 2479 test_params->slave_port_ids[1]); 2480 2481 /* Clean up and remove slaves from bonded device */ 2482 return remove_slaves_and_stop_bonded_device(); 2483 } 2484 2485 static int 2486 test_activebackup_verify_slave_link_status_change_failover(void) 2487 { 2488 struct rte_mbuf *pkt_burst[TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; 2489 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 2490 struct rte_eth_stats port_stats; 2491 2492 uint16_t slaves[RTE_MAX_ETHPORTS]; 2493 2494 int i, burst_size, slave_count, primary_port; 2495 2496 burst_size = 21; 2497 2498 memset(pkt_burst, 0, sizeof(pkt_burst)); 2499 2500 /* Generate packet burst for testing */ 2501 TEST_ASSERT_EQUAL(generate_test_burst( 2502 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, 2503 "generate_test_burst failed"); 2504 2505 /* Initialize bonded device with 4 slaves in round robin mode */ 2506 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2507 BONDING_MODE_ACTIVE_BACKUP, 0, 2508 TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1), 2509 "Failed to initialize bonded device with slaves"); 2510 2511 /* Verify Current Slaves Count /Active Slave Count is */ 2512 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, 2513 RTE_MAX_ETHPORTS); 2514 TEST_ASSERT_EQUAL(slave_count, 4, 2515 "Number of slaves (%d) is not as expected (%d).", 2516 slave_count, 4); 2517 2518 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 2519 slaves, RTE_MAX_ETHPORTS); 2520 TEST_ASSERT_EQUAL(slave_count, 4, 2521 "Number of active slaves (%d) is not as expected (%d).", 2522 slave_count, 4); 2523 2524 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 2525 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], 2526 "Primary port not as expected"); 2527 2528 /* Bring 2 slaves down and verify active slave count */ 2529 virtual_ethdev_simulate_link_status_interrupt( 2530 test_params->slave_port_ids[1], 0); 2531 virtual_ethdev_simulate_link_status_interrupt( 2532 test_params->slave_port_ids[3], 0); 2533 2534 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( 2535 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, 2536 "Number of active slaves (%d) is not as expected (%d).", 2537 slave_count, 2); 2538 2539 virtual_ethdev_simulate_link_status_interrupt( 2540 test_params->slave_port_ids[1], 1); 2541 virtual_ethdev_simulate_link_status_interrupt( 2542 test_params->slave_port_ids[3], 1); 2543 2544 2545 /* Bring primary port down, verify that active slave count is 3 and primary 2546 * has changed */ 2547 virtual_ethdev_simulate_link_status_interrupt( 2548 test_params->slave_port_ids[0], 0); 2549 2550 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( 2551 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2552 3, 2553 "Number of active slaves (%d) is not as expected (%d).", 2554 slave_count, 3); 2555 2556 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 2557 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2], 2558 "Primary port not as expected"); 2559 2560 /* Verify that pkts are sent on new primary slave */ 2561 2562 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 2563 test_params->bonded_port_id, 0, &pkt_burst[0][0], 2564 burst_size), burst_size, "rte_eth_tx_burst failed"); 2565 2566 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 2567 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 2568 "(%d) port_stats.opackets not as expected", 2569 test_params->slave_port_ids[2]); 2570 2571 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 2572 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2573 "(%d) port_stats.opackets not as expected\n", 2574 test_params->slave_port_ids[0]); 2575 2576 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 2577 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2578 "(%d) port_stats.opackets not as expected\n", 2579 test_params->slave_port_ids[1]); 2580 2581 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 2582 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2583 "(%d) port_stats.opackets not as expected\n", 2584 test_params->slave_port_ids[3]); 2585 2586 /* Generate packet burst for testing */ 2587 2588 for (i = 0; i < TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT; i++) { 2589 TEST_ASSERT_EQUAL(generate_test_burst( 2590 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size, 2591 "generate_test_burst failed"); 2592 2593 virtual_ethdev_add_mbufs_to_rx_queue( 2594 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size); 2595 } 2596 2597 TEST_ASSERT_EQUAL(rte_eth_rx_burst( 2598 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), 2599 burst_size, "rte_eth_rx_burst\n"); 2600 2601 /* Verify bonded device rx count */ 2602 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2603 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, 2604 "(%d) port_stats.ipackets not as expected", 2605 test_params->bonded_port_id); 2606 2607 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 2608 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 2609 "(%d) port_stats.opackets not as expected", 2610 test_params->slave_port_ids[2]); 2611 2612 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 2613 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2614 "(%d) port_stats.opackets not as expected", 2615 test_params->slave_port_ids[0]); 2616 2617 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 2618 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2619 "(%d) port_stats.opackets not as expected", 2620 test_params->slave_port_ids[1]); 2621 2622 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 2623 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 2624 "(%d) port_stats.opackets not as expected", 2625 test_params->slave_port_ids[3]); 2626 2627 /* Clean up and remove slaves from bonded device */ 2628 return remove_slaves_and_stop_bonded_device(); 2629 } 2630 2631 /** Balance Mode Tests */ 2632 2633 static int 2634 test_balance_xmit_policy_configuration(void) 2635 { 2636 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2637 BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1), 2638 "Failed to initialize_bonded_device_with_slaves."); 2639 2640 /* Invalid port id */ 2641 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set( 2642 INVALID_PORT_ID, BALANCE_XMIT_POLICY_LAYER2), 2643 "Expected call to failed as invalid port specified."); 2644 2645 /* Set xmit policy on non bonded device */ 2646 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_set( 2647 test_params->slave_port_ids[0], BALANCE_XMIT_POLICY_LAYER2), 2648 "Expected call to failed as invalid port specified."); 2649 2650 2651 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 2652 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), 2653 "Failed to set balance xmit policy."); 2654 2655 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), 2656 BALANCE_XMIT_POLICY_LAYER2, "balance xmit policy not as expected."); 2657 2658 2659 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 2660 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23), 2661 "Failed to set balance xmit policy."); 2662 2663 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), 2664 BALANCE_XMIT_POLICY_LAYER23, 2665 "balance xmit policy not as expected."); 2666 2667 2668 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 2669 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34), 2670 "Failed to set balance xmit policy."); 2671 2672 TEST_ASSERT_EQUAL(rte_eth_bond_xmit_policy_get(test_params->bonded_port_id), 2673 BALANCE_XMIT_POLICY_LAYER34, 2674 "balance xmit policy not as expected."); 2675 2676 /* Invalid port id */ 2677 TEST_ASSERT_FAIL(rte_eth_bond_xmit_policy_get(INVALID_PORT_ID), 2678 "Expected call to failed as invalid port specified."); 2679 2680 /* Clean up and remove slaves from bonded device */ 2681 return remove_slaves_and_stop_bonded_device(); 2682 } 2683 2684 #define TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT (2) 2685 2686 static int 2687 test_balance_l2_tx_burst(void) 2688 { 2689 struct rte_mbuf *pkts_burst[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; 2690 int burst_size[TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT] = { 10, 15 }; 2691 2692 uint16_t pktlen; 2693 int i; 2694 struct rte_eth_stats port_stats; 2695 2696 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2697 BONDING_MODE_BALANCE, 0, TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1), 2698 "Failed to initialize_bonded_device_with_slaves."); 2699 2700 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 2701 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), 2702 "Failed to set balance xmit policy."); 2703 2704 initialize_eth_header(test_params->pkt_eth_hdr, 2705 (struct rte_ether_addr *)src_mac, 2706 (struct rte_ether_addr *)dst_mac_0, 2707 RTE_ETHER_TYPE_IPV4, 0, 0); 2708 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, 2709 dst_port_0, 16); 2710 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, 2711 dst_addr_0, pktlen); 2712 2713 /* Generate a burst 1 of packets to transmit */ 2714 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[0][0], 2715 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, 2716 test_params->pkt_udp_hdr, burst_size[0], 2717 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[0], 2718 "failed to generate packet burst"); 2719 2720 initialize_eth_header(test_params->pkt_eth_hdr, 2721 (struct rte_ether_addr *)src_mac, 2722 (struct rte_ether_addr *)dst_mac_1, 2723 RTE_ETHER_TYPE_IPV4, 0, 0); 2724 2725 /* Generate a burst 2 of packets to transmit */ 2726 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, &pkts_burst[1][0], 2727 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 1, 2728 test_params->pkt_udp_hdr, burst_size[1], 2729 PACKET_BURST_GEN_PKT_LEN, 1), burst_size[1], 2730 "failed to generate packet burst"); 2731 2732 /* Send burst 1 on bonded port */ 2733 for (i = 0; i < TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT; i++) { 2734 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, 2735 &pkts_burst[i][0], burst_size[i]), 2736 burst_size[i], "Failed to transmit packet burst"); 2737 } 2738 2739 /* Verify bonded port tx stats */ 2740 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2741 TEST_ASSERT_EQUAL(port_stats.opackets, 2742 (uint64_t)(burst_size[0] + burst_size[1]), 2743 "Bonded Port (%d) opackets value (%u) not as expected (%d)", 2744 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 2745 burst_size[0] + burst_size[1]); 2746 2747 2748 /* Verify slave ports tx stats */ 2749 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 2750 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[0], 2751 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2752 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, 2753 burst_size[0]); 2754 2755 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 2756 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size[1], 2757 "Slave Port (%d) opackets value (%u) not as expected (%d)\n", 2758 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, 2759 burst_size[1]); 2760 2761 /* Put all slaves down and try and transmit */ 2762 for (i = 0; i < test_params->bonded_slave_count; i++) { 2763 2764 virtual_ethdev_simulate_link_status_interrupt( 2765 test_params->slave_port_ids[i], 0); 2766 } 2767 2768 /* Send burst on bonded port */ 2769 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 2770 test_params->bonded_port_id, 0, &pkts_burst[0][0], burst_size[0]), 2771 0, "Expected zero packet"); 2772 2773 /* Clean up and remove slaves from bonded device */ 2774 return remove_slaves_and_stop_bonded_device(); 2775 } 2776 2777 static int 2778 balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4, 2779 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr) 2780 { 2781 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2; 2782 2783 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST]; 2784 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST]; 2785 2786 struct rte_eth_stats port_stats; 2787 2788 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2789 BONDING_MODE_BALANCE, 0, 2, 1), 2790 "Failed to initialize_bonded_device_with_slaves."); 2791 2792 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 2793 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER23), 2794 "Failed to set balance xmit policy."); 2795 2796 burst_size_1 = 20; 2797 burst_size_2 = 10; 2798 2799 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST, 2800 "Burst size specified is greater than supported."); 2801 2802 /* Generate test bursts of packets to transmit */ 2803 TEST_ASSERT_EQUAL(generate_test_burst( 2804 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0), 2805 burst_size_1, "failed to generate packet burst"); 2806 2807 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, vlan_enabled, ipv4, 2808 toggle_mac_addr, toggle_ip_addr, 0), burst_size_2, 2809 "failed to generate packet burst"); 2810 2811 /* Send burst 1 on bonded port */ 2812 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, 2813 burst_size_1); 2814 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed"); 2815 2816 /* Send burst 2 on bonded port */ 2817 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, 2818 burst_size_2); 2819 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed"); 2820 2821 /* Verify bonded port tx stats */ 2822 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2823 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2), 2824 "Bonded Port (%d) opackets value (%u) not as expected (%d)", 2825 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 2826 nb_tx_1 + nb_tx_2); 2827 2828 /* Verify slave ports tx stats */ 2829 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 2830 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1, 2831 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2832 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, 2833 nb_tx_1); 2834 2835 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 2836 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2, 2837 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2838 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, 2839 nb_tx_2); 2840 2841 /* Put all slaves down and try and transmit */ 2842 for (i = 0; i < test_params->bonded_slave_count; i++) { 2843 2844 virtual_ethdev_simulate_link_status_interrupt( 2845 test_params->slave_port_ids[i], 0); 2846 } 2847 2848 /* Send burst on bonded port */ 2849 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 2850 test_params->bonded_port_id, 0, pkts_burst_1, 2851 burst_size_1), 0, "Expected zero packet"); 2852 2853 2854 /* Clean up and remove slaves from bonded device */ 2855 return remove_slaves_and_stop_bonded_device(); 2856 } 2857 2858 static int 2859 test_balance_l23_tx_burst_ipv4_toggle_ip_addr(void) 2860 { 2861 return balance_l23_tx_burst(0, 1, 0, 1); 2862 } 2863 2864 static int 2865 test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr(void) 2866 { 2867 return balance_l23_tx_burst(1, 1, 0, 1); 2868 } 2869 2870 static int 2871 test_balance_l23_tx_burst_ipv6_toggle_ip_addr(void) 2872 { 2873 return balance_l23_tx_burst(0, 0, 0, 1); 2874 } 2875 2876 static int 2877 test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr(void) 2878 { 2879 return balance_l23_tx_burst(1, 0, 0, 1); 2880 } 2881 2882 static int 2883 test_balance_l23_tx_burst_toggle_mac_addr(void) 2884 { 2885 return balance_l23_tx_burst(0, 0, 1, 0); 2886 } 2887 2888 static int 2889 balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4, 2890 uint8_t toggle_mac_addr, uint8_t toggle_ip_addr, 2891 uint8_t toggle_udp_port) 2892 { 2893 int i, burst_size_1, burst_size_2, nb_tx_1, nb_tx_2; 2894 2895 struct rte_mbuf *pkts_burst_1[MAX_PKT_BURST]; 2896 struct rte_mbuf *pkts_burst_2[MAX_PKT_BURST]; 2897 2898 struct rte_eth_stats port_stats; 2899 2900 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 2901 BONDING_MODE_BALANCE, 0, 2, 1), 2902 "Failed to initialize_bonded_device_with_slaves."); 2903 2904 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 2905 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER34), 2906 "Failed to set balance xmit policy."); 2907 2908 burst_size_1 = 20; 2909 burst_size_2 = 10; 2910 2911 TEST_ASSERT(burst_size_1 < MAX_PKT_BURST || burst_size_2 < MAX_PKT_BURST, 2912 "Burst size specified is greater than supported."); 2913 2914 /* Generate test bursts of packets to transmit */ 2915 TEST_ASSERT_EQUAL(generate_test_burst( 2916 pkts_burst_1, burst_size_1, vlan_enabled, ipv4, 0, 0, 0), 2917 burst_size_1, "failed to generate burst"); 2918 2919 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, burst_size_2, 2920 vlan_enabled, ipv4, toggle_mac_addr, toggle_ip_addr, 2921 toggle_udp_port), burst_size_2, "failed to generate burst"); 2922 2923 /* Send burst 1 on bonded port */ 2924 nb_tx_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, 2925 burst_size_1); 2926 TEST_ASSERT_EQUAL(nb_tx_1, burst_size_1, "tx burst failed"); 2927 2928 /* Send burst 2 on bonded port */ 2929 nb_tx_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, 2930 burst_size_2); 2931 TEST_ASSERT_EQUAL(nb_tx_2, burst_size_2, "tx burst failed"); 2932 2933 2934 /* Verify bonded port tx stats */ 2935 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 2936 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(nb_tx_1 + nb_tx_2), 2937 "Bonded Port (%d) opackets value (%u) not as expected (%d)", 2938 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 2939 nb_tx_1 + nb_tx_2); 2940 2941 /* Verify slave ports tx stats */ 2942 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 2943 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_1, 2944 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2945 test_params->slave_port_ids[0], (unsigned int)port_stats.opackets, 2946 nb_tx_1); 2947 2948 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 2949 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)nb_tx_2, 2950 "Slave Port (%d) opackets value (%u) not as expected (%d)", 2951 test_params->slave_port_ids[1], (unsigned int)port_stats.opackets, 2952 nb_tx_2); 2953 2954 /* Put all slaves down and try and transmit */ 2955 for (i = 0; i < test_params->bonded_slave_count; i++) { 2956 2957 virtual_ethdev_simulate_link_status_interrupt( 2958 test_params->slave_port_ids[i], 0); 2959 } 2960 2961 /* Send burst on bonded port */ 2962 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 2963 test_params->bonded_port_id, 0, pkts_burst_1, 2964 burst_size_1), 0, "Expected zero packet"); 2965 2966 /* Clean up and remove slaves from bonded device */ 2967 return remove_slaves_and_stop_bonded_device(); 2968 } 2969 2970 static int 2971 test_balance_l34_tx_burst_ipv4_toggle_ip_addr(void) 2972 { 2973 return balance_l34_tx_burst(0, 1, 0, 1, 0); 2974 } 2975 2976 static int 2977 test_balance_l34_tx_burst_ipv4_toggle_udp_port(void) 2978 { 2979 return balance_l34_tx_burst(0, 1, 0, 0, 1); 2980 } 2981 2982 static int 2983 test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr(void) 2984 { 2985 return balance_l34_tx_burst(1, 1, 0, 1, 0); 2986 } 2987 2988 static int 2989 test_balance_l34_tx_burst_ipv6_toggle_ip_addr(void) 2990 { 2991 return balance_l34_tx_burst(0, 0, 0, 1, 0); 2992 } 2993 2994 static int 2995 test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr(void) 2996 { 2997 return balance_l34_tx_burst(1, 0, 0, 1, 0); 2998 } 2999 3000 static int 3001 test_balance_l34_tx_burst_ipv6_toggle_udp_port(void) 3002 { 3003 return balance_l34_tx_burst(0, 0, 0, 0, 1); 3004 } 3005 3006 #define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT (2) 3007 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 (40) 3008 #define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2 (20) 3009 #define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT (25) 3010 #define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX (0) 3011 3012 static int 3013 test_balance_tx_burst_slave_tx_fail(void) 3014 { 3015 struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1]; 3016 struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2]; 3017 3018 struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT]; 3019 3020 struct rte_eth_stats port_stats; 3021 3022 int i, first_tx_fail_idx, tx_count_1, tx_count_2; 3023 3024 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3025 BONDING_MODE_BALANCE, 0, 3026 TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1), 3027 "Failed to initialise bonded device"); 3028 3029 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 3030 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), 3031 "Failed to set balance xmit policy."); 3032 3033 3034 /* Generate test bursts for transmission */ 3035 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1, 3036 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0), 3037 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 3038 "Failed to generate test packet burst 1"); 3039 3040 first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3041 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; 3042 3043 /* copy mbuf references for expected transmission failures */ 3044 for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++) 3045 expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx]; 3046 3047 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2, 3048 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0), 3049 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 3050 "Failed to generate test packet burst 2"); 3051 3052 3053 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail 3054 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */ 3055 virtual_ethdev_tx_burst_fn_set_success( 3056 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], 3057 0); 3058 3059 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( 3060 test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX], 3061 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); 3062 3063 3064 /* Transmit burst 1 */ 3065 tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1, 3066 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1); 3067 3068 TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3069 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 3070 "Transmitted (%d) packets, expected to transmit (%d) packets", 3071 tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3072 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); 3073 3074 /* Verify that failed packet are expected failed packets */ 3075 for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) { 3076 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1], 3077 "expected mbuf (%d) pointer %p not expected pointer %p", 3078 i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]); 3079 } 3080 3081 /* Transmit burst 2 */ 3082 tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2, 3083 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); 3084 3085 TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 3086 "Transmitted (%d) packets, expected to transmit (%d) packets", 3087 tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); 3088 3089 3090 /* Verify bonded port tx stats */ 3091 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3092 3093 TEST_ASSERT_EQUAL(port_stats.opackets, 3094 (uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3095 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) + 3096 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2), 3097 "Bonded Port (%d) opackets value (%u) not as expected (%d)", 3098 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 3099 (TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3100 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) + 3101 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); 3102 3103 /* Verify slave ports tx stats */ 3104 3105 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 3106 3107 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t) 3108 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3109 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 3110 "Slave Port (%d) opackets value (%u) not as expected (%d)", 3111 test_params->slave_port_ids[0], 3112 (unsigned int)port_stats.opackets, 3113 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - 3114 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); 3115 3116 3117 3118 3119 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 3120 3121 TEST_ASSERT_EQUAL(port_stats.opackets, 3122 (uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 3123 "Slave Port (%d) opackets value (%u) not as expected (%d)", 3124 test_params->slave_port_ids[1], 3125 (unsigned int)port_stats.opackets, 3126 TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2); 3127 3128 /* Verify that all mbufs have a ref value of zero */ 3129 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1], 3130 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1), 3131 "mbufs refcnts not as expected"); 3132 3133 free_mbufs(&pkts_burst_1[tx_count_1], 3134 TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT); 3135 3136 /* Clean up and remove slaves from bonded device */ 3137 return remove_slaves_and_stop_bonded_device(); 3138 } 3139 3140 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3) 3141 3142 static int 3143 test_balance_rx_burst(void) 3144 { 3145 struct rte_mbuf *gen_pkt_burst[TEST_BALANCE_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; 3146 3147 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 3148 struct rte_eth_stats port_stats; 3149 3150 int burst_size[TEST_BALANCE_RX_BURST_SLAVE_COUNT] = { 10, 5, 30 }; 3151 int i, j; 3152 3153 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); 3154 3155 /* Initialize bonded device with 4 slaves in round robin mode */ 3156 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3157 BONDING_MODE_BALANCE, 0, 3, 1), 3158 "Failed to initialise bonded device"); 3159 3160 /* Generate test bursts of packets to transmit */ 3161 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { 3162 TEST_ASSERT_EQUAL(generate_test_burst( 3163 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 3164 0, 0), burst_size[i], 3165 "failed to generate packet burst"); 3166 } 3167 3168 /* Add rx data to slaves */ 3169 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { 3170 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 3171 &gen_pkt_burst[i][0], burst_size[i]); 3172 } 3173 3174 /* Call rx burst on bonded device */ 3175 /* Send burst on bonded port */ 3176 TEST_ASSERT_EQUAL(rte_eth_rx_burst(test_params->bonded_port_id, 0, 3177 rx_pkt_burst, MAX_PKT_BURST), 3178 burst_size[0] + burst_size[1] + burst_size[2], 3179 "balance rx burst failed\n"); 3180 3181 /* Verify bonded device rx count */ 3182 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3183 TEST_ASSERT_EQUAL(port_stats.ipackets, 3184 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), 3185 "Bonded Port (%d) ipackets value (%u) not as expected (%d)", 3186 test_params->bonded_port_id, (unsigned int)port_stats.ipackets, 3187 burst_size[0] + burst_size[1] + burst_size[2]); 3188 3189 3190 /* Verify bonded slave devices rx counts */ 3191 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 3192 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], 3193 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3194 test_params->slave_port_ids[0], 3195 (unsigned int)port_stats.ipackets, burst_size[0]); 3196 3197 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 3198 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], 3199 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3200 test_params->slave_port_ids[1], (unsigned int)port_stats.ipackets, 3201 burst_size[1]); 3202 3203 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 3204 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], 3205 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3206 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets, 3207 burst_size[2]); 3208 3209 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 3210 TEST_ASSERT_EQUAL(port_stats.ipackets, 0, 3211 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3212 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets, 3213 0); 3214 3215 /* free mbufs */ 3216 for (i = 0; i < TEST_BALANCE_RX_BURST_SLAVE_COUNT; i++) { 3217 for (j = 0; j < MAX_PKT_BURST; j++) { 3218 if (gen_pkt_burst[i][j] != NULL) { 3219 rte_pktmbuf_free(gen_pkt_burst[i][j]); 3220 gen_pkt_burst[i][j] = NULL; 3221 } 3222 } 3223 } 3224 3225 /* Clean up and remove slaves from bonded device */ 3226 return remove_slaves_and_stop_bonded_device(); 3227 } 3228 3229 static int 3230 test_balance_verify_promiscuous_enable_disable(void) 3231 { 3232 int i; 3233 int ret; 3234 3235 /* Initialize bonded device with 4 slaves in round robin mode */ 3236 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3237 BONDING_MODE_BALANCE, 0, 4, 1), 3238 "Failed to initialise bonded device"); 3239 3240 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id); 3241 TEST_ASSERT_SUCCESS(ret, 3242 "Failed to enable promiscuous mode for port %d: %s", 3243 test_params->bonded_port_id, rte_strerror(-ret)); 3244 3245 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, 3246 "Port (%d) promiscuous mode not enabled", 3247 test_params->bonded_port_id); 3248 3249 for (i = 0; i < test_params->bonded_slave_count; i++) { 3250 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( 3251 test_params->slave_port_ids[i]), 1, 3252 "Port (%d) promiscuous mode not enabled", 3253 test_params->slave_port_ids[i]); 3254 } 3255 3256 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id); 3257 TEST_ASSERT_SUCCESS(ret, 3258 "Failed to disable promiscuous mode for port %d: %s", 3259 test_params->bonded_port_id, rte_strerror(-ret)); 3260 3261 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, 3262 "Port (%d) promiscuous mode not disabled", 3263 test_params->bonded_port_id); 3264 3265 for (i = 0; i < test_params->bonded_slave_count; i++) { 3266 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( 3267 test_params->slave_port_ids[i]), 0, 3268 "Port (%d) promiscuous mode not disabled", 3269 test_params->slave_port_ids[i]); 3270 } 3271 3272 /* Clean up and remove slaves from bonded device */ 3273 return remove_slaves_and_stop_bonded_device(); 3274 } 3275 3276 static int 3277 test_balance_verify_mac_assignment(void) 3278 { 3279 struct rte_ether_addr read_mac_addr; 3280 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1; 3281 3282 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0), 3283 "Failed to get mac address (port %d)", 3284 test_params->slave_port_ids[0]); 3285 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1), 3286 "Failed to get mac address (port %d)", 3287 test_params->slave_port_ids[1]); 3288 3289 /* Initialize bonded device with 2 slaves in active backup mode */ 3290 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3291 BONDING_MODE_BALANCE, 0, 2, 1), 3292 "Failed to initialise bonded device"); 3293 3294 /* Verify that bonded MACs is that of first slave and that the other slave 3295 * MAC hasn't been changed */ 3296 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 3297 "Failed to get mac address (port %d)", 3298 test_params->bonded_port_id); 3299 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3300 sizeof(read_mac_addr)), 3301 "bonded port (%d) mac address not set to that of primary port", 3302 test_params->bonded_port_id); 3303 3304 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 3305 "Failed to get mac address (port %d)", 3306 test_params->slave_port_ids[0]); 3307 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3308 sizeof(read_mac_addr)), 3309 "slave port (%d) mac address not set to that of primary port", 3310 test_params->slave_port_ids[0]); 3311 3312 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 3313 "Failed to get mac address (port %d)", 3314 test_params->slave_port_ids[1]); 3315 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3316 sizeof(read_mac_addr)), 3317 "slave port (%d) mac address not set to that of primary port", 3318 test_params->slave_port_ids[1]); 3319 3320 /* change primary and verify that MAC addresses haven't changed */ 3321 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, 3322 test_params->slave_port_ids[1]), 3323 "Failed to set bonded port (%d) primary port to (%d)\n", 3324 test_params->bonded_port_id, test_params->slave_port_ids[1]); 3325 3326 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 3327 "Failed to get mac address (port %d)", 3328 test_params->bonded_port_id); 3329 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3330 sizeof(read_mac_addr)), 3331 "bonded port (%d) mac address not set to that of primary port", 3332 test_params->bonded_port_id); 3333 3334 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 3335 "Failed to get mac address (port %d)", 3336 test_params->slave_port_ids[0]); 3337 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3338 sizeof(read_mac_addr)), 3339 "slave port (%d) mac address not set to that of primary port", 3340 test_params->slave_port_ids[0]); 3341 3342 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 3343 "Failed to get mac address (port %d)", 3344 test_params->slave_port_ids[1]); 3345 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3346 sizeof(read_mac_addr)), 3347 "slave port (%d) mac address not set to that of primary port", 3348 test_params->slave_port_ids[1]); 3349 3350 /* stop / start bonded device and verify that primary MAC address is 3351 * propagated to bonded device and slaves */ 3352 3353 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id), 3354 "Failed to stop bonded port %u", 3355 test_params->bonded_port_id); 3356 3357 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), 3358 "Failed to start bonded device"); 3359 3360 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 3361 "Failed to get mac address (port %d)", 3362 test_params->bonded_port_id); 3363 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 3364 sizeof(read_mac_addr)), 3365 "bonded port (%d) mac address not set to that of primary port", 3366 test_params->bonded_port_id); 3367 3368 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 3369 "Failed to get mac address (port %d)", 3370 test_params->slave_port_ids[0]); 3371 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 3372 sizeof(read_mac_addr)), 3373 "slave port (%d) mac address not set to that of primary port", 3374 test_params->slave_port_ids[0]); 3375 3376 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 3377 "Failed to get mac address (port %d)", 3378 test_params->slave_port_ids[1]); 3379 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 3380 sizeof(read_mac_addr)), 3381 "slave port (%d) mac address not set to that of primary port", 3382 test_params->slave_port_ids[1]); 3383 3384 /* Set explicit MAC address */ 3385 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( 3386 test_params->bonded_port_id, 3387 (struct rte_ether_addr *)bonded_mac), 3388 "failed to set MAC"); 3389 3390 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 3391 "Failed to get mac address (port %d)", 3392 test_params->bonded_port_id); 3393 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 3394 sizeof(read_mac_addr)), 3395 "bonded port (%d) mac address not set to that of bonded port", 3396 test_params->bonded_port_id); 3397 3398 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 3399 "Failed to get mac address (port %d)", 3400 test_params->slave_port_ids[0]); 3401 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 3402 sizeof(read_mac_addr)), 3403 "slave port (%d) mac address not as expected\n", 3404 test_params->slave_port_ids[0]); 3405 3406 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 3407 "Failed to get mac address (port %d)", 3408 test_params->slave_port_ids[1]); 3409 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 3410 sizeof(read_mac_addr)), 3411 "slave port (%d) mac address not set to that of bonded port", 3412 test_params->slave_port_ids[1]); 3413 3414 /* Clean up and remove slaves from bonded device */ 3415 return remove_slaves_and_stop_bonded_device(); 3416 } 3417 3418 #define TEST_BALANCE_LINK_STATUS_SLAVE_COUNT (4) 3419 3420 static int 3421 test_balance_verify_slave_link_status_change_behaviour(void) 3422 { 3423 struct rte_mbuf *pkt_burst[TEST_BALANCE_LINK_STATUS_SLAVE_COUNT][MAX_PKT_BURST]; 3424 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 3425 struct rte_eth_stats port_stats; 3426 3427 uint16_t slaves[RTE_MAX_ETHPORTS]; 3428 3429 int i, burst_size, slave_count; 3430 3431 memset(pkt_burst, 0, sizeof(pkt_burst)); 3432 3433 /* Initialize bonded device with 4 slaves in round robin mode */ 3434 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3435 BONDING_MODE_BALANCE, 0, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1), 3436 "Failed to initialise bonded device"); 3437 3438 TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set( 3439 test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2), 3440 "Failed to set balance xmit policy."); 3441 3442 3443 /* Verify Current Slaves Count /Active Slave Count is */ 3444 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, 3445 RTE_MAX_ETHPORTS); 3446 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 3447 "Number of slaves (%d) is not as expected (%d).", 3448 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT); 3449 3450 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 3451 slaves, RTE_MAX_ETHPORTS); 3452 TEST_ASSERT_EQUAL(slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 3453 "Number of active slaves (%d) is not as expected (%d).", 3454 slave_count, TEST_BALANCE_LINK_STATUS_SLAVE_COUNT); 3455 3456 /* Set 2 slaves link status to down */ 3457 virtual_ethdev_simulate_link_status_interrupt( 3458 test_params->slave_port_ids[1], 0); 3459 virtual_ethdev_simulate_link_status_interrupt( 3460 test_params->slave_port_ids[3], 0); 3461 3462 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( 3463 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, 3464 "Number of active slaves (%d) is not as expected (%d).", 3465 slave_count, 2); 3466 3467 /* Send to sets of packet burst and verify that they are balanced across 3468 * slaves */ 3469 burst_size = 21; 3470 3471 TEST_ASSERT_EQUAL(generate_test_burst( 3472 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, 3473 "generate_test_burst failed"); 3474 3475 TEST_ASSERT_EQUAL(generate_test_burst( 3476 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size, 3477 "generate_test_burst failed"); 3478 3479 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 3480 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), 3481 burst_size, "rte_eth_tx_burst failed"); 3482 3483 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 3484 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size), 3485 burst_size, "rte_eth_tx_burst failed"); 3486 3487 3488 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3489 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size), 3490 "(%d) port_stats.opackets (%d) not as expected (%d).", 3491 test_params->bonded_port_id, (int)port_stats.opackets, 3492 burst_size + burst_size); 3493 3494 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 3495 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 3496 "(%d) port_stats.opackets (%d) not as expected (%d).", 3497 test_params->slave_port_ids[0], (int)port_stats.opackets, 3498 burst_size); 3499 3500 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 3501 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 3502 "(%d) port_stats.opackets (%d) not as expected (%d).", 3503 test_params->slave_port_ids[2], (int)port_stats.opackets, 3504 burst_size); 3505 3506 /* verify that all packets get send on primary slave when no other slaves 3507 * are available */ 3508 virtual_ethdev_simulate_link_status_interrupt( 3509 test_params->slave_port_ids[2], 0); 3510 3511 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( 3512 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 1, 3513 "Number of active slaves (%d) is not as expected (%d).", 3514 slave_count, 1); 3515 3516 TEST_ASSERT_EQUAL(generate_test_burst( 3517 &pkt_burst[1][0], burst_size, 0, 1, 1, 0, 0), burst_size, 3518 "generate_test_burst failed"); 3519 3520 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 3521 test_params->bonded_port_id, 0, &pkt_burst[1][0], burst_size), 3522 burst_size, "rte_eth_tx_burst failed"); 3523 3524 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3525 TEST_ASSERT_EQUAL(port_stats.opackets, 3526 (uint64_t)(burst_size + burst_size + burst_size), 3527 "(%d) port_stats.opackets (%d) not as expected (%d).\n", 3528 test_params->bonded_port_id, (int)port_stats.opackets, 3529 burst_size + burst_size + burst_size); 3530 3531 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 3532 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size + burst_size), 3533 "(%d) port_stats.opackets (%d) not as expected (%d).", 3534 test_params->slave_port_ids[0], (int)port_stats.opackets, 3535 burst_size + burst_size); 3536 3537 virtual_ethdev_simulate_link_status_interrupt( 3538 test_params->slave_port_ids[0], 0); 3539 virtual_ethdev_simulate_link_status_interrupt( 3540 test_params->slave_port_ids[1], 1); 3541 virtual_ethdev_simulate_link_status_interrupt( 3542 test_params->slave_port_ids[2], 1); 3543 virtual_ethdev_simulate_link_status_interrupt( 3544 test_params->slave_port_ids[3], 1); 3545 3546 for (i = 0; i < TEST_BALANCE_LINK_STATUS_SLAVE_COUNT; i++) { 3547 TEST_ASSERT_EQUAL(generate_test_burst( 3548 &pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0), burst_size, 3549 "Failed to generate packet burst"); 3550 3551 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 3552 &pkt_burst[i][0], burst_size); 3553 } 3554 3555 /* Verify that pkts are not received on slaves with link status down */ 3556 3557 rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, 3558 MAX_PKT_BURST); 3559 3560 /* Verify bonded device rx count */ 3561 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3562 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size * 3), 3563 "(%d) port_stats.ipackets (%d) not as expected (%d)\n", 3564 test_params->bonded_port_id, (int)port_stats.ipackets, 3565 burst_size * 3); 3566 3567 /* Clean up and remove slaves from bonded device */ 3568 return remove_slaves_and_stop_bonded_device(); 3569 } 3570 3571 static int 3572 test_broadcast_tx_burst(void) 3573 { 3574 int i, pktlen, burst_size; 3575 struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 3576 3577 struct rte_eth_stats port_stats; 3578 3579 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3580 BONDING_MODE_BROADCAST, 0, 2, 1), 3581 "Failed to initialise bonded device"); 3582 3583 initialize_eth_header(test_params->pkt_eth_hdr, 3584 (struct rte_ether_addr *)src_mac, 3585 (struct rte_ether_addr *)dst_mac_0, 3586 RTE_ETHER_TYPE_IPV4, 0, 0); 3587 3588 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, 3589 dst_port_0, 16); 3590 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, 3591 dst_addr_0, pktlen); 3592 3593 burst_size = 20 * test_params->bonded_slave_count; 3594 3595 TEST_ASSERT(burst_size < MAX_PKT_BURST, 3596 "Burst size specified is greater than supported."); 3597 3598 /* Generate a burst of packets to transmit */ 3599 TEST_ASSERT_EQUAL(generate_packet_burst(test_params->mbuf_pool, 3600 pkts_burst, test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 3601 1, test_params->pkt_udp_hdr, burst_size, PACKET_BURST_GEN_PKT_LEN, 3602 1), burst_size, "Failed to generate packet burst"); 3603 3604 /* Send burst on bonded port */ 3605 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, 3606 pkts_burst, burst_size), burst_size, 3607 "Bonded Port (%d) rx burst failed, packets transmitted value " 3608 "not as expected (%d)", 3609 test_params->bonded_port_id, burst_size); 3610 3611 /* Verify bonded port tx stats */ 3612 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3613 TEST_ASSERT_EQUAL(port_stats.opackets, 3614 (uint64_t)burst_size * test_params->bonded_slave_count, 3615 "Bonded Port (%d) opackets value (%u) not as expected (%d)", 3616 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 3617 burst_size); 3618 3619 /* Verify slave ports tx stats */ 3620 for (i = 0; i < test_params->bonded_slave_count; i++) { 3621 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats); 3622 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 3623 "Slave Port (%d) opackets value (%u) not as expected (%d)\n", 3624 test_params->bonded_port_id, 3625 (unsigned int)port_stats.opackets, burst_size); 3626 } 3627 3628 /* Put all slaves down and try and transmit */ 3629 for (i = 0; i < test_params->bonded_slave_count; i++) { 3630 3631 virtual_ethdev_simulate_link_status_interrupt( 3632 test_params->slave_port_ids[i], 0); 3633 } 3634 3635 /* Send burst on bonded port */ 3636 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 3637 test_params->bonded_port_id, 0, pkts_burst, burst_size), 0, 3638 "transmitted an unexpected number of packets"); 3639 3640 /* Clean up and remove slaves from bonded device */ 3641 return remove_slaves_and_stop_bonded_device(); 3642 } 3643 3644 3645 #define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT (3) 3646 #define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE (40) 3647 #define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT (15) 3648 #define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT (10) 3649 3650 static int 3651 test_broadcast_tx_burst_slave_tx_fail(void) 3652 { 3653 struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE]; 3654 struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT]; 3655 3656 struct rte_eth_stats port_stats; 3657 3658 int i, tx_count; 3659 3660 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3661 BONDING_MODE_BROADCAST, 0, 3662 TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1), 3663 "Failed to initialise bonded device"); 3664 3665 /* Generate test bursts for transmission */ 3666 TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst, 3667 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0), 3668 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 3669 "Failed to generate test packet burst"); 3670 3671 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) { 3672 expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3673 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i]; 3674 } 3675 3676 /* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail 3677 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */ 3678 virtual_ethdev_tx_burst_fn_set_success( 3679 test_params->slave_port_ids[0], 3680 0); 3681 virtual_ethdev_tx_burst_fn_set_success( 3682 test_params->slave_port_ids[1], 3683 0); 3684 virtual_ethdev_tx_burst_fn_set_success( 3685 test_params->slave_port_ids[2], 3686 0); 3687 3688 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( 3689 test_params->slave_port_ids[0], 3690 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); 3691 3692 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( 3693 test_params->slave_port_ids[1], 3694 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); 3695 3696 virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count( 3697 test_params->slave_port_ids[2], 3698 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); 3699 3700 /* Transmit burst */ 3701 tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst, 3702 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE); 3703 3704 TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3705 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 3706 "Transmitted (%d) packets, expected to transmit (%d) packets", 3707 tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3708 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); 3709 3710 /* Verify that failed packet are expected failed packets */ 3711 for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) { 3712 TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count], 3713 "expected mbuf (%d) pointer %p not expected pointer %p", 3714 i, expected_fail_pkts[i], pkts_burst[i + tx_count]); 3715 } 3716 3717 /* Verify slave ports tx stats */ 3718 3719 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 3720 3721 TEST_ASSERT_EQUAL(port_stats.opackets, 3722 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3723 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT, 3724 "Port (%d) opackets value (%u) not as expected (%d)", 3725 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 3726 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3727 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); 3728 3729 3730 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 3731 3732 TEST_ASSERT_EQUAL(port_stats.opackets, 3733 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3734 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 3735 "Port (%d) opackets value (%u) not as expected (%d)", 3736 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 3737 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3738 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); 3739 3740 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 3741 3742 TEST_ASSERT_EQUAL(port_stats.opackets, 3743 (uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3744 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT, 3745 "Port (%d) opackets value (%u) not as expected (%d)", 3746 test_params->bonded_port_id, (unsigned int)port_stats.opackets, 3747 TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE - 3748 TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT); 3749 3750 3751 /* Verify that all mbufs who transmission failed have a ref value of one */ 3752 TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count], 3753 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1), 3754 "mbufs refcnts not as expected"); 3755 3756 free_mbufs(&pkts_burst[tx_count], 3757 TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT); 3758 3759 /* Clean up and remove slaves from bonded device */ 3760 return remove_slaves_and_stop_bonded_device(); 3761 } 3762 3763 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3) 3764 3765 static int 3766 test_broadcast_rx_burst(void) 3767 { 3768 struct rte_mbuf *gen_pkt_burst[BROADCAST_RX_BURST_NUM_OF_SLAVES][MAX_PKT_BURST]; 3769 3770 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 3771 struct rte_eth_stats port_stats; 3772 3773 int burst_size[BROADCAST_RX_BURST_NUM_OF_SLAVES] = { 10, 5, 30 }; 3774 int i, j; 3775 3776 memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst)); 3777 3778 /* Initialize bonded device with 4 slaves in round robin mode */ 3779 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3780 BONDING_MODE_BROADCAST, 0, 3, 1), 3781 "Failed to initialise bonded device"); 3782 3783 /* Generate test bursts of packets to transmit */ 3784 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { 3785 TEST_ASSERT_EQUAL(generate_test_burst( 3786 &gen_pkt_burst[i][0], burst_size[i], 0, 0, 1, 0, 0), 3787 burst_size[i], "failed to generate packet burst"); 3788 } 3789 3790 /* Add rx data to slave 0 */ 3791 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { 3792 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 3793 &gen_pkt_burst[i][0], burst_size[i]); 3794 } 3795 3796 3797 /* Call rx burst on bonded device */ 3798 /* Send burst on bonded port */ 3799 TEST_ASSERT_EQUAL(rte_eth_rx_burst( 3800 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), 3801 burst_size[0] + burst_size[1] + burst_size[2], 3802 "rx burst failed"); 3803 3804 /* Verify bonded device rx count */ 3805 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 3806 TEST_ASSERT_EQUAL(port_stats.ipackets, 3807 (uint64_t)(burst_size[0] + burst_size[1] + burst_size[2]), 3808 "Bonded Port (%d) ipackets value (%u) not as expected (%d)", 3809 test_params->bonded_port_id, (unsigned int)port_stats.ipackets, 3810 burst_size[0] + burst_size[1] + burst_size[2]); 3811 3812 3813 /* Verify bonded slave devices rx counts */ 3814 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 3815 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[0], 3816 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3817 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets, 3818 burst_size[0]); 3819 3820 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 3821 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[1], 3822 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3823 test_params->slave_port_ids[0], (unsigned int)port_stats.ipackets, 3824 burst_size[1]); 3825 3826 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 3827 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size[2], 3828 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3829 test_params->slave_port_ids[2], (unsigned int)port_stats.ipackets, 3830 burst_size[2]); 3831 3832 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 3833 TEST_ASSERT_EQUAL(port_stats.ipackets, 0, 3834 "Slave Port (%d) ipackets value (%u) not as expected (%d)", 3835 test_params->slave_port_ids[3], (unsigned int)port_stats.ipackets, 3836 0); 3837 3838 /* free mbufs allocate for rx testing */ 3839 for (i = 0; i < BROADCAST_RX_BURST_NUM_OF_SLAVES; i++) { 3840 for (j = 0; j < MAX_PKT_BURST; j++) { 3841 if (gen_pkt_burst[i][j] != NULL) { 3842 rte_pktmbuf_free(gen_pkt_burst[i][j]); 3843 gen_pkt_burst[i][j] = NULL; 3844 } 3845 } 3846 } 3847 3848 /* Clean up and remove slaves from bonded device */ 3849 return remove_slaves_and_stop_bonded_device(); 3850 } 3851 3852 static int 3853 test_broadcast_verify_promiscuous_enable_disable(void) 3854 { 3855 int i; 3856 int ret; 3857 3858 /* Initialize bonded device with 4 slaves in round robin mode */ 3859 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3860 BONDING_MODE_BROADCAST, 0, 4, 1), 3861 "Failed to initialise bonded device"); 3862 3863 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id); 3864 TEST_ASSERT_SUCCESS(ret, 3865 "Failed to enable promiscuous mode for port %d: %s", 3866 test_params->bonded_port_id, rte_strerror(-ret)); 3867 3868 3869 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 1, 3870 "Port (%d) promiscuous mode not enabled", 3871 test_params->bonded_port_id); 3872 3873 for (i = 0; i < test_params->bonded_slave_count; i++) { 3874 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( 3875 test_params->slave_port_ids[i]), 1, 3876 "Port (%d) promiscuous mode not enabled", 3877 test_params->slave_port_ids[i]); 3878 } 3879 3880 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id); 3881 TEST_ASSERT_SUCCESS(ret, 3882 "Failed to disable promiscuous mode for port %d: %s", 3883 test_params->bonded_port_id, rte_strerror(-ret)); 3884 3885 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get(test_params->bonded_port_id), 0, 3886 "Port (%d) promiscuous mode not disabled", 3887 test_params->bonded_port_id); 3888 3889 for (i = 0; i < test_params->bonded_slave_count; i++) { 3890 TEST_ASSERT_EQUAL(rte_eth_promiscuous_get( 3891 test_params->slave_port_ids[i]), 0, 3892 "Port (%d) promiscuous mode not disabled", 3893 test_params->slave_port_ids[i]); 3894 } 3895 3896 /* Clean up and remove slaves from bonded device */ 3897 return remove_slaves_and_stop_bonded_device(); 3898 } 3899 3900 static int 3901 test_broadcast_verify_mac_assignment(void) 3902 { 3903 struct rte_ether_addr read_mac_addr; 3904 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1; 3905 3906 int i; 3907 3908 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0), 3909 "Failed to get mac address (port %d)", 3910 test_params->slave_port_ids[0]); 3911 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[2], &expected_mac_addr_1), 3912 "Failed to get mac address (port %d)", 3913 test_params->slave_port_ids[2]); 3914 3915 /* Initialize bonded device with 4 slaves in round robin mode */ 3916 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 3917 BONDING_MODE_BROADCAST, 0, 4, 1), 3918 "Failed to initialise bonded device"); 3919 3920 /* Verify that all MACs are the same as first slave added to bonded 3921 * device */ 3922 for (i = 0; i < test_params->bonded_slave_count; i++) { 3923 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 3924 "Failed to get mac address (port %d)", 3925 test_params->slave_port_ids[i]); 3926 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3927 sizeof(read_mac_addr)), 3928 "slave port (%d) mac address not set to that of primary port", 3929 test_params->slave_port_ids[i]); 3930 } 3931 3932 /* change primary and verify that MAC addresses haven't changed */ 3933 TEST_ASSERT_SUCCESS(rte_eth_bond_primary_set(test_params->bonded_port_id, 3934 test_params->slave_port_ids[2]), 3935 "Failed to set bonded port (%d) primary port to (%d)", 3936 test_params->bonded_port_id, test_params->slave_port_ids[i]); 3937 3938 for (i = 0; i < test_params->bonded_slave_count; i++) { 3939 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 3940 "Failed to get mac address (port %d)", 3941 test_params->slave_port_ids[i]); 3942 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 3943 sizeof(read_mac_addr)), 3944 "slave port (%d) mac address has changed to that of primary " 3945 "port without stop/start toggle of bonded device", 3946 test_params->slave_port_ids[i]); 3947 } 3948 3949 /* stop / start bonded device and verify that primary MAC address is 3950 * propagated to bonded device and slaves */ 3951 3952 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id), 3953 "Failed to stop bonded port %u", 3954 test_params->bonded_port_id); 3955 3956 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), 3957 "Failed to start bonded device"); 3958 3959 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 3960 "Failed to get mac address (port %d)", 3961 test_params->bonded_port_id); 3962 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 3963 sizeof(read_mac_addr)), 3964 "bonded port (%d) mac address not set to that of new primary port", 3965 test_params->slave_port_ids[i]); 3966 3967 for (i = 0; i < test_params->bonded_slave_count; i++) { 3968 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 3969 "Failed to get mac address (port %d)", 3970 test_params->slave_port_ids[i]); 3971 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 3972 sizeof(read_mac_addr)), 3973 "slave port (%d) mac address not set to that of new primary " 3974 "port", test_params->slave_port_ids[i]); 3975 } 3976 3977 /* Set explicit MAC address */ 3978 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( 3979 test_params->bonded_port_id, 3980 (struct rte_ether_addr *)bonded_mac), 3981 "Failed to set MAC address"); 3982 3983 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 3984 "Failed to get mac address (port %d)", 3985 test_params->bonded_port_id); 3986 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, 3987 sizeof(read_mac_addr)), 3988 "bonded port (%d) mac address not set to that of new primary port", 3989 test_params->slave_port_ids[i]); 3990 3991 3992 for (i = 0; i < test_params->bonded_slave_count; i++) { 3993 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[i], &read_mac_addr), 3994 "Failed to get mac address (port %d)", 3995 test_params->slave_port_ids[i]); 3996 TEST_ASSERT_SUCCESS(memcmp(bonded_mac, &read_mac_addr, 3997 sizeof(read_mac_addr)), 3998 "slave port (%d) mac address not set to that of new primary " 3999 "port", test_params->slave_port_ids[i]); 4000 } 4001 4002 /* Clean up and remove slaves from bonded device */ 4003 return remove_slaves_and_stop_bonded_device(); 4004 } 4005 4006 #define BROADCAST_LINK_STATUS_NUM_OF_SLAVES (4) 4007 static int 4008 test_broadcast_verify_slave_link_status_change_behaviour(void) 4009 { 4010 struct rte_mbuf *pkt_burst[BROADCAST_LINK_STATUS_NUM_OF_SLAVES][MAX_PKT_BURST]; 4011 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 4012 struct rte_eth_stats port_stats; 4013 4014 uint16_t slaves[RTE_MAX_ETHPORTS]; 4015 4016 int i, burst_size, slave_count; 4017 4018 memset(pkt_burst, 0, sizeof(pkt_burst)); 4019 4020 /* Initialize bonded device with 4 slaves in round robin mode */ 4021 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 4022 BONDING_MODE_BROADCAST, 0, BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 4023 1), "Failed to initialise bonded device"); 4024 4025 /* Verify Current Slaves Count /Active Slave Count is */ 4026 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, 4027 RTE_MAX_ETHPORTS); 4028 TEST_ASSERT_EQUAL(slave_count, 4, 4029 "Number of slaves (%d) is not as expected (%d).", 4030 slave_count, 4); 4031 4032 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 4033 slaves, RTE_MAX_ETHPORTS); 4034 TEST_ASSERT_EQUAL(slave_count, 4, 4035 "Number of active slaves (%d) is not as expected (%d).", 4036 slave_count, 4); 4037 4038 /* Set 2 slaves link status to down */ 4039 virtual_ethdev_simulate_link_status_interrupt( 4040 test_params->slave_port_ids[1], 0); 4041 virtual_ethdev_simulate_link_status_interrupt( 4042 test_params->slave_port_ids[3], 0); 4043 4044 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 4045 slaves, RTE_MAX_ETHPORTS); 4046 TEST_ASSERT_EQUAL(slave_count, 2, 4047 "Number of active slaves (%d) is not as expected (%d).", 4048 slave_count, 2); 4049 4050 for (i = 0; i < test_params->bonded_slave_count; i++) 4051 rte_eth_stats_reset(test_params->slave_port_ids[i]); 4052 4053 /* Verify that pkts are not sent on slaves with link status down */ 4054 burst_size = 21; 4055 4056 TEST_ASSERT_EQUAL(generate_test_burst( 4057 &pkt_burst[0][0], burst_size, 0, 0, 1, 0, 0), burst_size, 4058 "generate_test_burst failed"); 4059 4060 TEST_ASSERT_EQUAL(rte_eth_tx_burst(test_params->bonded_port_id, 0, 4061 &pkt_burst[0][0], burst_size), burst_size, 4062 "rte_eth_tx_burst failed\n"); 4063 4064 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 4065 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)(burst_size * slave_count), 4066 "(%d) port_stats.opackets (%d) not as expected (%d)\n", 4067 test_params->bonded_port_id, (int)port_stats.opackets, 4068 burst_size * slave_count); 4069 4070 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 4071 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 4072 "(%d) port_stats.opackets not as expected", 4073 test_params->slave_port_ids[0]); 4074 4075 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 4076 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 4077 "(%d) port_stats.opackets not as expected", 4078 test_params->slave_port_ids[1]); 4079 4080 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 4081 TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)burst_size, 4082 "(%d) port_stats.opackets not as expected", 4083 test_params->slave_port_ids[2]); 4084 4085 4086 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 4087 TEST_ASSERT_EQUAL(port_stats.opackets, 0, 4088 "(%d) port_stats.opackets not as expected", 4089 test_params->slave_port_ids[3]); 4090 4091 4092 for (i = 0; i < BROADCAST_LINK_STATUS_NUM_OF_SLAVES; i++) { 4093 TEST_ASSERT_EQUAL(generate_test_burst( 4094 &pkt_burst[i][0], burst_size, 0, 0, 1, 0, 0), 4095 burst_size, "failed to generate packet burst"); 4096 4097 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 4098 &pkt_burst[i][0], burst_size); 4099 } 4100 4101 /* Verify that pkts are not received on slaves with link status down */ 4102 TEST_ASSERT_EQUAL(rte_eth_rx_burst( 4103 test_params->bonded_port_id, 0, rx_pkt_burst, MAX_PKT_BURST), 4104 burst_size + burst_size, "rte_eth_rx_burst failed"); 4105 4106 4107 /* Verify bonded device rx count */ 4108 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 4109 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)(burst_size + burst_size), 4110 "(%d) port_stats.ipackets not as expected\n", 4111 test_params->bonded_port_id); 4112 4113 /* Clean up and remove slaves from bonded device */ 4114 return remove_slaves_and_stop_bonded_device(); 4115 } 4116 4117 static int 4118 test_reconfigure_bonded_device(void) 4119 { 4120 test_params->nb_rx_q = 4; 4121 test_params->nb_tx_q = 4; 4122 4123 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), 4124 "failed to reconfigure bonded device"); 4125 4126 test_params->nb_rx_q = 2; 4127 test_params->nb_tx_q = 2; 4128 4129 TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0), 4130 "failed to reconfigure bonded device with less rx/tx queues"); 4131 4132 return 0; 4133 } 4134 4135 4136 static int 4137 test_close_bonded_device(void) 4138 { 4139 rte_eth_dev_close(test_params->bonded_port_id); 4140 return 0; 4141 } 4142 4143 static void 4144 testsuite_teardown(void) 4145 { 4146 free(test_params->pkt_eth_hdr); 4147 test_params->pkt_eth_hdr = NULL; 4148 4149 /* Clean up and remove slaves from bonded device */ 4150 remove_slaves_and_stop_bonded_device(); 4151 } 4152 4153 static void 4154 free_virtualpmd_tx_queue(void) 4155 { 4156 int i, slave_port, to_free_cnt; 4157 struct rte_mbuf *pkts_to_free[MAX_PKT_BURST]; 4158 4159 /* Free tx queue of virtual pmd */ 4160 for (slave_port = 0; slave_port < test_params->bonded_slave_count; 4161 slave_port++) { 4162 to_free_cnt = virtual_ethdev_get_mbufs_from_tx_queue( 4163 test_params->slave_port_ids[slave_port], 4164 pkts_to_free, MAX_PKT_BURST); 4165 for (i = 0; i < to_free_cnt; i++) 4166 rte_pktmbuf_free(pkts_to_free[i]); 4167 } 4168 } 4169 4170 static int 4171 test_tlb_tx_burst(void) 4172 { 4173 int i, burst_size, nb_tx; 4174 uint64_t nb_tx2 = 0; 4175 struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; 4176 struct rte_eth_stats port_stats[32]; 4177 uint64_t sum_ports_opackets = 0, all_bond_opackets = 0, all_bond_obytes = 0; 4178 uint16_t pktlen; 4179 4180 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves 4181 (BONDING_MODE_TLB, 1, 3, 1), 4182 "Failed to initialise bonded device"); 4183 4184 burst_size = 20 * test_params->bonded_slave_count; 4185 4186 TEST_ASSERT(burst_size < MAX_PKT_BURST, 4187 "Burst size specified is greater than supported.\n"); 4188 4189 4190 /* Generate bursts of packets */ 4191 for (i = 0; i < 400000; i++) { 4192 /*test two types of mac src own(bonding) and others */ 4193 if (i % 2 == 0) { 4194 initialize_eth_header(test_params->pkt_eth_hdr, 4195 (struct rte_ether_addr *)src_mac, 4196 (struct rte_ether_addr *)dst_mac_0, 4197 RTE_ETHER_TYPE_IPV4, 0, 0); 4198 } else { 4199 initialize_eth_header(test_params->pkt_eth_hdr, 4200 (struct rte_ether_addr *)test_params->default_slave_mac, 4201 (struct rte_ether_addr *)dst_mac_0, 4202 RTE_ETHER_TYPE_IPV4, 0, 0); 4203 } 4204 pktlen = initialize_udp_header(test_params->pkt_udp_hdr, src_port, 4205 dst_port_0, 16); 4206 pktlen = initialize_ipv4_header(test_params->pkt_ipv4_hdr, src_addr, 4207 dst_addr_0, pktlen); 4208 generate_packet_burst(test_params->mbuf_pool, pkt_burst, 4209 test_params->pkt_eth_hdr, 0, test_params->pkt_ipv4_hdr, 4210 1, test_params->pkt_udp_hdr, burst_size, 60, 1); 4211 /* Send burst on bonded port */ 4212 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, 4213 burst_size); 4214 nb_tx2 += nb_tx; 4215 4216 free_virtualpmd_tx_queue(); 4217 4218 TEST_ASSERT_EQUAL(nb_tx, burst_size, 4219 "number of packet not equal burst size"); 4220 4221 rte_delay_us(5); 4222 } 4223 4224 4225 /* Verify bonded port tx stats */ 4226 rte_eth_stats_get(test_params->bonded_port_id, &port_stats[0]); 4227 4228 all_bond_opackets = port_stats[0].opackets; 4229 all_bond_obytes = port_stats[0].obytes; 4230 4231 TEST_ASSERT_EQUAL(port_stats[0].opackets, (uint64_t)nb_tx2, 4232 "Bonded Port (%d) opackets value (%u) not as expected (%d)\n", 4233 test_params->bonded_port_id, (unsigned int)port_stats[0].opackets, 4234 burst_size); 4235 4236 4237 /* Verify slave ports tx stats */ 4238 for (i = 0; i < test_params->bonded_slave_count; i++) { 4239 rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats[i]); 4240 sum_ports_opackets += port_stats[i].opackets; 4241 } 4242 4243 TEST_ASSERT_EQUAL(sum_ports_opackets, (uint64_t)all_bond_opackets, 4244 "Total packets sent by slaves is not equal to packets sent by bond interface"); 4245 4246 /* checking if distribution of packets is balanced over slaves */ 4247 for (i = 0; i < test_params->bonded_slave_count; i++) { 4248 TEST_ASSERT(port_stats[i].obytes > 0 && 4249 port_stats[i].obytes < all_bond_obytes, 4250 "Packets are not balanced over slaves"); 4251 } 4252 4253 /* Put all slaves down and try and transmit */ 4254 for (i = 0; i < test_params->bonded_slave_count; i++) { 4255 virtual_ethdev_simulate_link_status_interrupt( 4256 test_params->slave_port_ids[i], 0); 4257 } 4258 4259 /* Send burst on bonded port */ 4260 nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst, 4261 burst_size); 4262 TEST_ASSERT_EQUAL(nb_tx, 0, " bad number of packet in burst"); 4263 4264 /* Clean ugit checkout masterp and remove slaves from bonded device */ 4265 return remove_slaves_and_stop_bonded_device(); 4266 } 4267 4268 #define TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT (4) 4269 4270 static int 4271 test_tlb_rx_burst(void) 4272 { 4273 struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL }; 4274 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 4275 4276 struct rte_eth_stats port_stats; 4277 4278 int primary_port; 4279 4280 uint16_t i, j, nb_rx, burst_size = 17; 4281 4282 /* Initialize bonded device with 4 slaves in transmit load balancing mode */ 4283 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 4284 BONDING_MODE_TLB, 4285 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1, 1), 4286 "Failed to initialize bonded device"); 4287 4288 4289 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 4290 TEST_ASSERT(primary_port >= 0, 4291 "failed to get primary slave for bonded port (%d)", 4292 test_params->bonded_port_id); 4293 4294 for (i = 0; i < test_params->bonded_slave_count; i++) { 4295 /* Generate test bursts of packets to transmit */ 4296 TEST_ASSERT_EQUAL(generate_test_burst( 4297 &gen_pkt_burst[0], burst_size, 0, 1, 0, 0, 0), burst_size, 4298 "burst generation failed"); 4299 4300 /* Add rx data to slave */ 4301 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[i], 4302 &gen_pkt_burst[0], burst_size); 4303 4304 /* Call rx burst on bonded device */ 4305 nb_rx = rte_eth_rx_burst(test_params->bonded_port_id, 0, 4306 &rx_pkt_burst[0], MAX_PKT_BURST); 4307 4308 TEST_ASSERT_EQUAL(nb_rx, burst_size, "rte_eth_rx_burst failed\n"); 4309 4310 if (test_params->slave_port_ids[i] == primary_port) { 4311 /* Verify bonded device rx count */ 4312 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 4313 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, 4314 "Bonded Port (%d) ipackets value (%u) not as expected (%d)\n", 4315 test_params->bonded_port_id, 4316 (unsigned int)port_stats.ipackets, burst_size); 4317 4318 /* Verify bonded slave devices rx count */ 4319 for (j = 0; j < test_params->bonded_slave_count; j++) { 4320 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); 4321 if (i == j) { 4322 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, 4323 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", 4324 test_params->slave_port_ids[i], 4325 (unsigned int)port_stats.ipackets, burst_size); 4326 } else { 4327 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0, 4328 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", 4329 test_params->slave_port_ids[i], 4330 (unsigned int)port_stats.ipackets, 0); 4331 } 4332 } 4333 } else { 4334 for (j = 0; j < test_params->bonded_slave_count; j++) { 4335 rte_eth_stats_get(test_params->slave_port_ids[j], &port_stats); 4336 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)0, 4337 "Slave Port (%d) ipackets value (%u) not as expected (%d)\n", 4338 test_params->slave_port_ids[i], 4339 (unsigned int)port_stats.ipackets, 0); 4340 } 4341 } 4342 4343 /* free mbufs */ 4344 for (i = 0; i < burst_size; i++) 4345 rte_pktmbuf_free(rx_pkt_burst[i]); 4346 4347 /* reset bonded device stats */ 4348 rte_eth_stats_reset(test_params->bonded_port_id); 4349 } 4350 4351 /* Clean up and remove slaves from bonded device */ 4352 return remove_slaves_and_stop_bonded_device(); 4353 } 4354 4355 static int 4356 test_tlb_verify_promiscuous_enable_disable(void) 4357 { 4358 int i, primary_port, promiscuous_en; 4359 int ret; 4360 4361 /* Initialize bonded device with 4 slaves in transmit load balancing mode */ 4362 TEST_ASSERT_SUCCESS( initialize_bonded_device_with_slaves( 4363 BONDING_MODE_TLB, 0, 4, 1), 4364 "Failed to initialize bonded device"); 4365 4366 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 4367 TEST_ASSERT(primary_port >= 0, 4368 "failed to get primary slave for bonded port (%d)", 4369 test_params->bonded_port_id); 4370 4371 ret = rte_eth_promiscuous_enable(test_params->bonded_port_id); 4372 TEST_ASSERT_SUCCESS(ret, 4373 "Failed to enable promiscuous mode for port %d: %s", 4374 test_params->bonded_port_id, rte_strerror(-ret)); 4375 4376 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); 4377 TEST_ASSERT_EQUAL(promiscuous_en, (int)1, 4378 "Port (%d) promiscuous mode not enabled\n", 4379 test_params->bonded_port_id); 4380 for (i = 0; i < test_params->bonded_slave_count; i++) { 4381 promiscuous_en = rte_eth_promiscuous_get( 4382 test_params->slave_port_ids[i]); 4383 if (primary_port == test_params->slave_port_ids[i]) { 4384 TEST_ASSERT_EQUAL(promiscuous_en, (int)1, 4385 "Port (%d) promiscuous mode not enabled\n", 4386 test_params->bonded_port_id); 4387 } else { 4388 TEST_ASSERT_EQUAL(promiscuous_en, (int)0, 4389 "Port (%d) promiscuous mode enabled\n", 4390 test_params->bonded_port_id); 4391 } 4392 4393 } 4394 4395 ret = rte_eth_promiscuous_disable(test_params->bonded_port_id); 4396 TEST_ASSERT_SUCCESS(ret, 4397 "Failed to disable promiscuous mode for port %d: %s\n", 4398 test_params->bonded_port_id, rte_strerror(-ret)); 4399 4400 promiscuous_en = rte_eth_promiscuous_get(test_params->bonded_port_id); 4401 TEST_ASSERT_EQUAL(promiscuous_en, (int)0, 4402 "Port (%d) promiscuous mode not disabled\n", 4403 test_params->bonded_port_id); 4404 4405 for (i = 0; i < test_params->bonded_slave_count; i++) { 4406 promiscuous_en = rte_eth_promiscuous_get( 4407 test_params->slave_port_ids[i]); 4408 TEST_ASSERT_EQUAL(promiscuous_en, (int)0, 4409 "slave port (%d) promiscuous mode not disabled\n", 4410 test_params->slave_port_ids[i]); 4411 } 4412 4413 /* Clean up and remove slaves from bonded device */ 4414 return remove_slaves_and_stop_bonded_device(); 4415 } 4416 4417 static int 4418 test_tlb_verify_mac_assignment(void) 4419 { 4420 struct rte_ether_addr read_mac_addr; 4421 struct rte_ether_addr expected_mac_addr_0, expected_mac_addr_1; 4422 4423 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &expected_mac_addr_0), 4424 "Failed to get mac address (port %d)", 4425 test_params->slave_port_ids[0]); 4426 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &expected_mac_addr_1), 4427 "Failed to get mac address (port %d)", 4428 test_params->slave_port_ids[1]); 4429 4430 /* Initialize bonded device with 2 slaves in active backup mode */ 4431 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 4432 BONDING_MODE_TLB, 0, 2, 1), 4433 "Failed to initialize bonded device"); 4434 4435 /* Verify that bonded MACs is that of first slave and that the other slave 4436 * MAC hasn't been changed */ 4437 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 4438 "Failed to get mac address (port %d)", 4439 test_params->bonded_port_id); 4440 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 4441 sizeof(read_mac_addr)), 4442 "bonded port (%d) mac address not set to that of primary port", 4443 test_params->bonded_port_id); 4444 4445 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 4446 "Failed to get mac address (port %d)", 4447 test_params->slave_port_ids[0]); 4448 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 4449 sizeof(read_mac_addr)), 4450 "slave port (%d) mac address not set to that of primary port", 4451 test_params->slave_port_ids[0]); 4452 4453 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 4454 "Failed to get mac address (port %d)", 4455 test_params->slave_port_ids[1]); 4456 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 4457 sizeof(read_mac_addr)), 4458 "slave port (%d) mac address not as expected", 4459 test_params->slave_port_ids[1]); 4460 4461 /* change primary and verify that MAC addresses haven't changed */ 4462 TEST_ASSERT_EQUAL(rte_eth_bond_primary_set(test_params->bonded_port_id, 4463 test_params->slave_port_ids[1]), 0, 4464 "Failed to set bonded port (%d) primary port to (%d)", 4465 test_params->bonded_port_id, test_params->slave_port_ids[1]); 4466 4467 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 4468 "Failed to get mac address (port %d)", 4469 test_params->bonded_port_id); 4470 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 4471 sizeof(read_mac_addr)), 4472 "bonded port (%d) mac address not set to that of primary port", 4473 test_params->bonded_port_id); 4474 4475 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 4476 "Failed to get mac address (port %d)", 4477 test_params->slave_port_ids[0]); 4478 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 4479 sizeof(read_mac_addr)), 4480 "slave port (%d) mac address not set to that of primary port", 4481 test_params->slave_port_ids[0]); 4482 4483 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 4484 "Failed to get mac address (port %d)", 4485 test_params->slave_port_ids[1]); 4486 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 4487 sizeof(read_mac_addr)), 4488 "slave port (%d) mac address not as expected", 4489 test_params->slave_port_ids[1]); 4490 4491 /* stop / start bonded device and verify that primary MAC address is 4492 * propagated to bonded device and slaves */ 4493 4494 TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params->bonded_port_id), 4495 "Failed to stop bonded port %u", 4496 test_params->bonded_port_id); 4497 4498 TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params->bonded_port_id), 4499 "Failed to start device"); 4500 4501 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 4502 "Failed to get mac address (port %d)", 4503 test_params->bonded_port_id); 4504 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 4505 sizeof(read_mac_addr)), 4506 "bonded port (%d) mac address not set to that of primary port", 4507 test_params->bonded_port_id); 4508 4509 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 4510 "Failed to get mac address (port %d)", 4511 test_params->slave_port_ids[0]); 4512 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 4513 sizeof(read_mac_addr)), 4514 "slave port (%d) mac address not as expected", 4515 test_params->slave_port_ids[0]); 4516 4517 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 4518 "Failed to get mac address (port %d)", 4519 test_params->slave_port_ids[1]); 4520 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_1, &read_mac_addr, 4521 sizeof(read_mac_addr)), 4522 "slave port (%d) mac address not set to that of primary port", 4523 test_params->slave_port_ids[1]); 4524 4525 4526 /* Set explicit MAC address */ 4527 TEST_ASSERT_SUCCESS(rte_eth_bond_mac_address_set( 4528 test_params->bonded_port_id, 4529 (struct rte_ether_addr *)bonded_mac), 4530 "failed to set MAC address"); 4531 4532 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->bonded_port_id, &read_mac_addr), 4533 "Failed to get mac address (port %d)", 4534 test_params->bonded_port_id); 4535 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 4536 sizeof(read_mac_addr)), 4537 "bonded port (%d) mac address not set to that of bonded port", 4538 test_params->bonded_port_id); 4539 4540 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[0], &read_mac_addr), 4541 "Failed to get mac address (port %d)", 4542 test_params->slave_port_ids[0]); 4543 TEST_ASSERT_SUCCESS(memcmp(&expected_mac_addr_0, &read_mac_addr, 4544 sizeof(read_mac_addr)), 4545 "slave port (%d) mac address not as expected", 4546 test_params->slave_port_ids[0]); 4547 4548 TEST_ASSERT_SUCCESS(rte_eth_macaddr_get(test_params->slave_port_ids[1], &read_mac_addr), 4549 "Failed to get mac address (port %d)", 4550 test_params->slave_port_ids[1]); 4551 TEST_ASSERT_SUCCESS(memcmp(&bonded_mac, &read_mac_addr, 4552 sizeof(read_mac_addr)), 4553 "slave port (%d) mac address not set to that of bonded port", 4554 test_params->slave_port_ids[1]); 4555 4556 /* Clean up and remove slaves from bonded device */ 4557 return remove_slaves_and_stop_bonded_device(); 4558 } 4559 4560 static int 4561 test_tlb_verify_slave_link_status_change_failover(void) 4562 { 4563 struct rte_mbuf *pkt_burst[TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT][MAX_PKT_BURST]; 4564 struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST] = { NULL }; 4565 struct rte_eth_stats port_stats; 4566 4567 uint16_t slaves[RTE_MAX_ETHPORTS]; 4568 4569 int i, burst_size, slave_count, primary_port; 4570 4571 burst_size = 21; 4572 4573 memset(pkt_burst, 0, sizeof(pkt_burst)); 4574 4575 4576 4577 /* Initialize bonded device with 4 slaves in round robin mode */ 4578 TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves( 4579 BONDING_MODE_TLB, 0, 4580 TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT, 1), 4581 "Failed to initialize bonded device with slaves"); 4582 4583 /* Verify Current Slaves Count /Active Slave Count is */ 4584 slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id, slaves, 4585 RTE_MAX_ETHPORTS); 4586 TEST_ASSERT_EQUAL(slave_count, 4, 4587 "Number of slaves (%d) is not as expected (%d).\n", 4588 slave_count, 4); 4589 4590 slave_count = rte_eth_bond_active_slaves_get(test_params->bonded_port_id, 4591 slaves, RTE_MAX_ETHPORTS); 4592 TEST_ASSERT_EQUAL(slave_count, (int)4, 4593 "Number of slaves (%d) is not as expected (%d).\n", 4594 slave_count, 4); 4595 4596 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 4597 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[0], 4598 "Primary port not as expected"); 4599 4600 /* Bring 2 slaves down and verify active slave count */ 4601 virtual_ethdev_simulate_link_status_interrupt( 4602 test_params->slave_port_ids[1], 0); 4603 virtual_ethdev_simulate_link_status_interrupt( 4604 test_params->slave_port_ids[3], 0); 4605 4606 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( 4607 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 2, 4608 "Number of active slaves (%d) is not as expected (%d).", 4609 slave_count, 2); 4610 4611 virtual_ethdev_simulate_link_status_interrupt( 4612 test_params->slave_port_ids[1], 1); 4613 virtual_ethdev_simulate_link_status_interrupt( 4614 test_params->slave_port_ids[3], 1); 4615 4616 4617 /* Bring primary port down, verify that active slave count is 3 and primary 4618 * has changed */ 4619 virtual_ethdev_simulate_link_status_interrupt( 4620 test_params->slave_port_ids[0], 0); 4621 4622 TEST_ASSERT_EQUAL(rte_eth_bond_active_slaves_get( 4623 test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS), 3, 4624 "Number of active slaves (%d) is not as expected (%d).", 4625 slave_count, 3); 4626 4627 primary_port = rte_eth_bond_primary_get(test_params->bonded_port_id); 4628 TEST_ASSERT_EQUAL(primary_port, test_params->slave_port_ids[2], 4629 "Primary port not as expected"); 4630 rte_delay_us(500000); 4631 /* Verify that pkts are sent on new primary slave */ 4632 for (i = 0; i < 4; i++) { 4633 TEST_ASSERT_EQUAL(generate_test_burst( 4634 &pkt_burst[0][0], burst_size, 0, 1, 0, 0, 0), burst_size, 4635 "generate_test_burst failed\n"); 4636 TEST_ASSERT_EQUAL(rte_eth_tx_burst( 4637 test_params->bonded_port_id, 0, &pkt_burst[0][0], burst_size), burst_size, 4638 "rte_eth_tx_burst failed\n"); 4639 rte_delay_us(11000); 4640 } 4641 4642 rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats); 4643 TEST_ASSERT_EQUAL(port_stats.opackets, (int8_t)0, 4644 "(%d) port_stats.opackets not as expected\n", 4645 test_params->slave_port_ids[0]); 4646 4647 rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats); 4648 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, 4649 "(%d) port_stats.opackets not as expected\n", 4650 test_params->slave_port_ids[1]); 4651 4652 rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats); 4653 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, 4654 "(%d) port_stats.opackets not as expected\n", 4655 test_params->slave_port_ids[2]); 4656 4657 rte_eth_stats_get(test_params->slave_port_ids[3], &port_stats); 4658 TEST_ASSERT_NOT_EQUAL(port_stats.opackets, (int8_t)0, 4659 "(%d) port_stats.opackets not as expected\n", 4660 test_params->slave_port_ids[3]); 4661 4662 4663 /* Generate packet burst for testing */ 4664 4665 for (i = 0; i < TEST_ADAPTIVE_TRANSMIT_LOAD_BALANCING_RX_BURST_SLAVE_COUNT; i++) { 4666 if (generate_test_burst(&pkt_burst[i][0], burst_size, 0, 1, 0, 0, 0) != 4667 burst_size) 4668 return -1; 4669 4670 virtual_ethdev_add_mbufs_to_rx_queue( 4671 test_params->slave_port_ids[i], &pkt_burst[i][0], burst_size); 4672 } 4673 4674 if (rte_eth_rx_burst(test_params->bonded_port_id, 0, rx_pkt_burst, 4675 MAX_PKT_BURST) != burst_size) { 4676 printf("rte_eth_rx_burst\n"); 4677 return -1; 4678 4679 } 4680 4681 /* Verify bonded device rx count */ 4682 rte_eth_stats_get(test_params->bonded_port_id, &port_stats); 4683 TEST_ASSERT_EQUAL(port_stats.ipackets, (uint64_t)burst_size, 4684 "(%d) port_stats.ipackets not as expected\n", 4685 test_params->bonded_port_id); 4686 4687 /* Clean up and remove slaves from bonded device */ 4688 return remove_slaves_and_stop_bonded_device(); 4689 } 4690 4691 #define TEST_ALB_SLAVE_COUNT 2 4692 4693 static uint8_t mac_client1[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 1}; 4694 static uint8_t mac_client2[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 2}; 4695 static uint8_t mac_client3[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 3}; 4696 static uint8_t mac_client4[] = {0x00, 0xAA, 0x55, 0xFF, 0xCC, 4}; 4697 4698 static uint32_t ip_host = IPV4_ADDR(192, 168, 0, 0); 4699 static uint32_t ip_client1 = IPV4_ADDR(192, 168, 0, 1); 4700 static uint32_t ip_client2 = IPV4_ADDR(192, 168, 0, 2); 4701 static uint32_t ip_client3 = IPV4_ADDR(192, 168, 0, 3); 4702 static uint32_t ip_client4 = IPV4_ADDR(192, 168, 0, 4); 4703 4704 static int 4705 test_alb_change_mac_in_reply_sent(void) 4706 { 4707 struct rte_mbuf *pkt; 4708 struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; 4709 4710 struct rte_ether_hdr *eth_pkt; 4711 struct rte_arp_hdr *arp_pkt; 4712 4713 int slave_idx, nb_pkts, pkt_idx; 4714 int retval = 0; 4715 4716 struct rte_ether_addr bond_mac, client_mac; 4717 struct rte_ether_addr *slave_mac1, *slave_mac2; 4718 4719 TEST_ASSERT_SUCCESS( 4720 initialize_bonded_device_with_slaves(BONDING_MODE_ALB, 4721 0, TEST_ALB_SLAVE_COUNT, 1), 4722 "Failed to initialize_bonded_device_with_slaves."); 4723 4724 /* Flush tx queue */ 4725 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); 4726 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; 4727 slave_idx++) { 4728 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( 4729 test_params->slave_port_ids[slave_idx], pkts_sent, 4730 MAX_PKT_BURST); 4731 } 4732 4733 rte_ether_addr_copy( 4734 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, 4735 &bond_mac); 4736 4737 /* 4738 * Generating four packets with different mac and ip addresses and sending 4739 * them through the bonding port. 4740 */ 4741 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4742 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN); 4743 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4744 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4745 RTE_ETHER_TYPE_ARP, 0, 0); 4746 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4747 sizeof(struct rte_ether_hdr)); 4748 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client1, 4749 RTE_ARP_OP_REPLY); 4750 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); 4751 4752 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4753 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN); 4754 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4755 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4756 RTE_ETHER_TYPE_ARP, 0, 0); 4757 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4758 sizeof(struct rte_ether_hdr)); 4759 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client2, 4760 RTE_ARP_OP_REPLY); 4761 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); 4762 4763 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4764 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN); 4765 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4766 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4767 RTE_ETHER_TYPE_ARP, 0, 0); 4768 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4769 sizeof(struct rte_ether_hdr)); 4770 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client3, 4771 RTE_ARP_OP_REPLY); 4772 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); 4773 4774 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4775 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN); 4776 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4777 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4778 RTE_ETHER_TYPE_ARP, 0, 0); 4779 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4780 sizeof(struct rte_ether_hdr)); 4781 initialize_arp_header(arp_pkt, &bond_mac, &client_mac, ip_host, ip_client4, 4782 RTE_ARP_OP_REPLY); 4783 rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt, 1); 4784 4785 slave_mac1 = 4786 rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs; 4787 slave_mac2 = 4788 rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs; 4789 4790 /* 4791 * Checking if packets are properly distributed on bonding ports. Packets 4792 * 0 and 2 should be sent on port 0 and packets 1 and 3 on port 1. 4793 */ 4794 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { 4795 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( 4796 test_params->slave_port_ids[slave_idx], pkts_sent, 4797 MAX_PKT_BURST); 4798 4799 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { 4800 eth_pkt = rte_pktmbuf_mtod( 4801 pkts_sent[pkt_idx], struct rte_ether_hdr *); 4802 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4803 sizeof(struct rte_ether_hdr)); 4804 4805 if (slave_idx%2 == 0) { 4806 if (!rte_is_same_ether_addr(slave_mac1, 4807 &arp_pkt->arp_data.arp_sha)) { 4808 retval = -1; 4809 goto test_end; 4810 } 4811 } else { 4812 if (!rte_is_same_ether_addr(slave_mac2, 4813 &arp_pkt->arp_data.arp_sha)) { 4814 retval = -1; 4815 goto test_end; 4816 } 4817 } 4818 } 4819 } 4820 4821 test_end: 4822 retval += remove_slaves_and_stop_bonded_device(); 4823 return retval; 4824 } 4825 4826 static int 4827 test_alb_reply_from_client(void) 4828 { 4829 struct rte_ether_hdr *eth_pkt; 4830 struct rte_arp_hdr *arp_pkt; 4831 4832 struct rte_mbuf *pkt; 4833 struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; 4834 4835 int slave_idx, nb_pkts, pkt_idx, nb_pkts_sum = 0; 4836 int retval = 0; 4837 4838 struct rte_ether_addr bond_mac, client_mac; 4839 struct rte_ether_addr *slave_mac1, *slave_mac2; 4840 4841 TEST_ASSERT_SUCCESS( 4842 initialize_bonded_device_with_slaves(BONDING_MODE_ALB, 4843 0, TEST_ALB_SLAVE_COUNT, 1), 4844 "Failed to initialize_bonded_device_with_slaves."); 4845 4846 /* Flush tx queue */ 4847 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); 4848 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { 4849 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( 4850 test_params->slave_port_ids[slave_idx], pkts_sent, 4851 MAX_PKT_BURST); 4852 } 4853 4854 rte_ether_addr_copy( 4855 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, 4856 &bond_mac); 4857 4858 /* 4859 * Generating four packets with different mac and ip addresses and placing 4860 * them in the rx queue to be received by the bonding driver on rx_burst. 4861 */ 4862 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4863 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN); 4864 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4865 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4866 RTE_ETHER_TYPE_ARP, 0, 0); 4867 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4868 sizeof(struct rte_ether_hdr)); 4869 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host, 4870 RTE_ARP_OP_REPLY); 4871 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, 4872 1); 4873 4874 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4875 memcpy(client_mac.addr_bytes, mac_client2, RTE_ETHER_ADDR_LEN); 4876 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4877 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4878 RTE_ETHER_TYPE_ARP, 0, 0); 4879 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4880 sizeof(struct rte_ether_hdr)); 4881 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client2, ip_host, 4882 RTE_ARP_OP_REPLY); 4883 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, 4884 1); 4885 4886 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4887 memcpy(client_mac.addr_bytes, mac_client3, RTE_ETHER_ADDR_LEN); 4888 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4889 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4890 RTE_ETHER_TYPE_ARP, 0, 0); 4891 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4892 sizeof(struct rte_ether_hdr)); 4893 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client3, ip_host, 4894 RTE_ARP_OP_REPLY); 4895 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, 4896 1); 4897 4898 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4899 memcpy(client_mac.addr_bytes, mac_client4, RTE_ETHER_ADDR_LEN); 4900 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4901 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 4902 RTE_ETHER_TYPE_ARP, 0, 0); 4903 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4904 sizeof(struct rte_ether_hdr)); 4905 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client4, ip_host, 4906 RTE_ARP_OP_REPLY); 4907 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, 4908 1); 4909 4910 /* 4911 * Issue rx_burst and tx_burst to force bonding driver to send update ARP 4912 * packets to every client in alb table. 4913 */ 4914 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST); 4915 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); 4916 4917 slave_mac1 = rte_eth_devices[test_params->slave_port_ids[0]].data->mac_addrs; 4918 slave_mac2 = rte_eth_devices[test_params->slave_port_ids[1]].data->mac_addrs; 4919 4920 /* 4921 * Checking if update ARP packets were properly send on slave ports. 4922 */ 4923 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { 4924 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( 4925 test_params->slave_port_ids[slave_idx], pkts_sent, MAX_PKT_BURST); 4926 nb_pkts_sum += nb_pkts; 4927 4928 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { 4929 eth_pkt = rte_pktmbuf_mtod( 4930 pkts_sent[pkt_idx], struct rte_ether_hdr *); 4931 arp_pkt = (struct rte_arp_hdr *)((char *)eth_pkt + 4932 sizeof(struct rte_ether_hdr)); 4933 4934 if (slave_idx%2 == 0) { 4935 if (!rte_is_same_ether_addr(slave_mac1, 4936 &arp_pkt->arp_data.arp_sha)) { 4937 retval = -1; 4938 goto test_end; 4939 } 4940 } else { 4941 if (!rte_is_same_ether_addr(slave_mac2, 4942 &arp_pkt->arp_data.arp_sha)) { 4943 retval = -1; 4944 goto test_end; 4945 } 4946 } 4947 } 4948 } 4949 4950 /* Check if proper number of packets was send */ 4951 if (nb_pkts_sum < 4) { 4952 retval = -1; 4953 goto test_end; 4954 } 4955 4956 test_end: 4957 retval += remove_slaves_and_stop_bonded_device(); 4958 return retval; 4959 } 4960 4961 static int 4962 test_alb_receive_vlan_reply(void) 4963 { 4964 struct rte_ether_hdr *eth_pkt; 4965 struct rte_vlan_hdr *vlan_pkt; 4966 struct rte_arp_hdr *arp_pkt; 4967 4968 struct rte_mbuf *pkt; 4969 struct rte_mbuf *pkts_sent[MAX_PKT_BURST]; 4970 4971 int slave_idx, nb_pkts, pkt_idx; 4972 int retval = 0; 4973 4974 struct rte_ether_addr bond_mac, client_mac; 4975 4976 TEST_ASSERT_SUCCESS( 4977 initialize_bonded_device_with_slaves(BONDING_MODE_ALB, 4978 0, TEST_ALB_SLAVE_COUNT, 1), 4979 "Failed to initialize_bonded_device_with_slaves."); 4980 4981 /* Flush tx queue */ 4982 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); 4983 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { 4984 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( 4985 test_params->slave_port_ids[slave_idx], pkts_sent, 4986 MAX_PKT_BURST); 4987 } 4988 4989 rte_ether_addr_copy( 4990 rte_eth_devices[test_params->bonded_port_id].data->mac_addrs, 4991 &bond_mac); 4992 4993 /* 4994 * Generating packet with double VLAN header and placing it in the rx queue. 4995 */ 4996 pkt = rte_pktmbuf_alloc(test_params->mbuf_pool); 4997 memcpy(client_mac.addr_bytes, mac_client1, RTE_ETHER_ADDR_LEN); 4998 eth_pkt = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 4999 initialize_eth_header(eth_pkt, &bond_mac, &client_mac, 5000 RTE_ETHER_TYPE_VLAN, 0, 0); 5001 vlan_pkt = (struct rte_vlan_hdr *)((char *)(eth_pkt + 1)); 5002 vlan_pkt->vlan_tci = rte_cpu_to_be_16(1); 5003 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 5004 vlan_pkt = vlan_pkt+1; 5005 vlan_pkt->vlan_tci = rte_cpu_to_be_16(2); 5006 vlan_pkt->eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP); 5007 arp_pkt = (struct rte_arp_hdr *)((char *)(vlan_pkt + 1)); 5008 initialize_arp_header(arp_pkt, &client_mac, &bond_mac, ip_client1, ip_host, 5009 RTE_ARP_OP_REPLY); 5010 virtual_ethdev_add_mbufs_to_rx_queue(test_params->slave_port_ids[0], &pkt, 5011 1); 5012 5013 rte_eth_rx_burst(test_params->bonded_port_id, 0, pkts_sent, MAX_PKT_BURST); 5014 rte_eth_tx_burst(test_params->bonded_port_id, 0, NULL, 0); 5015 5016 /* 5017 * Checking if VLAN headers in generated ARP Update packet are correct. 5018 */ 5019 for (slave_idx = 0; slave_idx < test_params->bonded_slave_count; slave_idx++) { 5020 nb_pkts = virtual_ethdev_get_mbufs_from_tx_queue( 5021 test_params->slave_port_ids[slave_idx], pkts_sent, 5022 MAX_PKT_BURST); 5023 5024 for (pkt_idx = 0; pkt_idx < nb_pkts; pkt_idx++) { 5025 eth_pkt = rte_pktmbuf_mtod( 5026 pkts_sent[pkt_idx], struct rte_ether_hdr *); 5027 vlan_pkt = (struct rte_vlan_hdr *)( 5028 (char *)(eth_pkt + 1)); 5029 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(1)) { 5030 retval = -1; 5031 goto test_end; 5032 } 5033 if (vlan_pkt->eth_proto != rte_cpu_to_be_16( 5034 RTE_ETHER_TYPE_VLAN)) { 5035 retval = -1; 5036 goto test_end; 5037 } 5038 vlan_pkt = vlan_pkt+1; 5039 if (vlan_pkt->vlan_tci != rte_cpu_to_be_16(2)) { 5040 retval = -1; 5041 goto test_end; 5042 } 5043 if (vlan_pkt->eth_proto != rte_cpu_to_be_16( 5044 RTE_ETHER_TYPE_ARP)) { 5045 retval = -1; 5046 goto test_end; 5047 } 5048 } 5049 } 5050 5051 test_end: 5052 retval += remove_slaves_and_stop_bonded_device(); 5053 return retval; 5054 } 5055 5056 static int 5057 test_alb_ipv4_tx(void) 5058 { 5059 int burst_size, retval, pkts_send; 5060 struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; 5061 5062 retval = 0; 5063 5064 TEST_ASSERT_SUCCESS( 5065 initialize_bonded_device_with_slaves(BONDING_MODE_ALB, 5066 0, TEST_ALB_SLAVE_COUNT, 1), 5067 "Failed to initialize_bonded_device_with_slaves."); 5068 5069 burst_size = 32; 5070 5071 /* Generate test bursts of packets to transmit */ 5072 if (generate_test_burst(pkt_burst, burst_size, 0, 1, 0, 0, 0) != burst_size) { 5073 retval = -1; 5074 goto test_end; 5075 } 5076 5077 /* 5078 * Checking if ipv4 traffic is transmitted via TLB policy. 5079 */ 5080 pkts_send = rte_eth_tx_burst( 5081 test_params->bonded_port_id, 0, pkt_burst, burst_size); 5082 if (pkts_send != burst_size) { 5083 retval = -1; 5084 goto test_end; 5085 } 5086 5087 test_end: 5088 retval += remove_slaves_and_stop_bonded_device(); 5089 return retval; 5090 } 5091 5092 static struct unit_test_suite link_bonding_test_suite = { 5093 .suite_name = "Link Bonding Unit Test Suite", 5094 .setup = test_setup, 5095 .teardown = testsuite_teardown, 5096 .unit_test_cases = { 5097 TEST_CASE(test_create_bonded_device), 5098 TEST_CASE(test_create_bonded_device_with_invalid_params), 5099 TEST_CASE(test_add_slave_to_bonded_device), 5100 TEST_CASE(test_add_slave_to_invalid_bonded_device), 5101 TEST_CASE(test_remove_slave_from_bonded_device), 5102 TEST_CASE(test_remove_slave_from_invalid_bonded_device), 5103 TEST_CASE(test_get_slaves_from_bonded_device), 5104 TEST_CASE(test_add_already_bonded_slave_to_bonded_device), 5105 TEST_CASE(test_add_remove_multiple_slaves_to_from_bonded_device), 5106 TEST_CASE(test_start_bonded_device), 5107 TEST_CASE(test_stop_bonded_device), 5108 TEST_CASE(test_set_bonding_mode), 5109 TEST_CASE(test_set_primary_slave), 5110 TEST_CASE(test_set_explicit_bonded_mac), 5111 TEST_CASE(test_set_bonded_port_initialization_mac_assignment), 5112 TEST_CASE(test_status_interrupt), 5113 TEST_CASE(test_adding_slave_after_bonded_device_started), 5114 TEST_CASE(test_roundrobin_tx_burst), 5115 TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail), 5116 TEST_CASE(test_roundrobin_rx_burst_on_single_slave), 5117 TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves), 5118 TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable), 5119 TEST_CASE(test_roundrobin_verify_mac_assignment), 5120 TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour), 5121 TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change), 5122 TEST_CASE(test_activebackup_tx_burst), 5123 TEST_CASE(test_activebackup_rx_burst), 5124 TEST_CASE(test_activebackup_verify_promiscuous_enable_disable), 5125 TEST_CASE(test_activebackup_verify_mac_assignment), 5126 TEST_CASE(test_activebackup_verify_slave_link_status_change_failover), 5127 TEST_CASE(test_balance_xmit_policy_configuration), 5128 TEST_CASE(test_balance_l2_tx_burst), 5129 TEST_CASE(test_balance_l23_tx_burst_ipv4_toggle_ip_addr), 5130 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv4_toggle_ip_addr), 5131 TEST_CASE(test_balance_l23_tx_burst_ipv6_toggle_ip_addr), 5132 TEST_CASE(test_balance_l23_tx_burst_vlan_ipv6_toggle_ip_addr), 5133 TEST_CASE(test_balance_l23_tx_burst_toggle_mac_addr), 5134 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_ip_addr), 5135 TEST_CASE(test_balance_l34_tx_burst_ipv4_toggle_udp_port), 5136 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv4_toggle_ip_addr), 5137 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr), 5138 TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr), 5139 TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port), 5140 TEST_CASE(test_balance_tx_burst_slave_tx_fail), 5141 TEST_CASE(test_balance_rx_burst), 5142 TEST_CASE(test_balance_verify_promiscuous_enable_disable), 5143 TEST_CASE(test_balance_verify_mac_assignment), 5144 TEST_CASE(test_balance_verify_slave_link_status_change_behaviour), 5145 TEST_CASE(test_tlb_tx_burst), 5146 TEST_CASE(test_tlb_rx_burst), 5147 TEST_CASE(test_tlb_verify_mac_assignment), 5148 TEST_CASE(test_tlb_verify_promiscuous_enable_disable), 5149 TEST_CASE(test_tlb_verify_slave_link_status_change_failover), 5150 TEST_CASE(test_alb_change_mac_in_reply_sent), 5151 TEST_CASE(test_alb_reply_from_client), 5152 TEST_CASE(test_alb_receive_vlan_reply), 5153 TEST_CASE(test_alb_ipv4_tx), 5154 TEST_CASE(test_broadcast_tx_burst), 5155 TEST_CASE(test_broadcast_tx_burst_slave_tx_fail), 5156 TEST_CASE(test_broadcast_rx_burst), 5157 TEST_CASE(test_broadcast_verify_promiscuous_enable_disable), 5158 TEST_CASE(test_broadcast_verify_mac_assignment), 5159 TEST_CASE(test_broadcast_verify_slave_link_status_change_behaviour), 5160 TEST_CASE(test_reconfigure_bonded_device), 5161 TEST_CASE(test_close_bonded_device), 5162 5163 TEST_CASES_END() /**< NULL terminate unit test array */ 5164 } 5165 }; 5166 5167 5168 static int 5169 test_link_bonding(void) 5170 { 5171 return unit_test_suite_runner(&link_bonding_test_suite); 5172 } 5173 5174 REGISTER_TEST_COMMAND(link_bonding_autotest, test_link_bonding); 5175