xref: /dpdk/app/test-pmd/cmdline_mtr.c (revision f96a8ebb)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4 
5 #include <cmdline_parse.h>
6 #include <cmdline_parse_num.h>
7 #include <cmdline_parse_string.h>
8 
9 #include <rte_ethdev.h>
10 #include <rte_flow.h>
11 #include <rte_mtr.h>
12 
13 #include "testpmd.h"
14 #include "cmdline_mtr.h"
15 
16 #define PARSE_DELIMITER				" \f\n\r\t\v"
17 #define MAX_DSCP_TABLE_ENTRIES		64
18 
19 /** Display Meter Error Message */
20 static void
21 print_err_msg(struct rte_mtr_error *error)
22 {
23 	static const char *const errstrlist[] = {
24 		[RTE_MTR_ERROR_TYPE_NONE] = "no error",
25 		[RTE_MTR_ERROR_TYPE_UNSPECIFIED] = "cause unspecified",
26 		[RTE_MTR_ERROR_TYPE_METER_PROFILE_ID] = "meter profile id",
27 		[RTE_MTR_ERROR_TYPE_METER_PROFILE] = "meter profile null",
28 		[RTE_MTR_ERROR_TYPE_MTR_ID] = "meter id",
29 		[RTE_MTR_ERROR_TYPE_MTR_PARAMS] = "meter params null",
30 		[RTE_MTR_ERROR_TYPE_POLICER_ACTION_GREEN]
31 			= "policer action(green)",
32 		[RTE_MTR_ERROR_TYPE_POLICER_ACTION_YELLOW]
33 			= "policer action(yellow)",
34 		[RTE_MTR_ERROR_TYPE_POLICER_ACTION_RED]
35 			= "policer action(red)",
36 		[RTE_MTR_ERROR_TYPE_STATS_MASK] = "stats mask",
37 		[RTE_MTR_ERROR_TYPE_STATS] = "stats",
38 		[RTE_MTR_ERROR_TYPE_SHARED]
39 			= "shared meter",
40 	};
41 
42 	const char *errstr;
43 	char buf[64];
44 
45 	if ((unsigned int)error->type >= RTE_DIM(errstrlist) ||
46 		!errstrlist[error->type])
47 		errstr = "unknown type";
48 	else
49 		errstr = errstrlist[error->type];
50 
51 	if (error->cause)
52 		snprintf(buf, sizeof(buf), "cause: %p, ", error->cause);
53 
54 	printf("%s: %s%s (error %d)\n", errstr, error->cause ? buf : "",
55 		error->message ? error->message : "(no stated reason)",
56 		error->type);
57 }
58 
59 static int
60 parse_uint(uint64_t *value, const char *str)
61 {
62 	char *next = NULL;
63 	uint64_t n;
64 
65 	errno = 0;
66 	/* Parse number string */
67 	n = strtol(str, &next, 10);
68 	if (errno != 0 || str == next || *next != '\0')
69 		return -1;
70 
71 	*value = n;
72 
73 	return 0;
74 }
75 
76 static int
77 parse_dscp_table_entries(char *str, enum rte_color **dscp_table)
78 {
79 	char *token;
80 	int i = 0;
81 
82 	token = strtok_r(str, PARSE_DELIMITER, &str);
83 	if (token == NULL)
84 		return 0;
85 
86 	/* Allocate memory for dscp table */
87 	*dscp_table = (enum rte_color *)malloc(MAX_DSCP_TABLE_ENTRIES *
88 		sizeof(enum rte_color));
89 	if (*dscp_table == NULL)
90 		return -1;
91 
92 	while (1) {
93 		if (strcmp(token, "G") == 0 ||
94 			strcmp(token, "g") == 0)
95 			*dscp_table[i++] = RTE_COLOR_GREEN;
96 		else if (strcmp(token, "Y") == 0 ||
97 			strcmp(token, "y") == 0)
98 			*dscp_table[i++] = RTE_COLOR_YELLOW;
99 		else if (strcmp(token, "R") == 0 ||
100 			strcmp(token, "r") == 0)
101 			*dscp_table[i++] = RTE_COLOR_RED;
102 		else {
103 			free(*dscp_table);
104 			return -1;
105 		}
106 		if (i == MAX_DSCP_TABLE_ENTRIES)
107 			break;
108 
109 		token = strtok_r(str, PARSE_DELIMITER, &str);
110 		if (token == NULL) {
111 			free(*dscp_table);
112 			return -1;
113 		}
114 	}
115 	return 0;
116 }
117 
118 static int
119 parse_meter_color_str(char *c_str, uint32_t *use_prev_meter_color,
120 	enum rte_color **dscp_table)
121 {
122 	char *token;
123 	uint64_t previous_mtr_color = 0;
124 	int ret;
125 
126 	/* First token: use previous meter color */
127 	token = strtok_r(c_str, PARSE_DELIMITER, &c_str);
128 	if (token ==  NULL)
129 		return -1;
130 
131 	ret = parse_uint(&previous_mtr_color, token);
132 	if (ret != 0)
133 		return -1;
134 
135 	/* Check if previous meter color to be used */
136 	if (previous_mtr_color) {
137 		*use_prev_meter_color = previous_mtr_color;
138 		return 0;
139 	}
140 
141 	/* Parse dscp table entries */
142 	ret = parse_dscp_table_entries(c_str, dscp_table);
143 	if (ret != 0)
144 		return -1;
145 
146 	return 0;
147 }
148 
149 static int
150 string_to_policer_action(char *s)
151 {
152 	if ((strcmp(s, "G") == 0) || (strcmp(s, "g") == 0))
153 		return MTR_POLICER_ACTION_COLOR_GREEN;
154 
155 	if ((strcmp(s, "Y") == 0) || (strcmp(s, "y") == 0))
156 		return MTR_POLICER_ACTION_COLOR_YELLOW;
157 
158 	if ((strcmp(s, "R") == 0) || (strcmp(s, "r") == 0))
159 		return MTR_POLICER_ACTION_COLOR_RED;
160 
161 	if ((strcmp(s, "D") == 0) || (strcmp(s, "d") == 0))
162 		return MTR_POLICER_ACTION_DROP;
163 
164 	return -1;
165 }
166 
167 static int
168 parse_policer_action_string(char *p_str, uint32_t action_mask,
169 	enum rte_mtr_policer_action actions[])
170 {
171 	char *token;
172 	int count = __builtin_popcount(action_mask);
173 	int g_color = 0, y_color = 0, action, i;
174 
175 	for (i = 0; i < count; i++) {
176 		token = strtok_r(p_str, PARSE_DELIMITER, &p_str);
177 		if (token ==  NULL)
178 			return -1;
179 
180 		action = string_to_policer_action(token);
181 		if (action == -1)
182 			return -1;
183 
184 		if (g_color == 0 && (action_mask & 0x1)) {
185 			actions[RTE_COLOR_GREEN] = action;
186 			g_color = 1;
187 		} else if (y_color == 0 && (action_mask & 0x2)) {
188 			actions[RTE_COLOR_YELLOW] = action;
189 			y_color = 1;
190 		} else
191 			actions[RTE_COLOR_RED] = action;
192 	}
193 	return 0;
194 }
195 
196 static int
197 parse_multi_token_string(char *t_str, uint16_t *port_id,
198 	uint32_t *mtr_id, enum rte_color **dscp_table)
199 {
200 	char *token;
201 	uint64_t val;
202 	int ret;
203 
204 	/* First token: port id */
205 	token = strtok_r(t_str, PARSE_DELIMITER, &t_str);
206 	if (token ==  NULL)
207 		return -1;
208 
209 	ret = parse_uint(&val, token);
210 	if (ret != 0 || val > UINT16_MAX)
211 		return -1;
212 
213 	*port_id = val;
214 
215 	/* Second token: meter id */
216 	token = strtok_r(t_str, PARSE_DELIMITER, &t_str);
217 	if (token == NULL)
218 		return 0;
219 
220 	ret = parse_uint(&val, token);
221 	if (ret != 0 || val > UINT32_MAX)
222 		return -1;
223 
224 	*mtr_id = val;
225 
226 	ret = parse_dscp_table_entries(t_str, dscp_table);
227 	if (ret != 0)
228 		return -1;
229 
230 	return 0;
231 }
232 
233 /* *** Show Port Meter Capabilities *** */
234 struct cmd_show_port_meter_cap_result {
235 	cmdline_fixed_string_t show;
236 	cmdline_fixed_string_t port;
237 	cmdline_fixed_string_t meter;
238 	cmdline_fixed_string_t cap;
239 	uint16_t port_id;
240 };
241 
242 cmdline_parse_token_string_t cmd_show_port_meter_cap_show =
243 	TOKEN_STRING_INITIALIZER(
244 		struct cmd_show_port_meter_cap_result, show, "show");
245 cmdline_parse_token_string_t cmd_show_port_meter_cap_port =
246 	TOKEN_STRING_INITIALIZER(
247 		struct cmd_show_port_meter_cap_result, port, "port");
248 cmdline_parse_token_string_t cmd_show_port_meter_cap_meter =
249 	TOKEN_STRING_INITIALIZER(
250 		struct cmd_show_port_meter_cap_result, meter, "meter");
251 cmdline_parse_token_string_t cmd_show_port_meter_cap_cap =
252 	TOKEN_STRING_INITIALIZER(
253 		struct cmd_show_port_meter_cap_result, cap, "cap");
254 cmdline_parse_token_num_t cmd_show_port_meter_cap_port_id =
255 	TOKEN_NUM_INITIALIZER(
256 		struct cmd_show_port_meter_cap_result, port_id, RTE_UINT16);
257 
258 static void cmd_show_port_meter_cap_parsed(void *parsed_result,
259 	__rte_unused struct cmdline *cl,
260 	__rte_unused void *data)
261 {
262 	struct cmd_show_port_meter_cap_result *res = parsed_result;
263 	struct rte_mtr_capabilities cap;
264 	struct rte_mtr_error error;
265 	uint16_t port_id = res->port_id;
266 	int ret;
267 
268 	if (port_id_is_invalid(port_id, ENABLED_WARN))
269 		return;
270 
271 	memset(&cap, 0, sizeof(struct rte_mtr_capabilities));
272 	ret = rte_mtr_capabilities_get(port_id, &cap, &error);
273 	if (ret) {
274 		print_err_msg(&error);
275 		return;
276 	}
277 
278 	printf("\n****   Port Meter Object Capabilities ****\n\n");
279 	printf("cap.n_max %" PRIu32 "\n", cap.n_max);
280 	printf("cap.n_shared_max %" PRIu32 "\n", cap.n_shared_max);
281 	printf("cap.identical %" PRId32 "\n", cap.identical);
282 	printf("cap.shared_identical %" PRId32 "\n",
283 		cap.shared_identical);
284 	printf("cap.shared_n_flows_per_mtr_max %" PRIu32 "\n",
285 		cap.shared_n_flows_per_mtr_max);
286 	printf("cap.chaining_n_mtrs_per_flow_max %" PRIu32 "\n",
287 		cap.chaining_n_mtrs_per_flow_max);
288 	printf("cap.chaining_use_prev_mtr_color_supported %" PRId32 "\n",
289 		cap.chaining_use_prev_mtr_color_supported);
290 	printf("cap.chaining_use_prev_mtr_color_enforced %" PRId32 "\n",
291 		cap.chaining_use_prev_mtr_color_enforced);
292 	printf("cap.meter_srtcm_rfc2697_n_max %" PRIu32 "\n",
293 		cap.meter_srtcm_rfc2697_n_max);
294 	printf("cap.meter_trtcm_rfc2698_n_max %" PRIu32 "\n",
295 		cap.meter_trtcm_rfc2698_n_max);
296 	printf("cap.meter_trtcm_rfc4115_n_max %" PRIu32 "\n",
297 		cap.meter_trtcm_rfc4115_n_max);
298 	printf("cap.meter_rate_max %" PRIu64 "\n", cap.meter_rate_max);
299 	printf("cap.color_aware_srtcm_rfc2697_supported %" PRId32 "\n",
300 		cap.color_aware_srtcm_rfc2697_supported);
301 	printf("cap.color_aware_trtcm_rfc2698_supported %" PRId32 "\n",
302 		cap.color_aware_trtcm_rfc2698_supported);
303 	printf("cap.color_aware_trtcm_rfc4115_supported %" PRId32 "\n",
304 		cap.color_aware_trtcm_rfc4115_supported);
305 	printf("cap.policer_action_recolor_supported %" PRId32 "\n",
306 		cap.policer_action_recolor_supported);
307 	printf("cap.policer_action_drop_supported %" PRId32 "\n",
308 		cap.policer_action_drop_supported);
309 	printf("cap.srtcm_rfc2697_byte_mode_supported %" PRId32 "\n",
310 		cap.srtcm_rfc2697_byte_mode_supported);
311 	printf("cap.srtcm_rfc2697_packet_mode_supported %" PRId32 "\n",
312 		cap.srtcm_rfc2697_packet_mode_supported);
313 	printf("cap.trtcm_rfc2698_byte_mode_supported %" PRId32 "\n",
314 		cap.trtcm_rfc2698_byte_mode_supported);
315 	printf("cap.trtcm_rfc2698_packet_mode_supported %" PRId32 "\n",
316 		cap.trtcm_rfc2698_packet_mode_supported);
317 	printf("cap.trtcm_rfc4115_byte_mode_supported %" PRId32 "\n",
318 		cap.trtcm_rfc4115_byte_mode_supported);
319 	printf("cap.trtcm_rfc4115_packet_mode_supported %" PRId32 "\n",
320 		cap.trtcm_rfc4115_packet_mode_supported);
321 	printf("cap.stats_mask %" PRIx64 "\n", cap.stats_mask);
322 }
323 
324 cmdline_parse_inst_t cmd_show_port_meter_cap = {
325 	.f = cmd_show_port_meter_cap_parsed,
326 	.data = NULL,
327 	.help_str = "show port meter cap <port_id>",
328 	.tokens = {
329 		(void *)&cmd_show_port_meter_cap_show,
330 		(void *)&cmd_show_port_meter_cap_port,
331 		(void *)&cmd_show_port_meter_cap_meter,
332 		(void *)&cmd_show_port_meter_cap_cap,
333 		(void *)&cmd_show_port_meter_cap_port_id,
334 		NULL,
335 	},
336 };
337 
338 /* *** Add Port Meter Profile srtcm_rfc2697 *** */
339 struct cmd_add_port_meter_profile_srtcm_result {
340 	cmdline_fixed_string_t add;
341 	cmdline_fixed_string_t port;
342 	cmdline_fixed_string_t meter;
343 	cmdline_fixed_string_t profile;
344 	cmdline_fixed_string_t srtcm_rfc2697;
345 	uint16_t port_id;
346 	uint32_t profile_id;
347 	uint64_t cir;
348 	uint64_t cbs;
349 	uint64_t ebs;
350 	int packet_mode;
351 };
352 
353 cmdline_parse_token_string_t cmd_add_port_meter_profile_srtcm_add =
354 	TOKEN_STRING_INITIALIZER(
355 		struct cmd_add_port_meter_profile_srtcm_result, add, "add");
356 cmdline_parse_token_string_t cmd_add_port_meter_profile_srtcm_port =
357 	TOKEN_STRING_INITIALIZER(
358 		struct cmd_add_port_meter_profile_srtcm_result,
359 			port, "port");
360 cmdline_parse_token_string_t cmd_add_port_meter_profile_srtcm_meter =
361 	TOKEN_STRING_INITIALIZER(
362 		struct cmd_add_port_meter_profile_srtcm_result,
363 			meter, "meter");
364 cmdline_parse_token_string_t cmd_add_port_meter_profile_srtcm_profile =
365 	TOKEN_STRING_INITIALIZER(
366 		struct cmd_add_port_meter_profile_srtcm_result,
367 			profile, "profile");
368 cmdline_parse_token_string_t cmd_add_port_meter_profile_srtcm_srtcm_rfc2697 =
369 	TOKEN_STRING_INITIALIZER(
370 		struct cmd_add_port_meter_profile_srtcm_result,
371 			srtcm_rfc2697, "srtcm_rfc2697");
372 cmdline_parse_token_num_t cmd_add_port_meter_profile_srtcm_port_id =
373 	TOKEN_NUM_INITIALIZER(
374 		struct cmd_add_port_meter_profile_srtcm_result,
375 			port_id, RTE_UINT16);
376 cmdline_parse_token_num_t cmd_add_port_meter_profile_srtcm_profile_id =
377 	TOKEN_NUM_INITIALIZER(
378 		struct cmd_add_port_meter_profile_srtcm_result,
379 			profile_id, RTE_UINT32);
380 cmdline_parse_token_num_t cmd_add_port_meter_profile_srtcm_cir =
381 	TOKEN_NUM_INITIALIZER(
382 		struct cmd_add_port_meter_profile_srtcm_result,
383 			cir, RTE_UINT64);
384 cmdline_parse_token_num_t cmd_add_port_meter_profile_srtcm_cbs =
385 	TOKEN_NUM_INITIALIZER(
386 		struct cmd_add_port_meter_profile_srtcm_result,
387 			cbs, RTE_UINT64);
388 cmdline_parse_token_num_t cmd_add_port_meter_profile_srtcm_ebs =
389 	TOKEN_NUM_INITIALIZER(
390 		struct cmd_add_port_meter_profile_srtcm_result,
391 			ebs, RTE_UINT64);
392 cmdline_parse_token_num_t cmd_add_port_meter_profile_srtcm_packet_mode =
393 	TOKEN_NUM_INITIALIZER(
394 		struct cmd_add_port_meter_profile_srtcm_result,
395 			packet_mode, RTE_UINT32);
396 
397 static void cmd_add_port_meter_profile_srtcm_parsed(void *parsed_result,
398 	__rte_unused struct cmdline *cl,
399 	__rte_unused void *data)
400 {
401 	struct cmd_add_port_meter_profile_srtcm_result *res = parsed_result;
402 	struct rte_mtr_meter_profile mp;
403 	struct rte_mtr_error error;
404 	uint32_t profile_id = res->profile_id;
405 	uint16_t port_id = res->port_id;
406 	int ret;
407 
408 	if (port_id_is_invalid(port_id, ENABLED_WARN))
409 		return;
410 
411 	/* Private shaper profile params */
412 	memset(&mp, 0, sizeof(struct rte_mtr_meter_profile));
413 	mp.alg = RTE_MTR_SRTCM_RFC2697;
414 	mp.srtcm_rfc2697.cir = res->cir;
415 	mp.srtcm_rfc2697.cbs = res->cbs;
416 	mp.srtcm_rfc2697.ebs = res->ebs;
417 	mp.packet_mode = res->packet_mode;
418 
419 	ret = rte_mtr_meter_profile_add(port_id, profile_id, &mp, &error);
420 	if (ret != 0) {
421 		print_err_msg(&error);
422 		return;
423 	}
424 }
425 
426 cmdline_parse_inst_t cmd_add_port_meter_profile_srtcm = {
427 	.f = cmd_add_port_meter_profile_srtcm_parsed,
428 	.data = NULL,
429 	.help_str = "add port meter profile srtcm_rfc2697 <port_id> <profile_id> <cir> <cbs> <ebs> <packet_mode>",
430 	.tokens = {
431 		(void *)&cmd_add_port_meter_profile_srtcm_add,
432 		(void *)&cmd_add_port_meter_profile_srtcm_port,
433 		(void *)&cmd_add_port_meter_profile_srtcm_meter,
434 		(void *)&cmd_add_port_meter_profile_srtcm_profile,
435 		(void *)&cmd_add_port_meter_profile_srtcm_srtcm_rfc2697,
436 		(void *)&cmd_add_port_meter_profile_srtcm_port_id,
437 		(void *)&cmd_add_port_meter_profile_srtcm_profile_id,
438 		(void *)&cmd_add_port_meter_profile_srtcm_cir,
439 		(void *)&cmd_add_port_meter_profile_srtcm_cbs,
440 		(void *)&cmd_add_port_meter_profile_srtcm_ebs,
441 		(void *)&cmd_add_port_meter_profile_srtcm_packet_mode,
442 		NULL,
443 	},
444 };
445 
446 /* *** Add Port Meter Profile trtcm_rfc2698 *** */
447 struct cmd_add_port_meter_profile_trtcm_result {
448 	cmdline_fixed_string_t add;
449 	cmdline_fixed_string_t port;
450 	cmdline_fixed_string_t meter;
451 	cmdline_fixed_string_t profile;
452 	cmdline_fixed_string_t trtcm_rfc2698;
453 	uint16_t port_id;
454 	uint32_t profile_id;
455 	uint64_t cir;
456 	uint64_t pir;
457 	uint64_t cbs;
458 	uint64_t pbs;
459 	int packet_mode;
460 };
461 
462 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_add =
463 	TOKEN_STRING_INITIALIZER(
464 		struct cmd_add_port_meter_profile_trtcm_result, add, "add");
465 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_port =
466 	TOKEN_STRING_INITIALIZER(
467 		struct cmd_add_port_meter_profile_trtcm_result,
468 			port, "port");
469 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_meter =
470 	TOKEN_STRING_INITIALIZER(
471 		struct cmd_add_port_meter_profile_trtcm_result,
472 			meter, "meter");
473 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_profile =
474 	TOKEN_STRING_INITIALIZER(
475 		struct cmd_add_port_meter_profile_trtcm_result,
476 			profile, "profile");
477 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_trtcm_rfc2698 =
478 	TOKEN_STRING_INITIALIZER(
479 		struct cmd_add_port_meter_profile_trtcm_result,
480 			trtcm_rfc2698, "trtcm_rfc2698");
481 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_port_id =
482 	TOKEN_NUM_INITIALIZER(
483 		struct cmd_add_port_meter_profile_trtcm_result,
484 			port_id, RTE_UINT16);
485 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_profile_id =
486 	TOKEN_NUM_INITIALIZER(
487 		struct cmd_add_port_meter_profile_trtcm_result,
488 			profile_id, RTE_UINT32);
489 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_cir =
490 	TOKEN_NUM_INITIALIZER(
491 		struct cmd_add_port_meter_profile_trtcm_result,
492 			cir, RTE_UINT64);
493 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_pir =
494 	TOKEN_NUM_INITIALIZER(
495 		struct cmd_add_port_meter_profile_trtcm_result,
496 			pir, RTE_UINT64);
497 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_cbs =
498 	TOKEN_NUM_INITIALIZER(
499 		struct cmd_add_port_meter_profile_trtcm_result,
500 			cbs, RTE_UINT64);
501 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_pbs =
502 	TOKEN_NUM_INITIALIZER(
503 		struct cmd_add_port_meter_profile_trtcm_result,
504 			pbs, RTE_UINT64);
505 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_packet_mode =
506 	TOKEN_NUM_INITIALIZER(
507 		struct cmd_add_port_meter_profile_trtcm_result,
508 			packet_mode, RTE_UINT32);
509 
510 static void cmd_add_port_meter_profile_trtcm_parsed(void *parsed_result,
511 	__rte_unused struct cmdline *cl,
512 	__rte_unused void *data)
513 {
514 	struct cmd_add_port_meter_profile_trtcm_result *res = parsed_result;
515 	struct rte_mtr_meter_profile mp;
516 	struct rte_mtr_error error;
517 	uint32_t profile_id = res->profile_id;
518 	uint16_t port_id = res->port_id;
519 	int ret;
520 
521 	if (port_id_is_invalid(port_id, ENABLED_WARN))
522 		return;
523 
524 	/* Private shaper profile params */
525 	memset(&mp, 0, sizeof(struct rte_mtr_meter_profile));
526 	mp.alg = RTE_MTR_TRTCM_RFC2698;
527 	mp.trtcm_rfc2698.cir = res->cir;
528 	mp.trtcm_rfc2698.pir = res->pir;
529 	mp.trtcm_rfc2698.cbs = res->cbs;
530 	mp.trtcm_rfc2698.pbs = res->pbs;
531 	mp.packet_mode = res->packet_mode;
532 
533 	ret = rte_mtr_meter_profile_add(port_id, profile_id, &mp, &error);
534 	if (ret != 0) {
535 		print_err_msg(&error);
536 		return;
537 	}
538 }
539 
540 cmdline_parse_inst_t cmd_add_port_meter_profile_trtcm = {
541 	.f = cmd_add_port_meter_profile_trtcm_parsed,
542 	.data = NULL,
543 	.help_str = "add port meter profile trtcm_rfc2698 <port_id> <profile_id> <cir> <pir> <cbs> <pbs> <packet_mode>",
544 	.tokens = {
545 		(void *)&cmd_add_port_meter_profile_trtcm_add,
546 		(void *)&cmd_add_port_meter_profile_trtcm_port,
547 		(void *)&cmd_add_port_meter_profile_trtcm_meter,
548 		(void *)&cmd_add_port_meter_profile_trtcm_profile,
549 		(void *)&cmd_add_port_meter_profile_trtcm_trtcm_rfc2698,
550 		(void *)&cmd_add_port_meter_profile_trtcm_port_id,
551 		(void *)&cmd_add_port_meter_profile_trtcm_profile_id,
552 		(void *)&cmd_add_port_meter_profile_trtcm_cir,
553 		(void *)&cmd_add_port_meter_profile_trtcm_pir,
554 		(void *)&cmd_add_port_meter_profile_trtcm_cbs,
555 		(void *)&cmd_add_port_meter_profile_trtcm_pbs,
556 		(void *)&cmd_add_port_meter_profile_trtcm_packet_mode,
557 		NULL,
558 	},
559 };
560 
561 /* *** Add Port Meter Profile trtcm_rfc4115 *** */
562 struct cmd_add_port_meter_profile_trtcm_rfc4115_result {
563 	cmdline_fixed_string_t add;
564 	cmdline_fixed_string_t port;
565 	cmdline_fixed_string_t meter;
566 	cmdline_fixed_string_t profile;
567 	cmdline_fixed_string_t trtcm_rfc4115;
568 	uint16_t port_id;
569 	uint32_t profile_id;
570 	uint64_t cir;
571 	uint64_t eir;
572 	uint64_t cbs;
573 	uint64_t ebs;
574 	int packet_mode;
575 };
576 
577 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_rfc4115_add =
578 	TOKEN_STRING_INITIALIZER(
579 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result, add,
580 		"add");
581 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_rfc4115_port =
582 	TOKEN_STRING_INITIALIZER(
583 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
584 			port, "port");
585 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_rfc4115_meter =
586 	TOKEN_STRING_INITIALIZER(
587 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
588 			meter, "meter");
589 cmdline_parse_token_string_t cmd_add_port_meter_profile_trtcm_rfc4115_profile =
590 	TOKEN_STRING_INITIALIZER(
591 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
592 			profile, "profile");
593 cmdline_parse_token_string_t
594 	cmd_add_port_meter_profile_trtcm_rfc4115_trtcm_rfc4115 =
595 	TOKEN_STRING_INITIALIZER(
596 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
597 			trtcm_rfc4115, "trtcm_rfc4115");
598 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_rfc4115_port_id =
599 	TOKEN_NUM_INITIALIZER(
600 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
601 			port_id, RTE_UINT16);
602 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_rfc4115_profile_id =
603 	TOKEN_NUM_INITIALIZER(
604 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
605 			profile_id, RTE_UINT32);
606 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_rfc4115_cir =
607 	TOKEN_NUM_INITIALIZER(
608 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
609 			cir, RTE_UINT64);
610 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_rfc4115_eir =
611 	TOKEN_NUM_INITIALIZER(
612 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
613 			eir, RTE_UINT64);
614 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_rfc4115_cbs =
615 	TOKEN_NUM_INITIALIZER(
616 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
617 			cbs, RTE_UINT64);
618 cmdline_parse_token_num_t cmd_add_port_meter_profile_trtcm_rfc4115_ebs =
619 	TOKEN_NUM_INITIALIZER(
620 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
621 			ebs, RTE_UINT64);
622 cmdline_parse_token_num_t
623 	cmd_add_port_meter_profile_trtcm_rfc4115_packet_mode =
624 	TOKEN_NUM_INITIALIZER(
625 		struct cmd_add_port_meter_profile_trtcm_rfc4115_result,
626 			packet_mode, RTE_UINT32);
627 
628 static void cmd_add_port_meter_profile_trtcm_rfc4115_parsed(
629 	void *parsed_result,
630 	__rte_unused struct cmdline *cl,
631 	__rte_unused void *data)
632 {
633 	struct cmd_add_port_meter_profile_trtcm_rfc4115_result *res =
634 		parsed_result;
635 	struct rte_mtr_meter_profile mp;
636 	struct rte_mtr_error error;
637 	uint32_t profile_id = res->profile_id;
638 	uint16_t port_id = res->port_id;
639 	int ret;
640 
641 	if (port_id_is_invalid(port_id, ENABLED_WARN))
642 		return;
643 
644 	/* Private shaper profile params */
645 	memset(&mp, 0, sizeof(struct rte_mtr_meter_profile));
646 	mp.alg = RTE_MTR_TRTCM_RFC4115;
647 	mp.trtcm_rfc4115.cir = res->cir;
648 	mp.trtcm_rfc4115.eir = res->eir;
649 	mp.trtcm_rfc4115.cbs = res->cbs;
650 	mp.trtcm_rfc4115.ebs = res->ebs;
651 	mp.packet_mode = res->packet_mode;
652 
653 	ret = rte_mtr_meter_profile_add(port_id, profile_id, &mp, &error);
654 	if (ret != 0) {
655 		print_err_msg(&error);
656 		return;
657 	}
658 }
659 
660 cmdline_parse_inst_t cmd_add_port_meter_profile_trtcm_rfc4115 = {
661 	.f = cmd_add_port_meter_profile_trtcm_rfc4115_parsed,
662 	.data = NULL,
663 	.help_str = "add port meter profile trtcm_rfc4115 <port_id> <profile_id> <cir> <eir> <cbs> <ebs> <packet_mode>",
664 	.tokens = {
665 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_add,
666 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_port,
667 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_meter,
668 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_profile,
669 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_trtcm_rfc4115,
670 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_port_id,
671 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_profile_id,
672 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_cir,
673 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_eir,
674 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_cbs,
675 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_ebs,
676 		(void *)&cmd_add_port_meter_profile_trtcm_rfc4115_packet_mode,
677 		NULL,
678 	},
679 };
680 
681 /* *** Delete Port Meter Profile *** */
682 struct cmd_del_port_meter_profile_result {
683 	cmdline_fixed_string_t del;
684 	cmdline_fixed_string_t port;
685 	cmdline_fixed_string_t meter;
686 	cmdline_fixed_string_t profile;
687 	uint16_t port_id;
688 	uint32_t profile_id;
689 };
690 
691 cmdline_parse_token_string_t cmd_del_port_meter_profile_del =
692 	TOKEN_STRING_INITIALIZER(
693 		struct cmd_del_port_meter_profile_result, del, "del");
694 cmdline_parse_token_string_t cmd_del_port_meter_profile_port =
695 	TOKEN_STRING_INITIALIZER(
696 		struct cmd_del_port_meter_profile_result,
697 			port, "port");
698 cmdline_parse_token_string_t cmd_del_port_meter_profile_meter =
699 	TOKEN_STRING_INITIALIZER(
700 		struct cmd_del_port_meter_profile_result,
701 			meter, "meter");
702 cmdline_parse_token_string_t cmd_del_port_meter_profile_profile =
703 	TOKEN_STRING_INITIALIZER(
704 		struct cmd_del_port_meter_profile_result,
705 			profile, "profile");
706 cmdline_parse_token_num_t cmd_del_port_meter_profile_port_id =
707 	TOKEN_NUM_INITIALIZER(
708 		struct cmd_del_port_meter_profile_result,
709 			port_id, RTE_UINT16);
710 cmdline_parse_token_num_t cmd_del_port_meter_profile_profile_id =
711 	TOKEN_NUM_INITIALIZER(
712 		struct cmd_del_port_meter_profile_result,
713 			profile_id, RTE_UINT32);
714 
715 static void cmd_del_port_meter_profile_parsed(void *parsed_result,
716 	__rte_unused struct cmdline *cl,
717 	__rte_unused void *data)
718 {
719 	struct cmd_del_port_meter_profile_result *res = parsed_result;
720 	struct rte_mtr_error error;
721 	uint32_t profile_id = res->profile_id;
722 	uint16_t port_id = res->port_id;
723 	int ret;
724 
725 	if (port_id_is_invalid(port_id, ENABLED_WARN))
726 		return;
727 
728 	/* Delete meter profile */
729 	ret = rte_mtr_meter_profile_delete(port_id, profile_id, &error);
730 	if (ret != 0) {
731 		print_err_msg(&error);
732 		return;
733 	}
734 }
735 
736 cmdline_parse_inst_t cmd_del_port_meter_profile = {
737 	.f = cmd_del_port_meter_profile_parsed,
738 	.data = NULL,
739 	.help_str = "del port meter profile <port_id> <profile_id>",
740 	.tokens = {
741 		(void *)&cmd_del_port_meter_profile_del,
742 		(void *)&cmd_del_port_meter_profile_port,
743 		(void *)&cmd_del_port_meter_profile_meter,
744 		(void *)&cmd_del_port_meter_profile_profile,
745 		(void *)&cmd_del_port_meter_profile_port_id,
746 		(void *)&cmd_del_port_meter_profile_profile_id,
747 		NULL,
748 	},
749 };
750 
751 /* *** Create Port Meter Object *** */
752 struct cmd_create_port_meter_result {
753 	cmdline_fixed_string_t create;
754 	cmdline_fixed_string_t port;
755 	cmdline_fixed_string_t meter;
756 	uint16_t port_id;
757 	uint32_t mtr_id;
758 	uint32_t profile_id;
759 	cmdline_fixed_string_t meter_enable;
760 	cmdline_fixed_string_t g_action;
761 	cmdline_fixed_string_t y_action;
762 	cmdline_fixed_string_t r_action;
763 	uint64_t statistics_mask;
764 	uint32_t shared;
765 	cmdline_multi_string_t meter_input_color;
766 };
767 
768 cmdline_parse_token_string_t cmd_create_port_meter_create =
769 	TOKEN_STRING_INITIALIZER(
770 		struct cmd_create_port_meter_result, create, "create");
771 cmdline_parse_token_string_t cmd_create_port_meter_port =
772 	TOKEN_STRING_INITIALIZER(
773 		struct cmd_create_port_meter_result, port, "port");
774 cmdline_parse_token_string_t cmd_create_port_meter_meter =
775 	TOKEN_STRING_INITIALIZER(
776 		struct cmd_create_port_meter_result, meter, "meter");
777 cmdline_parse_token_num_t cmd_create_port_meter_port_id =
778 	TOKEN_NUM_INITIALIZER(
779 		struct cmd_create_port_meter_result, port_id, RTE_UINT16);
780 cmdline_parse_token_num_t cmd_create_port_meter_mtr_id =
781 	TOKEN_NUM_INITIALIZER(
782 		struct cmd_create_port_meter_result, mtr_id, RTE_UINT32);
783 cmdline_parse_token_num_t cmd_create_port_meter_profile_id =
784 	TOKEN_NUM_INITIALIZER(
785 		struct cmd_create_port_meter_result, profile_id, RTE_UINT32);
786 cmdline_parse_token_string_t cmd_create_port_meter_meter_enable =
787 	TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result,
788 		meter_enable, "yes#no");
789 cmdline_parse_token_string_t cmd_create_port_meter_g_action =
790 	TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result,
791 		g_action, "R#Y#G#D#r#y#g#d");
792 cmdline_parse_token_string_t cmd_create_port_meter_y_action =
793 	TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result,
794 		y_action, "R#Y#G#D#r#y#g#d");
795 cmdline_parse_token_string_t cmd_create_port_meter_r_action =
796 	TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result,
797 		r_action, "R#Y#G#D#r#y#g#d");
798 cmdline_parse_token_num_t cmd_create_port_meter_statistics_mask =
799 	TOKEN_NUM_INITIALIZER(struct cmd_create_port_meter_result,
800 		statistics_mask, RTE_UINT64);
801 cmdline_parse_token_num_t cmd_create_port_meter_shared =
802 	TOKEN_NUM_INITIALIZER(struct cmd_create_port_meter_result,
803 		shared, RTE_UINT32);
804 cmdline_parse_token_string_t cmd_create_port_meter_input_color =
805 	TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result,
806 		meter_input_color, TOKEN_STRING_MULTI);
807 
808 static void cmd_create_port_meter_parsed(void *parsed_result,
809 	__rte_unused struct cmdline *cl,
810 	__rte_unused void *data)
811 {
812 	struct cmd_create_port_meter_result *res = parsed_result;
813 	struct rte_mtr_error error;
814 	struct rte_mtr_params params;
815 	uint32_t mtr_id = res->mtr_id;
816 	uint32_t shared = res->shared;
817 	uint32_t use_prev_meter_color = 0;
818 	uint16_t port_id = res->port_id;
819 	enum rte_color *dscp_table = NULL;
820 	char *c_str = res->meter_input_color;
821 	int ret;
822 
823 	if (port_id_is_invalid(port_id, ENABLED_WARN))
824 		return;
825 
826 	/* Meter params */
827 	memset(&params, 0, sizeof(struct rte_mtr_params));
828 	params.meter_profile_id = res->profile_id;
829 
830 	/* Parse meter input color string params */
831 	ret = parse_meter_color_str(c_str, &use_prev_meter_color, &dscp_table);
832 	if (ret) {
833 		printf(" Meter input color params string parse error\n");
834 		return;
835 	}
836 
837 	params.use_prev_mtr_color = use_prev_meter_color;
838 	params.dscp_table = dscp_table;
839 
840 	if (strcmp(res->meter_enable, "yes") == 0)
841 		params.meter_enable = 1;
842 	else
843 		params.meter_enable = 0;
844 
845 	params.action[RTE_COLOR_GREEN] =
846 		string_to_policer_action(res->g_action);
847 	params.action[RTE_COLOR_YELLOW] =
848 		string_to_policer_action(res->y_action);
849 	params.action[RTE_COLOR_RED] =
850 		string_to_policer_action(res->r_action);
851 	params.stats_mask = res->statistics_mask;
852 
853 	ret = rte_mtr_create(port_id, mtr_id, &params, shared, &error);
854 	if (ret != 0) {
855 		free(dscp_table);
856 		print_err_msg(&error);
857 		return;
858 	}
859 }
860 
861 cmdline_parse_inst_t cmd_create_port_meter = {
862 	.f = cmd_create_port_meter_parsed,
863 	.data = NULL,
864 	.help_str = "create port meter <port_id> <mtr_id> <profile_id> <meter_enable>(yes|no) "
865 		"<g_action>(R|Y|G|D) <y_action>(R|Y|G|D) <r_action>(R|Y|G|D) "
866 		"<stats_mask> <shared> <use_pre_meter_color> "
867 		"[<dscp_tbl_entry0> <dscp_tbl_entry1> ...<dscp_tbl_entry63>]",
868 	.tokens = {
869 		(void *)&cmd_create_port_meter_create,
870 		(void *)&cmd_create_port_meter_port,
871 		(void *)&cmd_create_port_meter_meter,
872 		(void *)&cmd_create_port_meter_port_id,
873 		(void *)&cmd_create_port_meter_mtr_id,
874 		(void *)&cmd_create_port_meter_profile_id,
875 		(void *)&cmd_create_port_meter_meter_enable,
876 		(void *)&cmd_create_port_meter_g_action,
877 		(void *)&cmd_create_port_meter_y_action,
878 		(void *)&cmd_create_port_meter_r_action,
879 		(void *)&cmd_create_port_meter_statistics_mask,
880 		(void *)&cmd_create_port_meter_shared,
881 		(void *)&cmd_create_port_meter_input_color,
882 		NULL,
883 	},
884 };
885 
886 /* *** Enable Meter of MTR Object  *** */
887 struct cmd_enable_port_meter_result {
888 	cmdline_fixed_string_t enable;
889 	cmdline_fixed_string_t port;
890 	cmdline_fixed_string_t meter;
891 	uint16_t port_id;
892 	uint32_t mtr_id;
893 };
894 
895 cmdline_parse_token_string_t cmd_enable_port_meter_enable =
896 	TOKEN_STRING_INITIALIZER(
897 		struct cmd_enable_port_meter_result, enable, "enable");
898 cmdline_parse_token_string_t cmd_enable_port_meter_port =
899 	TOKEN_STRING_INITIALIZER(
900 		struct cmd_enable_port_meter_result, port, "port");
901 cmdline_parse_token_string_t cmd_enable_port_meter_meter =
902 	TOKEN_STRING_INITIALIZER(
903 		struct cmd_enable_port_meter_result, meter, "meter");
904 cmdline_parse_token_num_t cmd_enable_port_meter_port_id =
905 	TOKEN_NUM_INITIALIZER(
906 		struct cmd_enable_port_meter_result, port_id, RTE_UINT16);
907 cmdline_parse_token_num_t cmd_enable_port_meter_mtr_id =
908 	TOKEN_NUM_INITIALIZER(
909 		struct cmd_enable_port_meter_result, mtr_id, RTE_UINT32);
910 
911 static void cmd_enable_port_meter_parsed(void *parsed_result,
912 	__rte_unused struct cmdline *cl,
913 	__rte_unused void *data)
914 {
915 	struct cmd_enable_port_meter_result *res = parsed_result;
916 	struct rte_mtr_error error;
917 	uint32_t mtr_id = res->mtr_id;
918 	uint16_t port_id = res->port_id;
919 
920 	int ret;
921 
922 	if (port_id_is_invalid(port_id, ENABLED_WARN))
923 		return;
924 
925 	/* Enable Meter */
926 	ret = rte_mtr_meter_enable(port_id, mtr_id, &error);
927 	if (ret != 0) {
928 		print_err_msg(&error);
929 		return;
930 	}
931 }
932 
933 cmdline_parse_inst_t cmd_enable_port_meter = {
934 	.f = cmd_enable_port_meter_parsed,
935 	.data = NULL,
936 	.help_str = "enable port meter <port_id> <mtr_id>",
937 	.tokens = {
938 		(void *)&cmd_enable_port_meter_enable,
939 		(void *)&cmd_enable_port_meter_port,
940 		(void *)&cmd_enable_port_meter_meter,
941 		(void *)&cmd_enable_port_meter_port_id,
942 		(void *)&cmd_enable_port_meter_mtr_id,
943 		NULL,
944 	},
945 };
946 
947 /* *** Disable Meter of MTR Object  *** */
948 struct cmd_disable_port_meter_result {
949 	cmdline_fixed_string_t disable;
950 	cmdline_fixed_string_t port;
951 	cmdline_fixed_string_t meter;
952 	uint16_t port_id;
953 	uint32_t mtr_id;
954 };
955 
956 cmdline_parse_token_string_t cmd_disable_port_meter_disable =
957 	TOKEN_STRING_INITIALIZER(
958 		struct cmd_disable_port_meter_result, disable, "disable");
959 cmdline_parse_token_string_t cmd_disable_port_meter_port =
960 	TOKEN_STRING_INITIALIZER(
961 		struct cmd_disable_port_meter_result, port, "port");
962 cmdline_parse_token_string_t cmd_disable_port_meter_meter =
963 	TOKEN_STRING_INITIALIZER(
964 		struct cmd_disable_port_meter_result, meter, "meter");
965 cmdline_parse_token_num_t cmd_disable_port_meter_port_id =
966 	TOKEN_NUM_INITIALIZER(
967 		struct cmd_disable_port_meter_result, port_id, RTE_UINT16);
968 cmdline_parse_token_num_t cmd_disable_port_meter_mtr_id =
969 	TOKEN_NUM_INITIALIZER(
970 		struct cmd_disable_port_meter_result, mtr_id, RTE_UINT32);
971 
972 static void cmd_disable_port_meter_parsed(void *parsed_result,
973 	__rte_unused struct cmdline *cl,
974 	__rte_unused void *data)
975 {
976 	struct cmd_disable_port_meter_result *res = parsed_result;
977 	struct rte_mtr_error error;
978 	uint32_t mtr_id = res->mtr_id;
979 	uint16_t port_id = res->port_id;
980 
981 	int ret;
982 
983 	if (port_id_is_invalid(port_id, ENABLED_WARN))
984 		return;
985 
986 	/* Disable Meter */
987 	ret = rte_mtr_meter_disable(port_id, mtr_id, &error);
988 	if (ret != 0) {
989 		print_err_msg(&error);
990 		return;
991 	}
992 }
993 
994 cmdline_parse_inst_t cmd_disable_port_meter = {
995 	.f = cmd_disable_port_meter_parsed,
996 	.data = NULL,
997 	.help_str = "disable port meter <port_id> <mtr_id>",
998 	.tokens = {
999 		(void *)&cmd_disable_port_meter_disable,
1000 		(void *)&cmd_disable_port_meter_port,
1001 		(void *)&cmd_disable_port_meter_meter,
1002 		(void *)&cmd_disable_port_meter_port_id,
1003 		(void *)&cmd_disable_port_meter_mtr_id,
1004 		NULL,
1005 	},
1006 };
1007 
1008 /* *** Delete Port Meter Object *** */
1009 struct cmd_del_port_meter_result {
1010 	cmdline_fixed_string_t del;
1011 	cmdline_fixed_string_t port;
1012 	cmdline_fixed_string_t meter;
1013 	uint16_t port_id;
1014 	uint32_t mtr_id;
1015 };
1016 
1017 cmdline_parse_token_string_t cmd_del_port_meter_del =
1018 	TOKEN_STRING_INITIALIZER(
1019 		struct cmd_del_port_meter_result, del, "del");
1020 cmdline_parse_token_string_t cmd_del_port_meter_port =
1021 	TOKEN_STRING_INITIALIZER(
1022 		struct cmd_del_port_meter_result, port, "port");
1023 cmdline_parse_token_string_t cmd_del_port_meter_meter =
1024 	TOKEN_STRING_INITIALIZER(
1025 		struct cmd_del_port_meter_result, meter, "meter");
1026 cmdline_parse_token_num_t cmd_del_port_meter_port_id =
1027 	TOKEN_NUM_INITIALIZER(
1028 		struct cmd_del_port_meter_result, port_id, RTE_UINT16);
1029 cmdline_parse_token_num_t cmd_del_port_meter_mtr_id =
1030 	TOKEN_NUM_INITIALIZER(
1031 		struct cmd_del_port_meter_result, mtr_id, RTE_UINT32);
1032 
1033 static void cmd_del_port_meter_parsed(void *parsed_result,
1034 	__rte_unused struct cmdline *cl,
1035 	__rte_unused void *data)
1036 {
1037 	struct cmd_del_port_meter_result *res = parsed_result;
1038 	struct rte_mtr_error error;
1039 	uint32_t mtr_id = res->mtr_id;
1040 	uint16_t port_id = res->port_id;
1041 
1042 	int ret;
1043 
1044 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1045 		return;
1046 
1047 	/* Destroy Meter */
1048 	ret = rte_mtr_destroy(port_id, mtr_id, &error);
1049 	if (ret != 0) {
1050 		print_err_msg(&error);
1051 		return;
1052 	}
1053 }
1054 
1055 cmdline_parse_inst_t cmd_del_port_meter = {
1056 	.f = cmd_del_port_meter_parsed,
1057 	.data = NULL,
1058 	.help_str = "del port meter <port_id> <mtr_id>",
1059 	.tokens = {
1060 		(void *)&cmd_del_port_meter_del,
1061 		(void *)&cmd_del_port_meter_port,
1062 		(void *)&cmd_del_port_meter_meter,
1063 		(void *)&cmd_del_port_meter_port_id,
1064 		(void *)&cmd_del_port_meter_mtr_id,
1065 		NULL,
1066 	},
1067 };
1068 
1069 /* *** Set Port Meter Profile *** */
1070 struct cmd_set_port_meter_profile_result {
1071 	cmdline_fixed_string_t set;
1072 	cmdline_fixed_string_t port;
1073 	cmdline_fixed_string_t meter;
1074 	cmdline_fixed_string_t profile;
1075 	uint16_t port_id;
1076 	uint32_t mtr_id;
1077 	uint32_t profile_id;
1078 };
1079 
1080 cmdline_parse_token_string_t cmd_set_port_meter_profile_set =
1081 	TOKEN_STRING_INITIALIZER(
1082 		struct cmd_set_port_meter_profile_result, set, "set");
1083 cmdline_parse_token_string_t cmd_set_port_meter_profile_port =
1084 	TOKEN_STRING_INITIALIZER(
1085 		struct cmd_set_port_meter_profile_result, port, "port");
1086 cmdline_parse_token_string_t cmd_set_port_meter_profile_meter =
1087 	TOKEN_STRING_INITIALIZER(
1088 		struct cmd_set_port_meter_profile_result, meter, "meter");
1089 cmdline_parse_token_string_t cmd_set_port_meter_profile_profile =
1090 	TOKEN_STRING_INITIALIZER(
1091 		struct cmd_set_port_meter_profile_result, profile, "profile");
1092 cmdline_parse_token_num_t cmd_set_port_meter_profile_port_id =
1093 	TOKEN_NUM_INITIALIZER(
1094 		struct cmd_set_port_meter_profile_result, port_id,
1095 		RTE_UINT16);
1096 cmdline_parse_token_num_t cmd_set_port_meter_profile_mtr_id =
1097 	TOKEN_NUM_INITIALIZER(
1098 		struct cmd_set_port_meter_profile_result, mtr_id,
1099 		RTE_UINT32);
1100 cmdline_parse_token_num_t cmd_set_port_meter_profile_profile_id =
1101 	TOKEN_NUM_INITIALIZER(
1102 		struct cmd_set_port_meter_profile_result, profile_id,
1103 		RTE_UINT32);
1104 
1105 static void cmd_set_port_meter_profile_parsed(void *parsed_result,
1106 	__rte_unused struct cmdline *cl,
1107 	__rte_unused void *data)
1108 {
1109 	struct cmd_set_port_meter_profile_result *res = parsed_result;
1110 	struct rte_mtr_error error;
1111 	uint32_t mtr_id = res->mtr_id;
1112 	uint32_t profile_id = res->profile_id;
1113 	uint16_t port_id = res->port_id;
1114 
1115 	int ret;
1116 
1117 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1118 		return;
1119 
1120 	/* Set meter profile */
1121 	ret = rte_mtr_meter_profile_update(port_id, mtr_id,
1122 		profile_id, &error);
1123 	if (ret != 0) {
1124 		print_err_msg(&error);
1125 		return;
1126 	}
1127 }
1128 
1129 cmdline_parse_inst_t cmd_set_port_meter_profile = {
1130 	.f = cmd_set_port_meter_profile_parsed,
1131 	.data = NULL,
1132 	.help_str = "set port meter profile <port_id> <mtr_id> <profile_id>",
1133 	.tokens = {
1134 		(void *)&cmd_set_port_meter_profile_set,
1135 		(void *)&cmd_set_port_meter_profile_port,
1136 		(void *)&cmd_set_port_meter_profile_meter,
1137 		(void *)&cmd_set_port_meter_profile_profile,
1138 		(void *)&cmd_set_port_meter_profile_port_id,
1139 		(void *)&cmd_set_port_meter_profile_mtr_id,
1140 		(void *)&cmd_set_port_meter_profile_profile_id,
1141 		NULL,
1142 	},
1143 };
1144 
1145 /* *** Set Port Meter DSCP Table *** */
1146 struct cmd_set_port_meter_dscp_table_result {
1147 	cmdline_fixed_string_t set;
1148 	cmdline_fixed_string_t port;
1149 	cmdline_fixed_string_t meter;
1150 	cmdline_fixed_string_t dscp_table;
1151 	cmdline_multi_string_t token_string;
1152 };
1153 
1154 cmdline_parse_token_string_t cmd_set_port_meter_dscp_table_set =
1155 	TOKEN_STRING_INITIALIZER(
1156 		struct cmd_set_port_meter_dscp_table_result, set, "set");
1157 cmdline_parse_token_string_t cmd_set_port_meter_dscp_table_port =
1158 	TOKEN_STRING_INITIALIZER(
1159 		struct cmd_set_port_meter_dscp_table_result, port, "port");
1160 cmdline_parse_token_string_t cmd_set_port_meter_dscp_table_meter =
1161 	TOKEN_STRING_INITIALIZER(
1162 		struct cmd_set_port_meter_dscp_table_result, meter, "meter");
1163 cmdline_parse_token_string_t cmd_set_port_meter_dscp_table_dscp_table =
1164 	TOKEN_STRING_INITIALIZER(
1165 		struct cmd_set_port_meter_dscp_table_result,
1166 		dscp_table, "dscp table");
1167 cmdline_parse_token_string_t cmd_set_port_meter_dscp_table_token_string =
1168 	TOKEN_STRING_INITIALIZER(struct cmd_set_port_meter_dscp_table_result,
1169 		token_string, TOKEN_STRING_MULTI);
1170 
1171 static void cmd_set_port_meter_dscp_table_parsed(void *parsed_result,
1172 	__rte_unused struct cmdline *cl,
1173 	__rte_unused void *data)
1174 {
1175 	struct cmd_set_port_meter_dscp_table_result *res = parsed_result;
1176 	struct rte_mtr_error error;
1177 	enum rte_color *dscp_table = NULL;
1178 	char *t_str = res->token_string;
1179 	uint32_t mtr_id = 0;
1180 	uint16_t port_id;
1181 	int ret;
1182 
1183 	/* Parse string */
1184 	ret = parse_multi_token_string(t_str, &port_id, &mtr_id, &dscp_table);
1185 	if (ret) {
1186 		printf(" Multi token string parse error\n");
1187 		return;
1188 	}
1189 
1190 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1191 		goto free_table;
1192 
1193 	/* Update Meter DSCP Table*/
1194 	ret = rte_mtr_meter_dscp_table_update(port_id, mtr_id,
1195 		dscp_table, &error);
1196 	if (ret != 0)
1197 		print_err_msg(&error);
1198 
1199 free_table:
1200 	free(dscp_table);
1201 }
1202 
1203 cmdline_parse_inst_t cmd_set_port_meter_dscp_table = {
1204 	.f = cmd_set_port_meter_dscp_table_parsed,
1205 	.data = NULL,
1206 	.help_str = "set port meter dscp table <port_id> <mtr_id> "
1207 		"[<dscp_tbl_entry0> <dscp_tbl_entry1> ... <dscp_tbl_entry63>]",
1208 	.tokens = {
1209 		(void *)&cmd_set_port_meter_dscp_table_set,
1210 		(void *)&cmd_set_port_meter_dscp_table_port,
1211 		(void *)&cmd_set_port_meter_dscp_table_meter,
1212 		(void *)&cmd_set_port_meter_dscp_table_dscp_table,
1213 		(void *)&cmd_set_port_meter_dscp_table_token_string,
1214 		NULL,
1215 	},
1216 };
1217 
1218 /* *** Set Port Meter Policer Action *** */
1219 struct cmd_set_port_meter_policer_action_result {
1220 	cmdline_fixed_string_t set;
1221 	cmdline_fixed_string_t port;
1222 	cmdline_fixed_string_t meter;
1223 	cmdline_fixed_string_t policer;
1224 	cmdline_fixed_string_t action;
1225 	uint16_t port_id;
1226 	uint32_t mtr_id;
1227 	uint32_t action_mask;
1228 	cmdline_multi_string_t policer_action;
1229 };
1230 
1231 cmdline_parse_token_string_t cmd_set_port_meter_policer_action_set =
1232 	TOKEN_STRING_INITIALIZER(
1233 		struct cmd_set_port_meter_policer_action_result, set, "set");
1234 cmdline_parse_token_string_t cmd_set_port_meter_policer_action_port =
1235 	TOKEN_STRING_INITIALIZER(
1236 		struct cmd_set_port_meter_policer_action_result, port, "port");
1237 cmdline_parse_token_string_t cmd_set_port_meter_policer_action_meter =
1238 	TOKEN_STRING_INITIALIZER(
1239 		struct cmd_set_port_meter_policer_action_result, meter,
1240 		"meter");
1241 cmdline_parse_token_string_t cmd_set_port_meter_policer_action_policer =
1242 	TOKEN_STRING_INITIALIZER(
1243 		struct cmd_set_port_meter_policer_action_result, policer,
1244 		"policer");
1245 cmdline_parse_token_string_t cmd_set_port_meter_policer_action_action =
1246 	TOKEN_STRING_INITIALIZER(
1247 		struct cmd_set_port_meter_policer_action_result, action,
1248 		"action");
1249 cmdline_parse_token_num_t cmd_set_port_meter_policer_action_port_id =
1250 	TOKEN_NUM_INITIALIZER(
1251 		struct cmd_set_port_meter_policer_action_result, port_id,
1252 		RTE_UINT16);
1253 cmdline_parse_token_num_t cmd_set_port_meter_policer_action_mtr_id =
1254 	TOKEN_NUM_INITIALIZER(
1255 		struct cmd_set_port_meter_policer_action_result, mtr_id,
1256 		RTE_UINT32);
1257 cmdline_parse_token_num_t cmd_set_port_meter_policer_action_action_mask =
1258 	TOKEN_NUM_INITIALIZER(
1259 		struct cmd_set_port_meter_policer_action_result, action_mask,
1260 		RTE_UINT32);
1261 cmdline_parse_token_string_t cmd_set_port_meter_policer_action_policer_action =
1262 	TOKEN_STRING_INITIALIZER(
1263 		struct cmd_set_port_meter_policer_action_result,
1264 		policer_action, TOKEN_STRING_MULTI);
1265 
1266 static void cmd_set_port_meter_policer_action_parsed(void *parsed_result,
1267 	__rte_unused struct cmdline *cl,
1268 	__rte_unused void *data)
1269 {
1270 	struct cmd_set_port_meter_policer_action_result *res = parsed_result;
1271 	enum rte_mtr_policer_action *actions;
1272 	struct rte_mtr_error error;
1273 	uint32_t mtr_id = res->mtr_id;
1274 	uint32_t action_mask = res->action_mask;
1275 	uint16_t port_id = res->port_id;
1276 	char *p_str = res->policer_action;
1277 	int ret;
1278 
1279 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1280 		return;
1281 
1282 	/* Check: action mask */
1283 	if (action_mask == 0 || (action_mask & (~0x7UL))) {
1284 		printf(" Policer action mask not correct (error)\n");
1285 		return;
1286 	}
1287 
1288 	/* Allocate memory for policer actions */
1289 	actions = (enum rte_mtr_policer_action *)malloc(RTE_COLORS *
1290 		sizeof(enum rte_mtr_policer_action));
1291 	if (actions == NULL) {
1292 		printf("Memory for policer actions not allocated (error)\n");
1293 		return;
1294 	}
1295 	/* Parse policer action string */
1296 	ret = parse_policer_action_string(p_str, action_mask, actions);
1297 	if (ret) {
1298 		printf(" Policer action string parse error\n");
1299 		free(actions);
1300 		return;
1301 	}
1302 
1303 	ret = rte_mtr_policer_actions_update(port_id, mtr_id,
1304 		action_mask, actions, &error);
1305 	if (ret != 0) {
1306 		free(actions);
1307 		print_err_msg(&error);
1308 		return;
1309 	}
1310 
1311 	free(actions);
1312 }
1313 
1314 cmdline_parse_inst_t cmd_set_port_meter_policer_action = {
1315 	.f = cmd_set_port_meter_policer_action_parsed,
1316 	.data = NULL,
1317 	.help_str = "set port meter policer action <port_id> <mtr_id> "
1318 		"<action_mask> <action0> [<action1> <action2>]",
1319 	.tokens = {
1320 		(void *)&cmd_set_port_meter_policer_action_set,
1321 		(void *)&cmd_set_port_meter_policer_action_port,
1322 		(void *)&cmd_set_port_meter_policer_action_meter,
1323 		(void *)&cmd_set_port_meter_policer_action_policer,
1324 		(void *)&cmd_set_port_meter_policer_action_action,
1325 		(void *)&cmd_set_port_meter_policer_action_port_id,
1326 		(void *)&cmd_set_port_meter_policer_action_mtr_id,
1327 		(void *)&cmd_set_port_meter_policer_action_action_mask,
1328 		(void *)&cmd_set_port_meter_policer_action_policer_action,
1329 		NULL,
1330 	},
1331 };
1332 
1333 /* *** Set Port Meter Stats Mask *** */
1334 struct cmd_set_port_meter_stats_mask_result {
1335 	cmdline_fixed_string_t set;
1336 	cmdline_fixed_string_t port;
1337 	cmdline_fixed_string_t meter;
1338 	cmdline_fixed_string_t stats;
1339 	cmdline_fixed_string_t mask;
1340 	uint16_t port_id;
1341 	uint32_t mtr_id;
1342 	uint64_t stats_mask;
1343 };
1344 
1345 cmdline_parse_token_string_t cmd_set_port_meter_stats_mask_set =
1346 	TOKEN_STRING_INITIALIZER(
1347 		struct cmd_set_port_meter_stats_mask_result, set, "set");
1348 cmdline_parse_token_string_t cmd_set_port_meter_stats_mask_port =
1349 	TOKEN_STRING_INITIALIZER(
1350 		struct cmd_set_port_meter_stats_mask_result, port, "port");
1351 cmdline_parse_token_string_t cmd_set_port_meter_stats_mask_meter =
1352 	TOKEN_STRING_INITIALIZER(
1353 		struct cmd_set_port_meter_stats_mask_result, meter, "meter");
1354 cmdline_parse_token_string_t cmd_set_port_meter_stats_mask_stats =
1355 	TOKEN_STRING_INITIALIZER(
1356 		struct cmd_set_port_meter_stats_mask_result, stats, "stats");
1357 cmdline_parse_token_string_t cmd_set_port_meter_stats_mask_mask =
1358 	TOKEN_STRING_INITIALIZER(
1359 		struct cmd_set_port_meter_stats_mask_result, mask, "mask");
1360 cmdline_parse_token_num_t cmd_set_port_meter_stats_mask_port_id =
1361 	TOKEN_NUM_INITIALIZER(
1362 		struct cmd_set_port_meter_stats_mask_result, port_id,
1363 		RTE_UINT16);
1364 cmdline_parse_token_num_t cmd_set_port_meter_stats_mask_mtr_id =
1365 	TOKEN_NUM_INITIALIZER(
1366 		struct cmd_set_port_meter_stats_mask_result, mtr_id,
1367 		RTE_UINT32);
1368 cmdline_parse_token_num_t cmd_set_port_meter_stats_mask_stats_mask =
1369 	TOKEN_NUM_INITIALIZER(
1370 		struct cmd_set_port_meter_stats_mask_result, stats_mask,
1371 		RTE_UINT64);
1372 
1373 static void cmd_set_port_meter_stats_mask_parsed(void *parsed_result,
1374 	__rte_unused struct cmdline *cl,
1375 	__rte_unused void *data)
1376 {
1377 	struct cmd_set_port_meter_stats_mask_result *res = parsed_result;
1378 	struct rte_mtr_error error;
1379 	uint64_t stats_mask = res->stats_mask;
1380 	uint32_t mtr_id = res->mtr_id;
1381 	uint16_t port_id = res->port_id;
1382 	int ret;
1383 
1384 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1385 		return;
1386 
1387 	ret = rte_mtr_stats_update(port_id, mtr_id, stats_mask, &error);
1388 	if (ret != 0) {
1389 		print_err_msg(&error);
1390 		return;
1391 	}
1392 }
1393 
1394 cmdline_parse_inst_t cmd_set_port_meter_stats_mask = {
1395 	.f = cmd_set_port_meter_stats_mask_parsed,
1396 	.data = NULL,
1397 	.help_str = "set port meter stats mask <port_id> <mtr_id> <stats_mask>",
1398 	.tokens = {
1399 		(void *)&cmd_set_port_meter_stats_mask_set,
1400 		(void *)&cmd_set_port_meter_stats_mask_port,
1401 		(void *)&cmd_set_port_meter_stats_mask_meter,
1402 		(void *)&cmd_set_port_meter_stats_mask_stats,
1403 		(void *)&cmd_set_port_meter_stats_mask_mask,
1404 		(void *)&cmd_set_port_meter_stats_mask_port_id,
1405 		(void *)&cmd_set_port_meter_stats_mask_mtr_id,
1406 		(void *)&cmd_set_port_meter_stats_mask_stats_mask,
1407 		NULL,
1408 	},
1409 };
1410 
1411 /* *** Show Port Meter Stats *** */
1412 struct cmd_show_port_meter_stats_result {
1413 	cmdline_fixed_string_t show;
1414 	cmdline_fixed_string_t port;
1415 	cmdline_fixed_string_t meter;
1416 	cmdline_fixed_string_t stats;
1417 	uint16_t port_id;
1418 	uint32_t mtr_id;
1419 	cmdline_fixed_string_t clear;
1420 };
1421 
1422 cmdline_parse_token_string_t cmd_show_port_meter_stats_show =
1423 	TOKEN_STRING_INITIALIZER(
1424 		struct cmd_show_port_meter_stats_result, show, "show");
1425 cmdline_parse_token_string_t cmd_show_port_meter_stats_port =
1426 	TOKEN_STRING_INITIALIZER(
1427 		struct cmd_show_port_meter_stats_result, port, "port");
1428 cmdline_parse_token_string_t cmd_show_port_meter_stats_meter =
1429 	TOKEN_STRING_INITIALIZER(
1430 		struct cmd_show_port_meter_stats_result, meter, "meter");
1431 cmdline_parse_token_string_t cmd_show_port_meter_stats_stats =
1432 	TOKEN_STRING_INITIALIZER(
1433 		struct cmd_show_port_meter_stats_result, stats, "stats");
1434 cmdline_parse_token_num_t cmd_show_port_meter_stats_port_id =
1435 	TOKEN_NUM_INITIALIZER(
1436 		struct cmd_show_port_meter_stats_result, port_id, RTE_UINT16);
1437 cmdline_parse_token_num_t cmd_show_port_meter_stats_mtr_id =
1438 	TOKEN_NUM_INITIALIZER(
1439 		struct cmd_show_port_meter_stats_result, mtr_id, RTE_UINT32);
1440 cmdline_parse_token_string_t cmd_show_port_meter_stats_clear =
1441 	TOKEN_STRING_INITIALIZER(
1442 		struct cmd_show_port_meter_stats_result, clear, "yes#no");
1443 
1444 static void cmd_show_port_meter_stats_parsed(void *parsed_result,
1445 	__rte_unused struct cmdline *cl,
1446 	__rte_unused void *data)
1447 {
1448 	struct cmd_show_port_meter_stats_result *res = parsed_result;
1449 	struct rte_mtr_stats stats;
1450 	uint64_t stats_mask = 0;
1451 	struct rte_mtr_error error;
1452 	uint32_t mtr_id = res->mtr_id;
1453 	uint32_t clear = 0;
1454 	uint16_t port_id = res->port_id;
1455 	int ret;
1456 
1457 	if (port_id_is_invalid(port_id, ENABLED_WARN))
1458 		return;
1459 
1460 	if (strcmp(res->clear, "yes") == 0)
1461 		clear = 1;
1462 
1463 	memset(&stats, 0, sizeof(struct rte_mtr_stats));
1464 	ret = rte_mtr_stats_read(port_id, mtr_id, &stats,
1465 		&stats_mask, clear, &error);
1466 	if (ret != 0) {
1467 		print_err_msg(&error);
1468 		return;
1469 	}
1470 
1471 	/* Display stats */
1472 	if (stats_mask & RTE_MTR_STATS_N_PKTS_GREEN)
1473 		printf("\tPkts G: %" PRIu64 "\n",
1474 			stats.n_pkts[RTE_COLOR_GREEN]);
1475 	if (stats_mask & RTE_MTR_STATS_N_BYTES_GREEN)
1476 		printf("\tBytes G: %" PRIu64 "\n",
1477 			stats.n_bytes[RTE_COLOR_GREEN]);
1478 	if (stats_mask & RTE_MTR_STATS_N_PKTS_YELLOW)
1479 		printf("\tPkts Y: %" PRIu64 "\n",
1480 			stats.n_pkts[RTE_COLOR_YELLOW]);
1481 	if (stats_mask & RTE_MTR_STATS_N_BYTES_YELLOW)
1482 		printf("\tBytes Y: %" PRIu64 "\n",
1483 			stats.n_bytes[RTE_COLOR_YELLOW]);
1484 	if (stats_mask & RTE_MTR_STATS_N_PKTS_RED)
1485 		printf("\tPkts R: %" PRIu64 "\n",
1486 			stats.n_pkts[RTE_COLOR_RED]);
1487 	if (stats_mask & RTE_MTR_STATS_N_BYTES_RED)
1488 		printf("\tBytes R: %" PRIu64 "\n",
1489 			stats.n_bytes[RTE_COLOR_RED]);
1490 	if (stats_mask & RTE_MTR_STATS_N_PKTS_DROPPED)
1491 		printf("\tPkts DROPPED: %" PRIu64 "\n",
1492 			stats.n_pkts_dropped);
1493 	if (stats_mask & RTE_MTR_STATS_N_BYTES_DROPPED)
1494 		printf("\tBytes DROPPED: %" PRIu64 "\n",
1495 			stats.n_bytes_dropped);
1496 }
1497 
1498 cmdline_parse_inst_t cmd_show_port_meter_stats = {
1499 	.f = cmd_show_port_meter_stats_parsed,
1500 	.data = NULL,
1501 	.help_str = "show port meter stats <port_id> <mtr_id> <clear>(yes|no)",
1502 	.tokens = {
1503 		(void *)&cmd_show_port_meter_stats_show,
1504 		(void *)&cmd_show_port_meter_stats_port,
1505 		(void *)&cmd_show_port_meter_stats_meter,
1506 		(void *)&cmd_show_port_meter_stats_stats,
1507 		(void *)&cmd_show_port_meter_stats_port_id,
1508 		(void *)&cmd_show_port_meter_stats_mtr_id,
1509 		(void *)&cmd_show_port_meter_stats_clear,
1510 		NULL,
1511 	},
1512 };
1513