xref: /dpdk/drivers/net/bonding/bonding_testpmd.c (revision 72206323a5dd3182b13f61b25a64abdddfee595c)
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, &params->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