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