1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2016 Intel Corporation. 3 */ 4 5 #include <rte_eth_bond.h> 6 #include <rte_eth_bond_8023ad.h> 7 8 #include <cmdline_parse.h> 9 #include <cmdline_parse_etheraddr.h> 10 #include <cmdline_parse_num.h> 11 #include <cmdline_parse_string.h> 12 13 #include "testpmd.h" 14 15 /* *** SET BONDING MODE *** */ 16 struct cmd_set_bonding_mode_result { 17 cmdline_fixed_string_t set; 18 cmdline_fixed_string_t bonding; 19 cmdline_fixed_string_t mode; 20 uint8_t value; 21 portid_t port_id; 22 }; 23 24 static void cmd_set_bonding_mode_parsed(void *parsed_result, 25 __rte_unused struct cmdline *cl, __rte_unused void *data) 26 { 27 struct cmd_set_bonding_mode_result *res = parsed_result; 28 portid_t port_id = res->port_id; 29 struct rte_port *port = &ports[port_id]; 30 31 /* 32 * Bonding mode changed means resources of device changed, like whether 33 * started rte timer or not. Device should be restarted when resources 34 * of device changed. 35 */ 36 if (port->port_status != RTE_PORT_STOPPED) { 37 fprintf(stderr, 38 "\t Error: Can't set bonding mode when port %d is not stopped\n", 39 port_id); 40 return; 41 } 42 43 /* Set the bonding mode for the relevant port. */ 44 if (rte_eth_bond_mode_set(port_id, res->value) != 0) 45 fprintf(stderr, "\t Failed to set bonding mode for port = %d.\n", 46 port_id); 47 } 48 49 static cmdline_parse_token_string_t cmd_setbonding_mode_set = 50 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result, 51 set, "set"); 52 static cmdline_parse_token_string_t cmd_setbonding_mode_bonding = 53 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result, 54 bonding, "bonding"); 55 static cmdline_parse_token_string_t cmd_setbonding_mode_mode = 56 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result, 57 mode, "mode"); 58 static cmdline_parse_token_num_t cmd_setbonding_mode_value = 59 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result, 60 value, RTE_UINT8); 61 static cmdline_parse_token_num_t cmd_setbonding_mode_port = 62 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result, 63 port_id, RTE_UINT16); 64 65 static cmdline_parse_inst_t cmd_set_bonding_mode = { 66 .f = cmd_set_bonding_mode_parsed, 67 .help_str = "set bonding mode <mode_value> <port_id>: " 68 "Set the bonding mode for port_id", 69 .data = NULL, 70 .tokens = { 71 (void *)&cmd_setbonding_mode_set, 72 (void *)&cmd_setbonding_mode_bonding, 73 (void *)&cmd_setbonding_mode_mode, 74 (void *)&cmd_setbonding_mode_value, 75 (void *)&cmd_setbonding_mode_port, 76 NULL 77 } 78 }; 79 80 /* *** SET BONDING SLOW_QUEUE SW/HW *** */ 81 struct cmd_set_bonding_lacp_dedicated_queues_result { 82 cmdline_fixed_string_t set; 83 cmdline_fixed_string_t bonding; 84 cmdline_fixed_string_t lacp; 85 cmdline_fixed_string_t dedicated_queues; 86 portid_t port_id; 87 cmdline_fixed_string_t mode; 88 }; 89 90 static void cmd_set_bonding_lacp_dedicated_queues_parsed(void *parsed_result, 91 __rte_unused struct cmdline *cl, __rte_unused void *data) 92 { 93 struct cmd_set_bonding_lacp_dedicated_queues_result *res = parsed_result; 94 portid_t port_id = res->port_id; 95 struct rte_port *port; 96 97 port = &ports[port_id]; 98 99 /** Check if the port is not started **/ 100 if (port->port_status != RTE_PORT_STOPPED) { 101 fprintf(stderr, "Please stop port %d first\n", port_id); 102 return; 103 } 104 105 if (!strcmp(res->mode, "enable")) { 106 if (rte_eth_bond_8023ad_dedicated_queues_enable(port_id) == 0) 107 printf("Dedicate queues for LACP control packets" 108 " enabled\n"); 109 else 110 printf("Enabling dedicate queues for LACP control " 111 "packets on port %d failed\n", port_id); 112 } else if (!strcmp(res->mode, "disable")) { 113 if (rte_eth_bond_8023ad_dedicated_queues_disable(port_id) == 0) 114 printf("Dedicated queues for LACP control packets " 115 "disabled\n"); 116 else 117 printf("Disabling dedicated queues for LACP control " 118 "traffic on port %d failed\n", port_id); 119 } 120 } 121 122 static cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_set = 123 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, 124 set, "set"); 125 static cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_bonding = 126 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, 127 bonding, "bonding"); 128 static cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_lacp = 129 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, 130 lacp, "lacp"); 131 static cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_dedicated_queues = 132 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, 133 dedicated_queues, "dedicated_queues"); 134 static cmdline_parse_token_num_t cmd_setbonding_lacp_dedicated_queues_port_id = 135 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, 136 port_id, RTE_UINT16); 137 static cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_mode = 138 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, 139 mode, "enable#disable"); 140 141 static cmdline_parse_inst_t cmd_set_lacp_dedicated_queues = { 142 .f = cmd_set_bonding_lacp_dedicated_queues_parsed, 143 .help_str = "set bonding lacp dedicated_queues <port_id> " 144 "enable|disable: " 145 "Enable/disable dedicated queues for LACP control traffic for port_id", 146 .data = NULL, 147 .tokens = { 148 (void *)&cmd_setbonding_lacp_dedicated_queues_set, 149 (void *)&cmd_setbonding_lacp_dedicated_queues_bonding, 150 (void *)&cmd_setbonding_lacp_dedicated_queues_lacp, 151 (void *)&cmd_setbonding_lacp_dedicated_queues_dedicated_queues, 152 (void *)&cmd_setbonding_lacp_dedicated_queues_port_id, 153 (void *)&cmd_setbonding_lacp_dedicated_queues_mode, 154 NULL 155 } 156 }; 157 158 /* *** SET BALANCE XMIT POLICY *** */ 159 struct cmd_set_bonding_balance_xmit_policy_result { 160 cmdline_fixed_string_t set; 161 cmdline_fixed_string_t bonding; 162 cmdline_fixed_string_t balance_xmit_policy; 163 portid_t port_id; 164 cmdline_fixed_string_t policy; 165 }; 166 167 static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result, 168 __rte_unused struct cmdline *cl, __rte_unused void *data) 169 { 170 struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result; 171 portid_t port_id = res->port_id; 172 uint8_t policy; 173 174 if (!strcmp(res->policy, "l2")) { 175 policy = BALANCE_XMIT_POLICY_LAYER2; 176 } else if (!strcmp(res->policy, "l23")) { 177 policy = BALANCE_XMIT_POLICY_LAYER23; 178 } else if (!strcmp(res->policy, "l34")) { 179 policy = BALANCE_XMIT_POLICY_LAYER34; 180 } else { 181 fprintf(stderr, "\t Invalid xmit policy selection"); 182 return; 183 } 184 185 /* Set the bonding mode for the relevant port. */ 186 if (rte_eth_bond_xmit_policy_set(port_id, policy) != 0) { 187 fprintf(stderr, 188 "\t Failed to set bonding balance xmit policy for port = %d.\n", 189 port_id); 190 } 191 } 192 193 static cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set = 194 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result, 195 set, "set"); 196 static cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding = 197 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result, 198 bonding, "bonding"); 199 static cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy = 200 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result, 201 balance_xmit_policy, "balance_xmit_policy"); 202 static cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port = 203 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result, 204 port_id, RTE_UINT16); 205 static cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy = 206 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result, 207 policy, "l2#l23#l34"); 208 209 static cmdline_parse_inst_t cmd_set_balance_xmit_policy = { 210 .f = cmd_set_bonding_balance_xmit_policy_parsed, 211 .help_str = "set bonding balance_xmit_policy <port_id> " 212 "l2|l23|l34: " 213 "Set the bonding balance_xmit_policy for port_id", 214 .data = NULL, 215 .tokens = { 216 (void *)&cmd_setbonding_balance_xmit_policy_set, 217 (void *)&cmd_setbonding_balance_xmit_policy_bonding, 218 (void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy, 219 (void *)&cmd_setbonding_balance_xmit_policy_port, 220 (void *)&cmd_setbonding_balance_xmit_policy_policy, 221 NULL 222 } 223 }; 224 225 /* *** SHOW IEEE802.3 BONDING INFORMATION *** */ 226 struct cmd_show_bonding_lacp_info_result { 227 cmdline_fixed_string_t show; 228 cmdline_fixed_string_t bonding; 229 cmdline_fixed_string_t lacp; 230 cmdline_fixed_string_t info; 231 portid_t port_id; 232 }; 233 234 static void port_param_show(struct port_params *params) 235 { 236 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 237 238 printf("\t\tsystem priority: %u\n", params->system_priority); 239 rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, ¶ms->system); 240 printf("\t\tsystem mac address: %s\n", buf); 241 printf("\t\tport key: %u\n", params->key); 242 printf("\t\tport priority: %u\n", params->port_priority); 243 printf("\t\tport number: %u\n", params->port_number); 244 } 245 246 static void lacp_slave_info_show(struct rte_eth_bond_8023ad_slave_info *info) 247 { 248 char a_state[256] = { 0 }; 249 char p_state[256] = { 0 }; 250 int a_len = 0; 251 int p_len = 0; 252 uint32_t i; 253 254 static const char * const state[] = { 255 "ACTIVE", 256 "TIMEOUT", 257 "AGGREGATION", 258 "SYNCHRONIZATION", 259 "COLLECTING", 260 "DISTRIBUTING", 261 "DEFAULTED", 262 "EXPIRED" 263 }; 264 static const char * const selection[] = { 265 "UNSELECTED", 266 "STANDBY", 267 "SELECTED" 268 }; 269 270 for (i = 0; i < RTE_DIM(state); i++) { 271 if ((info->actor_state >> i) & 1) 272 a_len += snprintf(&a_state[a_len], 273 RTE_DIM(a_state) - a_len, "%s ", 274 state[i]); 275 276 if ((info->partner_state >> i) & 1) 277 p_len += snprintf(&p_state[p_len], 278 RTE_DIM(p_state) - p_len, "%s ", 279 state[i]); 280 } 281 printf("\tAggregator port id: %u\n", info->agg_port_id); 282 printf("\tselection: %s\n", selection[info->selected]); 283 printf("\tActor detail info:\n"); 284 port_param_show(&info->actor); 285 printf("\t\tport state: %s\n", a_state); 286 printf("\tPartner detail info:\n"); 287 port_param_show(&info->partner); 288 printf("\t\tport state: %s\n", p_state); 289 printf("\n"); 290 } 291 292 static void lacp_conf_show(struct rte_eth_bond_8023ad_conf *conf) 293 { 294 printf("\tfast period: %u ms\n", conf->fast_periodic_ms); 295 printf("\tslow period: %u ms\n", conf->slow_periodic_ms); 296 printf("\tshort timeout: %u ms\n", conf->short_timeout_ms); 297 printf("\tlong timeout: %u ms\n", conf->long_timeout_ms); 298 printf("\taggregate wait timeout: %u ms\n", 299 conf->aggregate_wait_timeout_ms); 300 printf("\ttx period: %u ms\n", conf->tx_period_ms); 301 printf("\trx marker period: %u ms\n", conf->rx_marker_period_ms); 302 printf("\tupdate timeout: %u ms\n", conf->update_timeout_ms); 303 switch (conf->agg_selection) { 304 case AGG_BANDWIDTH: 305 printf("\taggregation mode: bandwidth\n"); 306 break; 307 case AGG_STABLE: 308 printf("\taggregation mode: stable\n"); 309 break; 310 case AGG_COUNT: 311 printf("\taggregation mode: count\n"); 312 break; 313 default: 314 printf("\taggregation mode: invalid\n"); 315 break; 316 } 317 318 printf("\n"); 319 } 320 321 static void cmd_show_bonding_lacp_info_parsed(void *parsed_result, 322 __rte_unused struct cmdline *cl, __rte_unused void *data) 323 { 324 struct cmd_show_bonding_lacp_info_result *res = parsed_result; 325 struct rte_eth_bond_8023ad_slave_info slave_info; 326 struct rte_eth_bond_8023ad_conf port_conf; 327 portid_t slaves[RTE_MAX_ETHPORTS]; 328 portid_t port_id = res->port_id; 329 int num_active_slaves; 330 int bonding_mode; 331 int i; 332 int ret; 333 334 bonding_mode = rte_eth_bond_mode_get(port_id); 335 if (bonding_mode != BONDING_MODE_8023AD) { 336 fprintf(stderr, "\tBonding mode is not mode 4\n"); 337 return; 338 } 339 340 num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves, 341 RTE_MAX_ETHPORTS); 342 if (num_active_slaves < 0) { 343 fprintf(stderr, "\tFailed to get active slave list for port = %u\n", 344 port_id); 345 return; 346 } 347 if (num_active_slaves == 0) 348 fprintf(stderr, "\tIEEE802.3 port %u has no active slave\n", 349 port_id); 350 351 printf("\tIEEE802.3 port: %u\n", port_id); 352 ret = rte_eth_bond_8023ad_conf_get(port_id, &port_conf); 353 if (ret) { 354 fprintf(stderr, "\tGet bonded device %u info failed\n", 355 port_id); 356 return; 357 } 358 lacp_conf_show(&port_conf); 359 360 for (i = 0; i < num_active_slaves; i++) { 361 ret = rte_eth_bond_8023ad_slave_info(port_id, slaves[i], 362 &slave_info); 363 if (ret) { 364 fprintf(stderr, "\tGet slave device %u info failed\n", 365 slaves[i]); 366 return; 367 } 368 printf("\tSlave Port: %u\n", slaves[i]); 369 lacp_slave_info_show(&slave_info); 370 } 371 } 372 373 static cmdline_parse_token_string_t cmd_show_bonding_lacp_info_show = 374 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result, 375 show, "show"); 376 static cmdline_parse_token_string_t cmd_show_bonding_lacp_info_bonding = 377 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result, 378 bonding, "bonding"); 379 static cmdline_parse_token_string_t cmd_show_bonding_lacp_info_lacp = 380 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result, 381 bonding, "lacp"); 382 static cmdline_parse_token_string_t cmd_show_bonding_lacp_info_info = 383 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_lacp_info_result, 384 info, "info"); 385 static cmdline_parse_token_num_t cmd_show_bonding_lacp_info_port_id = 386 TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_lacp_info_result, 387 port_id, RTE_UINT16); 388 389 static cmdline_parse_inst_t cmd_show_bonding_lacp_info = { 390 .f = cmd_show_bonding_lacp_info_parsed, 391 .help_str = "show bonding lacp info <port_id> : " 392 "Show bonding IEEE802.3 information for port_id", 393 .data = NULL, 394 .tokens = { 395 (void *)&cmd_show_bonding_lacp_info_show, 396 (void *)&cmd_show_bonding_lacp_info_bonding, 397 (void *)&cmd_show_bonding_lacp_info_lacp, 398 (void *)&cmd_show_bonding_lacp_info_info, 399 (void *)&cmd_show_bonding_lacp_info_port_id, 400 NULL 401 } 402 }; 403 404 /* *** SHOW NIC BONDING CONFIGURATION *** */ 405 struct cmd_show_bonding_config_result { 406 cmdline_fixed_string_t show; 407 cmdline_fixed_string_t bonding; 408 cmdline_fixed_string_t config; 409 portid_t port_id; 410 }; 411 412 static void cmd_show_bonding_config_parsed(void *parsed_result, 413 __rte_unused struct cmdline *cl, __rte_unused void *data) 414 { 415 struct cmd_show_bonding_config_result *res = parsed_result; 416 int bonding_mode, agg_mode; 417 portid_t slaves[RTE_MAX_ETHPORTS]; 418 int num_slaves, num_active_slaves; 419 int primary_id; 420 int i; 421 portid_t port_id = res->port_id; 422 423 /* Display the bonding mode.*/ 424 bonding_mode = rte_eth_bond_mode_get(port_id); 425 if (bonding_mode < 0) { 426 fprintf(stderr, "\tFailed to get bonding mode for port = %d\n", 427 port_id); 428 return; 429 } 430 printf("\tBonding mode: %d\n", bonding_mode); 431 432 if (bonding_mode == BONDING_MODE_BALANCE || 433 bonding_mode == BONDING_MODE_8023AD) { 434 int balance_xmit_policy; 435 436 balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id); 437 if (balance_xmit_policy < 0) { 438 fprintf(stderr, 439 "\tFailed to get balance xmit policy for port = %d\n", 440 port_id); 441 return; 442 } 443 printf("\tBalance Xmit Policy: "); 444 445 switch (balance_xmit_policy) { 446 case BALANCE_XMIT_POLICY_LAYER2: 447 printf("BALANCE_XMIT_POLICY_LAYER2"); 448 break; 449 case BALANCE_XMIT_POLICY_LAYER23: 450 printf("BALANCE_XMIT_POLICY_LAYER23"); 451 break; 452 case BALANCE_XMIT_POLICY_LAYER34: 453 printf("BALANCE_XMIT_POLICY_LAYER34"); 454 break; 455 } 456 printf("\n"); 457 } 458 459 if (bonding_mode == BONDING_MODE_8023AD) { 460 agg_mode = rte_eth_bond_8023ad_agg_selection_get(port_id); 461 printf("\tIEEE802.3AD Aggregator Mode: "); 462 switch (agg_mode) { 463 case AGG_BANDWIDTH: 464 printf("bandwidth"); 465 break; 466 case AGG_STABLE: 467 printf("stable"); 468 break; 469 case AGG_COUNT: 470 printf("count"); 471 break; 472 } 473 printf("\n"); 474 } 475 476 num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS); 477 478 if (num_slaves < 0) { 479 fprintf(stderr, "\tFailed to get slave list for port = %d\n", 480 port_id); 481 return; 482 } 483 if (num_slaves > 0) { 484 printf("\tSlaves (%d): [", num_slaves); 485 for (i = 0; i < num_slaves - 1; i++) 486 printf("%d ", slaves[i]); 487 488 printf("%d]\n", slaves[num_slaves - 1]); 489 } else { 490 printf("\tSlaves: []\n"); 491 } 492 493 num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves, 494 RTE_MAX_ETHPORTS); 495 496 if (num_active_slaves < 0) { 497 fprintf(stderr, 498 "\tFailed to get active slave list for port = %d\n", 499 port_id); 500 return; 501 } 502 if (num_active_slaves > 0) { 503 printf("\tActive Slaves (%d): [", num_active_slaves); 504 for (i = 0; i < num_active_slaves - 1; i++) 505 printf("%d ", slaves[i]); 506 507 printf("%d]\n", slaves[num_active_slaves - 1]); 508 509 } else { 510 printf("\tActive Slaves: []\n"); 511 } 512 513 primary_id = rte_eth_bond_primary_get(port_id); 514 if (primary_id < 0) { 515 fprintf(stderr, "\tFailed to get primary slave for port = %d\n", 516 port_id); 517 return; 518 } 519 printf("\tPrimary: [%d]\n", primary_id); 520 } 521 522 static cmdline_parse_token_string_t cmd_showbonding_config_show = 523 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result, 524 show, "show"); 525 static cmdline_parse_token_string_t cmd_showbonding_config_bonding = 526 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result, 527 bonding, "bonding"); 528 static cmdline_parse_token_string_t cmd_showbonding_config_config = 529 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result, 530 config, "config"); 531 static cmdline_parse_token_num_t cmd_showbonding_config_port = 532 TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result, 533 port_id, RTE_UINT16); 534 535 static cmdline_parse_inst_t cmd_show_bonding_config = { 536 .f = cmd_show_bonding_config_parsed, 537 .help_str = "show bonding config <port_id>: " 538 "Show the bonding config for port_id", 539 .data = NULL, 540 .tokens = { 541 (void *)&cmd_showbonding_config_show, 542 (void *)&cmd_showbonding_config_bonding, 543 (void *)&cmd_showbonding_config_config, 544 (void *)&cmd_showbonding_config_port, 545 NULL 546 } 547 }; 548 549 /* *** SET BONDING PRIMARY *** */ 550 struct cmd_set_bonding_primary_result { 551 cmdline_fixed_string_t set; 552 cmdline_fixed_string_t bonding; 553 cmdline_fixed_string_t primary; 554 portid_t slave_id; 555 portid_t port_id; 556 }; 557 558 static void cmd_set_bonding_primary_parsed(void *parsed_result, 559 __rte_unused struct cmdline *cl, __rte_unused void *data) 560 { 561 struct cmd_set_bonding_primary_result *res = parsed_result; 562 portid_t master_port_id = res->port_id; 563 portid_t slave_port_id = res->slave_id; 564 565 /* Set the primary slave for a bonded device. */ 566 if (rte_eth_bond_primary_set(master_port_id, slave_port_id) != 0) { 567 fprintf(stderr, "\t Failed to set primary slave for port = %d.\n", 568 master_port_id); 569 return; 570 } 571 init_port_config(); 572 } 573 574 static cmdline_parse_token_string_t cmd_setbonding_primary_set = 575 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result, 576 set, "set"); 577 static cmdline_parse_token_string_t cmd_setbonding_primary_bonding = 578 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result, 579 bonding, "bonding"); 580 static cmdline_parse_token_string_t cmd_setbonding_primary_primary = 581 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result, 582 primary, "primary"); 583 static cmdline_parse_token_num_t cmd_setbonding_primary_slave = 584 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result, 585 slave_id, RTE_UINT16); 586 static cmdline_parse_token_num_t cmd_setbonding_primary_port = 587 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result, 588 port_id, RTE_UINT16); 589 590 static cmdline_parse_inst_t cmd_set_bonding_primary = { 591 .f = cmd_set_bonding_primary_parsed, 592 .help_str = "set bonding primary <slave_id> <port_id>: " 593 "Set the primary slave for port_id", 594 .data = NULL, 595 .tokens = { 596 (void *)&cmd_setbonding_primary_set, 597 (void *)&cmd_setbonding_primary_bonding, 598 (void *)&cmd_setbonding_primary_primary, 599 (void *)&cmd_setbonding_primary_slave, 600 (void *)&cmd_setbonding_primary_port, 601 NULL 602 } 603 }; 604 605 /* *** ADD SLAVE *** */ 606 struct cmd_add_bonding_slave_result { 607 cmdline_fixed_string_t add; 608 cmdline_fixed_string_t bonding; 609 cmdline_fixed_string_t slave; 610 portid_t slave_id; 611 portid_t port_id; 612 }; 613 614 static void cmd_add_bonding_slave_parsed(void *parsed_result, 615 __rte_unused struct cmdline *cl, __rte_unused void *data) 616 { 617 struct cmd_add_bonding_slave_result *res = parsed_result; 618 portid_t master_port_id = res->port_id; 619 portid_t slave_port_id = res->slave_id; 620 621 /* add the slave for a bonded device. */ 622 if (rte_eth_bond_slave_add(master_port_id, slave_port_id) != 0) { 623 fprintf(stderr, 624 "\t Failed to add slave %d to master port = %d.\n", 625 slave_port_id, master_port_id); 626 return; 627 } 628 init_port_config(); 629 set_port_slave_flag(slave_port_id); 630 } 631 632 static cmdline_parse_token_string_t cmd_addbonding_slave_add = 633 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result, 634 add, "add"); 635 static cmdline_parse_token_string_t cmd_addbonding_slave_bonding = 636 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result, 637 bonding, "bonding"); 638 static cmdline_parse_token_string_t cmd_addbonding_slave_slave = 639 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result, 640 slave, "slave"); 641 static cmdline_parse_token_num_t cmd_addbonding_slave_slaveid = 642 TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result, 643 slave_id, RTE_UINT16); 644 static cmdline_parse_token_num_t cmd_addbonding_slave_port = 645 TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result, 646 port_id, RTE_UINT16); 647 648 static cmdline_parse_inst_t cmd_add_bonding_slave = { 649 .f = cmd_add_bonding_slave_parsed, 650 .help_str = "add bonding slave <slave_id> <port_id>: " 651 "Add a slave device to a bonded device", 652 .data = NULL, 653 .tokens = { 654 (void *)&cmd_addbonding_slave_add, 655 (void *)&cmd_addbonding_slave_bonding, 656 (void *)&cmd_addbonding_slave_slave, 657 (void *)&cmd_addbonding_slave_slaveid, 658 (void *)&cmd_addbonding_slave_port, 659 NULL 660 } 661 }; 662 663 /* *** REMOVE SLAVE *** */ 664 struct cmd_remove_bonding_slave_result { 665 cmdline_fixed_string_t remove; 666 cmdline_fixed_string_t bonding; 667 cmdline_fixed_string_t slave; 668 portid_t slave_id; 669 portid_t port_id; 670 }; 671 672 static void cmd_remove_bonding_slave_parsed(void *parsed_result, 673 __rte_unused struct cmdline *cl, __rte_unused void *data) 674 { 675 struct cmd_remove_bonding_slave_result *res = parsed_result; 676 portid_t master_port_id = res->port_id; 677 portid_t slave_port_id = res->slave_id; 678 679 /* remove the slave from a bonded device. */ 680 if (rte_eth_bond_slave_remove(master_port_id, slave_port_id) != 0) { 681 fprintf(stderr, 682 "\t Failed to remove slave %d from master port = %d.\n", 683 slave_port_id, master_port_id); 684 return; 685 } 686 init_port_config(); 687 clear_port_slave_flag(slave_port_id); 688 } 689 690 static cmdline_parse_token_string_t cmd_removebonding_slave_remove = 691 TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result, 692 remove, "remove"); 693 static cmdline_parse_token_string_t cmd_removebonding_slave_bonding = 694 TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result, 695 bonding, "bonding"); 696 static cmdline_parse_token_string_t cmd_removebonding_slave_slave = 697 TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result, 698 slave, "slave"); 699 static cmdline_parse_token_num_t cmd_removebonding_slave_slaveid = 700 TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result, 701 slave_id, RTE_UINT16); 702 static cmdline_parse_token_num_t cmd_removebonding_slave_port = 703 TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result, 704 port_id, RTE_UINT16); 705 706 static cmdline_parse_inst_t cmd_remove_bonding_slave = { 707 .f = cmd_remove_bonding_slave_parsed, 708 .help_str = "remove bonding slave <slave_id> <port_id>: " 709 "Remove a slave device from a bonded device", 710 .data = NULL, 711 .tokens = { 712 (void *)&cmd_removebonding_slave_remove, 713 (void *)&cmd_removebonding_slave_bonding, 714 (void *)&cmd_removebonding_slave_slave, 715 (void *)&cmd_removebonding_slave_slaveid, 716 (void *)&cmd_removebonding_slave_port, 717 NULL 718 } 719 }; 720 721 /* *** CREATE BONDED DEVICE *** */ 722 struct cmd_create_bonded_device_result { 723 cmdline_fixed_string_t create; 724 cmdline_fixed_string_t bonded; 725 cmdline_fixed_string_t device; 726 uint8_t mode; 727 uint8_t socket; 728 }; 729 730 static int bond_dev_num; 731 732 static void cmd_create_bonded_device_parsed(void *parsed_result, 733 __rte_unused struct cmdline *cl, __rte_unused void *data) 734 { 735 struct cmd_create_bonded_device_result *res = parsed_result; 736 char ethdev_name[RTE_ETH_NAME_MAX_LEN]; 737 int port_id; 738 int ret; 739 740 if (test_done == 0) { 741 fprintf(stderr, "Please stop forwarding first\n"); 742 return; 743 } 744 745 snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d", 746 bond_dev_num++); 747 748 /* Create a new bonded device. */ 749 port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket); 750 if (port_id < 0) { 751 fprintf(stderr, "\t Failed to create bonded device.\n"); 752 return; 753 } 754 printf("Created new bonded device %s on (port %d).\n", ethdev_name, 755 port_id); 756 757 /* Update number of ports */ 758 nb_ports = rte_eth_dev_count_avail(); 759 reconfig(port_id, res->socket); 760 ret = rte_eth_promiscuous_enable(port_id); 761 if (ret != 0) 762 fprintf(stderr, "Failed to enable promiscuous mode for port %u: %s - ignore\n", 763 port_id, rte_strerror(-ret)); 764 765 ports[port_id].bond_flag = 1; 766 ports[port_id].need_setup = 0; 767 ports[port_id].port_status = RTE_PORT_STOPPED; 768 } 769 770 static cmdline_parse_token_string_t cmd_createbonded_device_create = 771 TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result, 772 create, "create"); 773 static cmdline_parse_token_string_t cmd_createbonded_device_bonded = 774 TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result, 775 bonded, "bonded"); 776 static cmdline_parse_token_string_t cmd_createbonded_device_device = 777 TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result, 778 device, "device"); 779 static cmdline_parse_token_num_t cmd_createbonded_device_mode = 780 TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result, 781 mode, RTE_UINT8); 782 static cmdline_parse_token_num_t cmd_createbonded_device_socket = 783 TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result, 784 socket, RTE_UINT8); 785 786 static cmdline_parse_inst_t cmd_create_bonded_device = { 787 .f = cmd_create_bonded_device_parsed, 788 .help_str = "create bonded device <mode> <socket>: " 789 "Create a new bonded device with specific bonding mode and socket", 790 .data = NULL, 791 .tokens = { 792 (void *)&cmd_createbonded_device_create, 793 (void *)&cmd_createbonded_device_bonded, 794 (void *)&cmd_createbonded_device_device, 795 (void *)&cmd_createbonded_device_mode, 796 (void *)&cmd_createbonded_device_socket, 797 NULL 798 } 799 }; 800 801 /* *** SET MAC ADDRESS IN BONDED DEVICE *** */ 802 struct cmd_set_bond_mac_addr_result { 803 cmdline_fixed_string_t set; 804 cmdline_fixed_string_t bonding; 805 cmdline_fixed_string_t mac_addr; 806 uint16_t port_num; 807 struct rte_ether_addr address; 808 }; 809 810 static void cmd_set_bond_mac_addr_parsed(void *parsed_result, 811 __rte_unused struct cmdline *cl, __rte_unused void *data) 812 { 813 struct cmd_set_bond_mac_addr_result *res = parsed_result; 814 int ret; 815 816 if (port_id_is_invalid(res->port_num, ENABLED_WARN)) 817 return; 818 819 ret = rte_eth_bond_mac_address_set(res->port_num, &res->address); 820 821 /* check the return value and print it if is < 0 */ 822 if (ret < 0) 823 fprintf(stderr, "set_bond_mac_addr error: (%s)\n", 824 strerror(-ret)); 825 } 826 827 static cmdline_parse_token_string_t cmd_set_bond_mac_addr_set = 828 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, 829 set, "set"); 830 static cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding = 831 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, 832 bonding, "bonding"); 833 static cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac = 834 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, 835 mac_addr, "mac_addr"); 836 static cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum = 837 TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, 838 port_num, RTE_UINT16); 839 static cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr = 840 TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, 841 address); 842 843 static cmdline_parse_inst_t cmd_set_bond_mac_addr = { 844 .f = cmd_set_bond_mac_addr_parsed, 845 .data = NULL, 846 .help_str = "set bonding mac_addr <port_id> <mac_addr>", 847 .tokens = { 848 (void *)&cmd_set_bond_mac_addr_set, 849 (void *)&cmd_set_bond_mac_addr_bonding, 850 (void *)&cmd_set_bond_mac_addr_mac, 851 (void *)&cmd_set_bond_mac_addr_portnum, 852 (void *)&cmd_set_bond_mac_addr_addr, 853 NULL 854 } 855 }; 856 857 /* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */ 858 struct cmd_set_bond_mon_period_result { 859 cmdline_fixed_string_t set; 860 cmdline_fixed_string_t bonding; 861 cmdline_fixed_string_t mon_period; 862 uint16_t port_num; 863 uint32_t period_ms; 864 }; 865 866 static void cmd_set_bond_mon_period_parsed(void *parsed_result, 867 __rte_unused struct cmdline *cl, __rte_unused void *data) 868 { 869 struct cmd_set_bond_mon_period_result *res = parsed_result; 870 int ret; 871 872 ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms); 873 874 /* check the return value and print it if is < 0 */ 875 if (ret < 0) 876 fprintf(stderr, "set_bond_mac_addr error: (%s)\n", 877 strerror(-ret)); 878 } 879 880 static cmdline_parse_token_string_t cmd_set_bond_mon_period_set = 881 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result, 882 set, "set"); 883 static cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding = 884 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result, 885 bonding, "bonding"); 886 static cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period = 887 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result, 888 mon_period, "mon_period"); 889 static cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum = 890 TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result, 891 port_num, RTE_UINT16); 892 static cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms = 893 TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result, 894 period_ms, RTE_UINT32); 895 896 static cmdline_parse_inst_t cmd_set_bond_mon_period = { 897 .f = cmd_set_bond_mon_period_parsed, 898 .data = NULL, 899 .help_str = "set bonding mon_period <port_id> <period_ms>", 900 .tokens = { 901 (void *)&cmd_set_bond_mon_period_set, 902 (void *)&cmd_set_bond_mon_period_bonding, 903 (void *)&cmd_set_bond_mon_period_mon_period, 904 (void *)&cmd_set_bond_mon_period_portnum, 905 (void *)&cmd_set_bond_mon_period_period_ms, 906 NULL 907 } 908 }; 909 910 struct cmd_set_bonding_agg_mode_policy_result { 911 cmdline_fixed_string_t set; 912 cmdline_fixed_string_t bonding; 913 cmdline_fixed_string_t agg_mode; 914 uint16_t port_num; 915 cmdline_fixed_string_t policy; 916 }; 917 918 static void 919 cmd_set_bonding_agg_mode(void *parsed_result, 920 __rte_unused struct cmdline *cl, __rte_unused void *data) 921 { 922 struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result; 923 uint8_t policy = AGG_BANDWIDTH; 924 925 if (!strcmp(res->policy, "bandwidth")) 926 policy = AGG_BANDWIDTH; 927 else if (!strcmp(res->policy, "stable")) 928 policy = AGG_STABLE; 929 else if (!strcmp(res->policy, "count")) 930 policy = AGG_COUNT; 931 932 rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy); 933 } 934 935 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set = 936 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, 937 set, "set"); 938 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding = 939 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, 940 bonding, "bonding"); 941 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode = 942 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, 943 agg_mode, "agg_mode"); 944 static cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum = 945 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, 946 port_num, RTE_UINT16); 947 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string = 948 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result, 949 policy, "stable#bandwidth#count"); 950 951 static cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = { 952 .f = cmd_set_bonding_agg_mode, 953 .data = NULL, 954 .help_str = "set bonding mode IEEE802.3AD aggregator policy <port_id> <agg_name>", 955 .tokens = { 956 (void *)&cmd_set_bonding_agg_mode_set, 957 (void *)&cmd_set_bonding_agg_mode_bonding, 958 (void *)&cmd_set_bonding_agg_mode_agg_mode, 959 (void *)&cmd_set_bonding_agg_mode_portnum, 960 (void *)&cmd_set_bonding_agg_mode_policy_string, 961 NULL 962 } 963 }; 964 965 static struct testpmd_driver_commands bonding_cmds = { 966 .commands = { 967 { 968 &cmd_set_bonding_mode, 969 "set bonding mode (value) (port_id)\n" 970 " Set the bonding mode on a bonded device.\n", 971 }, 972 { 973 &cmd_show_bonding_config, 974 "show bonding config (port_id)\n" 975 " Show the bonding config for port_id.\n", 976 }, 977 { 978 &cmd_show_bonding_lacp_info, 979 "show bonding lacp info (port_id)\n" 980 " Show the bonding lacp information for port_id.\n", 981 }, 982 { 983 &cmd_set_bonding_primary, 984 "set bonding primary (slave_id) (port_id)\n" 985 " Set the primary slave for a bonded device.\n", 986 }, 987 { 988 &cmd_add_bonding_slave, 989 "add bonding slave (slave_id) (port_id)\n" 990 " Add a slave device to a bonded device.\n", 991 }, 992 { 993 &cmd_remove_bonding_slave, 994 "remove bonding slave (slave_id) (port_id)\n" 995 " Remove a slave device from a bonded device.\n", 996 }, 997 { 998 &cmd_create_bonded_device, 999 "create bonded device (mode) (socket)\n" 1000 " Create a new bonded device with specific bonding mode and socket.\n", 1001 }, 1002 { 1003 &cmd_set_bond_mac_addr, 1004 "set bonding mac_addr (port_id) (address)\n" 1005 " Set the MAC address of a bonded device.\n", 1006 }, 1007 { 1008 &cmd_set_balance_xmit_policy, 1009 "set bonding balance_xmit_policy (port_id) (l2|l23|l34)\n" 1010 " Set the transmit balance policy for bonded device running in balance mode.\n", 1011 }, 1012 { 1013 &cmd_set_bond_mon_period, 1014 "set bonding mon_period (port_id) (value)\n" 1015 " Set the bonding link status monitoring polling period in ms.\n", 1016 }, 1017 { 1018 &cmd_set_lacp_dedicated_queues, 1019 "set bonding lacp dedicated_queues <port_id> (enable|disable)\n" 1020 " Enable/disable dedicated queues for LACP control traffic.\n", 1021 }, 1022 { 1023 &cmd_set_bonding_agg_mode_policy, 1024 "set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)\n" 1025 " Set Aggregation mode for IEEE802.3AD (mode 4)\n", 1026 }, 1027 { NULL, NULL }, 1028 }, 1029 }; 1030 TESTPMD_ADD_DRIVER_COMMANDS(bonding_cmds) 1031