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