xref: /dpdk/drivers/net/bonding/bonding_testpmd.c (revision fb360c75062d71014c1bba90db64f493fb0ae9e2)
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 	ports[master_port_id].update_conf = 1;
629 	init_port_config();
630 	set_port_slave_flag(slave_port_id);
631 }
632 
633 static cmdline_parse_token_string_t cmd_addbonding_slave_add =
634 	TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
635 		add, "add");
636 static cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
637 	TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
638 		bonding, "bonding");
639 static cmdline_parse_token_string_t cmd_addbonding_slave_slave =
640 	TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
641 		slave, "slave");
642 static cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
643 	TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
644 		slave_id, RTE_UINT16);
645 static cmdline_parse_token_num_t cmd_addbonding_slave_port =
646 	TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
647 		port_id, RTE_UINT16);
648 
649 static cmdline_parse_inst_t cmd_add_bonding_slave = {
650 	.f = cmd_add_bonding_slave_parsed,
651 	.help_str = "add bonding slave <slave_id> <port_id>: "
652 		"Add a slave device to a bonded device",
653 	.data = NULL,
654 	.tokens = {
655 		(void *)&cmd_addbonding_slave_add,
656 		(void *)&cmd_addbonding_slave_bonding,
657 		(void *)&cmd_addbonding_slave_slave,
658 		(void *)&cmd_addbonding_slave_slaveid,
659 		(void *)&cmd_addbonding_slave_port,
660 		NULL
661 	}
662 };
663 
664 /* *** REMOVE SLAVE *** */
665 struct cmd_remove_bonding_slave_result {
666 	cmdline_fixed_string_t remove;
667 	cmdline_fixed_string_t bonding;
668 	cmdline_fixed_string_t slave;
669 	portid_t slave_id;
670 	portid_t port_id;
671 };
672 
673 static void cmd_remove_bonding_slave_parsed(void *parsed_result,
674 	__rte_unused struct cmdline *cl, __rte_unused void *data)
675 {
676 	struct cmd_remove_bonding_slave_result *res = parsed_result;
677 	portid_t master_port_id = res->port_id;
678 	portid_t slave_port_id = res->slave_id;
679 
680 	/* remove the slave from a bonded device. */
681 	if (rte_eth_bond_slave_remove(master_port_id, slave_port_id) != 0) {
682 		fprintf(stderr,
683 			"\t Failed to remove slave %d from master port = %d.\n",
684 			slave_port_id, master_port_id);
685 		return;
686 	}
687 	init_port_config();
688 	clear_port_slave_flag(slave_port_id);
689 }
690 
691 static cmdline_parse_token_string_t cmd_removebonding_slave_remove =
692 	TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
693 		remove, "remove");
694 static cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
695 	TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
696 		bonding, "bonding");
697 static cmdline_parse_token_string_t cmd_removebonding_slave_slave =
698 	TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
699 		slave, "slave");
700 static cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
701 	TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
702 		slave_id, RTE_UINT16);
703 static cmdline_parse_token_num_t cmd_removebonding_slave_port =
704 	TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
705 		port_id, RTE_UINT16);
706 
707 static cmdline_parse_inst_t cmd_remove_bonding_slave = {
708 	.f = cmd_remove_bonding_slave_parsed,
709 	.help_str = "remove bonding slave <slave_id> <port_id>: "
710 		"Remove a slave device from a bonded device",
711 	.data = NULL,
712 	.tokens = {
713 		(void *)&cmd_removebonding_slave_remove,
714 		(void *)&cmd_removebonding_slave_bonding,
715 		(void *)&cmd_removebonding_slave_slave,
716 		(void *)&cmd_removebonding_slave_slaveid,
717 		(void *)&cmd_removebonding_slave_port,
718 		NULL
719 	}
720 };
721 
722 /* *** CREATE BONDED DEVICE *** */
723 struct cmd_create_bonded_device_result {
724 	cmdline_fixed_string_t create;
725 	cmdline_fixed_string_t bonded;
726 	cmdline_fixed_string_t device;
727 	uint8_t mode;
728 	uint8_t socket;
729 };
730 
731 static int bond_dev_num;
732 
733 static void cmd_create_bonded_device_parsed(void *parsed_result,
734 	__rte_unused struct cmdline *cl, __rte_unused void *data)
735 {
736 	struct cmd_create_bonded_device_result *res = parsed_result;
737 	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
738 	int port_id;
739 	int ret;
740 
741 	if (test_done == 0) {
742 		fprintf(stderr, "Please stop forwarding first\n");
743 		return;
744 	}
745 
746 	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d",
747 			bond_dev_num++);
748 
749 	/* Create a new bonded device. */
750 	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
751 	if (port_id < 0) {
752 		fprintf(stderr, "\t Failed to create bonded device.\n");
753 		return;
754 	}
755 	printf("Created new bonded device %s on (port %d).\n", ethdev_name,
756 		port_id);
757 
758 	/* Update number of ports */
759 	nb_ports = rte_eth_dev_count_avail();
760 	reconfig(port_id, res->socket);
761 	ret = rte_eth_promiscuous_enable(port_id);
762 	if (ret != 0)
763 		fprintf(stderr, "Failed to enable promiscuous mode for port %u: %s - ignore\n",
764 			port_id, rte_strerror(-ret));
765 
766 	ports[port_id].update_conf = 1;
767 	ports[port_id].bond_flag = 1;
768 	ports[port_id].need_setup = 0;
769 	ports[port_id].port_status = RTE_PORT_STOPPED;
770 }
771 
772 static cmdline_parse_token_string_t cmd_createbonded_device_create =
773 	TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
774 		create, "create");
775 static cmdline_parse_token_string_t cmd_createbonded_device_bonded =
776 	TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
777 		bonded, "bonded");
778 static cmdline_parse_token_string_t cmd_createbonded_device_device =
779 	TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
780 		device, "device");
781 static cmdline_parse_token_num_t cmd_createbonded_device_mode =
782 	TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
783 		mode, RTE_UINT8);
784 static cmdline_parse_token_num_t cmd_createbonded_device_socket =
785 	TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
786 		socket, RTE_UINT8);
787 
788 static cmdline_parse_inst_t cmd_create_bonded_device = {
789 	.f = cmd_create_bonded_device_parsed,
790 	.help_str = "create bonded device <mode> <socket>: "
791 		"Create a new bonded device with specific bonding mode and socket",
792 	.data = NULL,
793 	.tokens = {
794 		(void *)&cmd_createbonded_device_create,
795 		(void *)&cmd_createbonded_device_bonded,
796 		(void *)&cmd_createbonded_device_device,
797 		(void *)&cmd_createbonded_device_mode,
798 		(void *)&cmd_createbonded_device_socket,
799 		NULL
800 	}
801 };
802 
803 /* *** SET MAC ADDRESS IN BONDED DEVICE *** */
804 struct cmd_set_bond_mac_addr_result {
805 	cmdline_fixed_string_t set;
806 	cmdline_fixed_string_t bonding;
807 	cmdline_fixed_string_t mac_addr;
808 	uint16_t port_num;
809 	struct rte_ether_addr address;
810 };
811 
812 static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
813 	__rte_unused struct cmdline *cl, __rte_unused void *data)
814 {
815 	struct cmd_set_bond_mac_addr_result *res = parsed_result;
816 	int ret;
817 
818 	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
819 		return;
820 
821 	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
822 
823 	/* check the return value and print it if is < 0 */
824 	if (ret < 0)
825 		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
826 			strerror(-ret));
827 }
828 
829 static cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
830 	TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result,
831 		set, "set");
832 static cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
833 	TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result,
834 		bonding, "bonding");
835 static cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
836 	TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result,
837 		mac_addr, "mac_addr");
838 static cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
839 	TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result,
840 		port_num, RTE_UINT16);
841 static cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
842 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result,
843 		address);
844 
845 static cmdline_parse_inst_t cmd_set_bond_mac_addr = {
846 	.f = cmd_set_bond_mac_addr_parsed,
847 	.data = NULL,
848 	.help_str = "set bonding mac_addr <port_id> <mac_addr>",
849 	.tokens = {
850 		(void *)&cmd_set_bond_mac_addr_set,
851 		(void *)&cmd_set_bond_mac_addr_bonding,
852 		(void *)&cmd_set_bond_mac_addr_mac,
853 		(void *)&cmd_set_bond_mac_addr_portnum,
854 		(void *)&cmd_set_bond_mac_addr_addr,
855 		NULL
856 	}
857 };
858 
859 /* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
860 struct cmd_set_bond_mon_period_result {
861 	cmdline_fixed_string_t set;
862 	cmdline_fixed_string_t bonding;
863 	cmdline_fixed_string_t mon_period;
864 	uint16_t port_num;
865 	uint32_t period_ms;
866 };
867 
868 static void cmd_set_bond_mon_period_parsed(void *parsed_result,
869 	__rte_unused struct cmdline *cl, __rte_unused void *data)
870 {
871 	struct cmd_set_bond_mon_period_result *res = parsed_result;
872 	int ret;
873 
874 	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
875 
876 	/* check the return value and print it if is < 0 */
877 	if (ret < 0)
878 		fprintf(stderr, "set_bond_mac_addr error: (%s)\n",
879 			strerror(-ret));
880 }
881 
882 static cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
883 	TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
884 		set, "set");
885 static cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
886 	TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
887 		bonding, "bonding");
888 static cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
889 	TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
890 		mon_period,	"mon_period");
891 static cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
892 	TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
893 		port_num, RTE_UINT16);
894 static cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
895 	TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
896 		period_ms, RTE_UINT32);
897 
898 static cmdline_parse_inst_t cmd_set_bond_mon_period = {
899 	.f = cmd_set_bond_mon_period_parsed,
900 	.data = NULL,
901 	.help_str = "set bonding mon_period <port_id> <period_ms>",
902 	.tokens = {
903 		(void *)&cmd_set_bond_mon_period_set,
904 		(void *)&cmd_set_bond_mon_period_bonding,
905 		(void *)&cmd_set_bond_mon_period_mon_period,
906 		(void *)&cmd_set_bond_mon_period_portnum,
907 		(void *)&cmd_set_bond_mon_period_period_ms,
908 		NULL
909 	}
910 };
911 
912 struct cmd_set_bonding_agg_mode_policy_result {
913 	cmdline_fixed_string_t set;
914 	cmdline_fixed_string_t bonding;
915 	cmdline_fixed_string_t agg_mode;
916 	uint16_t port_num;
917 	cmdline_fixed_string_t policy;
918 };
919 
920 static void
921 cmd_set_bonding_agg_mode(void *parsed_result,
922 	__rte_unused struct cmdline *cl, __rte_unused void *data)
923 {
924 	struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result;
925 	uint8_t policy = AGG_BANDWIDTH;
926 
927 	if (!strcmp(res->policy, "bandwidth"))
928 		policy = AGG_BANDWIDTH;
929 	else if (!strcmp(res->policy, "stable"))
930 		policy = AGG_STABLE;
931 	else if (!strcmp(res->policy, "count"))
932 		policy = AGG_COUNT;
933 
934 	rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy);
935 }
936 
937 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set =
938 	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
939 		set, "set");
940 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding =
941 	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
942 		bonding, "bonding");
943 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode =
944 	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
945 		agg_mode, "agg_mode");
946 static cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum =
947 	TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result,
948 		port_num, RTE_UINT16);
949 static cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string =
950 	TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
951 		policy, "stable#bandwidth#count");
952 
953 static cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = {
954 	.f = cmd_set_bonding_agg_mode,
955 	.data = NULL,
956 	.help_str = "set bonding mode IEEE802.3AD aggregator policy <port_id> <agg_name>",
957 	.tokens = {
958 		(void *)&cmd_set_bonding_agg_mode_set,
959 		(void *)&cmd_set_bonding_agg_mode_bonding,
960 		(void *)&cmd_set_bonding_agg_mode_agg_mode,
961 		(void *)&cmd_set_bonding_agg_mode_portnum,
962 		(void *)&cmd_set_bonding_agg_mode_policy_string,
963 		NULL
964 	}
965 };
966 
967 static struct testpmd_driver_commands bonding_cmds = {
968 	.commands = {
969 	{
970 		&cmd_set_bonding_mode,
971 		"set bonding mode (value) (port_id)\n"
972 		"	Set the bonding mode on a bonded device.\n",
973 	},
974 	{
975 		&cmd_show_bonding_config,
976 		"show bonding config (port_id)\n"
977 		"	Show the bonding config for port_id.\n",
978 	},
979 	{
980 		&cmd_show_bonding_lacp_info,
981 		"show bonding lacp info (port_id)\n"
982 		"	Show the bonding lacp information for port_id.\n",
983 	},
984 	{
985 		&cmd_set_bonding_primary,
986 		"set bonding primary (slave_id) (port_id)\n"
987 		"	Set the primary slave for a bonded device.\n",
988 	},
989 	{
990 		&cmd_add_bonding_slave,
991 		"add bonding slave (slave_id) (port_id)\n"
992 		"	Add a slave device to a bonded device.\n",
993 	},
994 	{
995 		&cmd_remove_bonding_slave,
996 		"remove bonding slave (slave_id) (port_id)\n"
997 		"	Remove a slave device from a bonded device.\n",
998 	},
999 	{
1000 		&cmd_create_bonded_device,
1001 		"create bonded device (mode) (socket)\n"
1002 		"	Create a new bonded device with specific bonding mode and socket.\n",
1003 	},
1004 	{
1005 		&cmd_set_bond_mac_addr,
1006 		"set bonding mac_addr (port_id) (address)\n"
1007 		"	Set the MAC address of a bonded device.\n",
1008 	},
1009 	{
1010 		&cmd_set_balance_xmit_policy,
1011 		"set bonding balance_xmit_policy (port_id) (l2|l23|l34)\n"
1012 		"	Set the transmit balance policy for bonded device running in balance mode.\n",
1013 	},
1014 	{
1015 		&cmd_set_bond_mon_period,
1016 		"set bonding mon_period (port_id) (value)\n"
1017 		"	Set the bonding link status monitoring polling period in ms.\n",
1018 	},
1019 	{
1020 		&cmd_set_lacp_dedicated_queues,
1021 		"set bonding lacp dedicated_queues <port_id> (enable|disable)\n"
1022 		"	Enable/disable dedicated queues for LACP control traffic.\n",
1023 	},
1024 	{
1025 		&cmd_set_bonding_agg_mode_policy,
1026 		"set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)\n"
1027 		"	Set Aggregation mode for IEEE802.3AD (mode 4)\n",
1028 	},
1029 	{ NULL, NULL },
1030 	},
1031 };
1032 TESTPMD_ADD_DRIVER_COMMANDS(bonding_cmds)
1033