xref: /dpdk/app/test-pmd/bpf_cmd.c (revision 34890bfa6e11bae143064825c22755d842531e40)
1e977e419SKonstantin Ananyev /* SPDX-License-Identifier: BSD-3-Clause
2e977e419SKonstantin Ananyev  * Copyright(c) 2018 Intel Corporation
3e977e419SKonstantin Ananyev  */
4e977e419SKonstantin Ananyev 
572b452c5SDmitry Kozlyuk #include <ctype.h>
6e977e419SKonstantin Ananyev #include <stdio.h>
772b452c5SDmitry Kozlyuk 
8e977e419SKonstantin Ananyev #include <rte_mbuf.h>
9e977e419SKonstantin Ananyev #include <rte_ethdev.h>
10e977e419SKonstantin Ananyev #include <rte_flow.h>
11e977e419SKonstantin Ananyev #include <rte_bpf_ethdev.h>
12e977e419SKonstantin Ananyev 
13e977e419SKonstantin Ananyev #include <cmdline.h>
14e977e419SKonstantin Ananyev #include <cmdline_parse.h>
15e977e419SKonstantin Ananyev #include <cmdline_parse_num.h>
16e977e419SKonstantin Ananyev #include <cmdline_parse_string.h>
17e977e419SKonstantin Ananyev 
18e977e419SKonstantin Ananyev #include "testpmd.h"
19e977e419SKonstantin Ananyev 
20e977e419SKonstantin Ananyev static const struct rte_bpf_xsym bpf_xsym[] = {
21e977e419SKonstantin Ananyev 	{
22e977e419SKonstantin Ananyev 		.name = RTE_STR(stdout),
23e977e419SKonstantin Ananyev 		.type = RTE_BPF_XTYPE_VAR,
2460702e8cSKonstantin Ananyev 		.var = {
253529e8f3SNatanael Copa 			.val = (void *)(uintptr_t)&stdout,
2660702e8cSKonstantin Ananyev 			.desc = {
2760702e8cSKonstantin Ananyev 				.type = RTE_BPF_ARG_PTR,
2860702e8cSKonstantin Ananyev 				.size = sizeof(stdout),
2960702e8cSKonstantin Ananyev 			},
3060702e8cSKonstantin Ananyev 		},
31e977e419SKonstantin Ananyev 	},
32e977e419SKonstantin Ananyev 	{
33e977e419SKonstantin Ananyev 		.name = RTE_STR(rte_pktmbuf_dump),
34e977e419SKonstantin Ananyev 		.type = RTE_BPF_XTYPE_FUNC,
3560702e8cSKonstantin Ananyev 		.func = {
3660702e8cSKonstantin Ananyev 			.val = (void *)rte_pktmbuf_dump,
3760702e8cSKonstantin Ananyev 			.nb_args = 3,
3860702e8cSKonstantin Ananyev 			.args = {
3960702e8cSKonstantin Ananyev 				[0] = {
4060702e8cSKonstantin Ananyev 					.type = RTE_BPF_ARG_RAW,
4160702e8cSKonstantin Ananyev 					.size = sizeof(uintptr_t),
4260702e8cSKonstantin Ananyev 				},
4360702e8cSKonstantin Ananyev 				[1] = {
4460702e8cSKonstantin Ananyev 					.type = RTE_BPF_ARG_PTR_MBUF,
4560702e8cSKonstantin Ananyev 					.size = sizeof(struct rte_mbuf),
4660702e8cSKonstantin Ananyev 				},
4760702e8cSKonstantin Ananyev 				[2] = {
4860702e8cSKonstantin Ananyev 					.type = RTE_BPF_ARG_RAW,
4960702e8cSKonstantin Ananyev 					.size = sizeof(uint32_t),
5060702e8cSKonstantin Ananyev 				},
5160702e8cSKonstantin Ananyev 			},
5260702e8cSKonstantin Ananyev 		},
53e977e419SKonstantin Ananyev 	},
54e977e419SKonstantin Ananyev };
55e977e419SKonstantin Ananyev 
56e977e419SKonstantin Ananyev /* *** load BPF program *** */
57e977e419SKonstantin Ananyev struct cmd_bpf_ld_result {
58e977e419SKonstantin Ananyev 	cmdline_fixed_string_t bpf;
59e977e419SKonstantin Ananyev 	cmdline_fixed_string_t dir;
609b539662SChenbo Xia 	uint16_t port;
61e977e419SKonstantin Ananyev 	uint16_t queue;
62e977e419SKonstantin Ananyev 	cmdline_fixed_string_t op;
63e977e419SKonstantin Ananyev 	cmdline_fixed_string_t flags;
64e977e419SKonstantin Ananyev 	cmdline_fixed_string_t prm;
65e977e419SKonstantin Ananyev };
66e977e419SKonstantin Ananyev 
67e977e419SKonstantin Ananyev static void
bpf_parse_flags(const char * str,struct rte_bpf_arg * arg,uint32_t * flags)68e977e419SKonstantin Ananyev bpf_parse_flags(const char *str, struct rte_bpf_arg *arg, uint32_t *flags)
69e977e419SKonstantin Ananyev {
70e977e419SKonstantin Ananyev 	uint32_t i, v;
71e977e419SKonstantin Ananyev 
72e977e419SKonstantin Ananyev 	*flags = RTE_BPF_ETH_F_NONE;
73e977e419SKonstantin Ananyev 	arg->type = RTE_BPF_ARG_PTR;
7426cbb419SViacheslav Ovsiienko 	arg->size = mbuf_data_size[0];
75e977e419SKonstantin Ananyev 
76e977e419SKonstantin Ananyev 	for (i = 0; str[i] != 0; i++) {
77e977e419SKonstantin Ananyev 		v = toupper(str[i]);
78e977e419SKonstantin Ananyev 		if (v == 'J')
79e977e419SKonstantin Ananyev 			*flags |= RTE_BPF_ETH_F_JIT;
80e977e419SKonstantin Ananyev 		else if (v == 'M') {
81e977e419SKonstantin Ananyev 			arg->type = RTE_BPF_ARG_PTR_MBUF;
82e977e419SKonstantin Ananyev 			arg->size = sizeof(struct rte_mbuf);
8326cbb419SViacheslav Ovsiienko 			arg->buf_size = mbuf_data_size[0];
84e977e419SKonstantin Ananyev 		} else if (v == '-')
85e977e419SKonstantin Ananyev 			continue;
86e977e419SKonstantin Ananyev 		else
8761a3b0e5SAndrew Rybchenko 			fprintf(stderr, "unknown flag: \'%c\'", v);
88e977e419SKonstantin Ananyev 	}
89e977e419SKonstantin Ananyev }
90e977e419SKonstantin Ananyev 
cmd_operate_bpf_ld_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)91e977e419SKonstantin Ananyev static void cmd_operate_bpf_ld_parsed(void *parsed_result,
92f2fc83b4SThomas Monjalon 				__rte_unused struct cmdline *cl,
93f2fc83b4SThomas Monjalon 				__rte_unused void *data)
94e977e419SKonstantin Ananyev {
95e977e419SKonstantin Ananyev 	int32_t rc;
96e977e419SKonstantin Ananyev 	uint32_t flags;
97e977e419SKonstantin Ananyev 	struct cmd_bpf_ld_result *res;
98e977e419SKonstantin Ananyev 	struct rte_bpf_prm prm;
99e977e419SKonstantin Ananyev 	const char *fname, *sname;
100e977e419SKonstantin Ananyev 
101e977e419SKonstantin Ananyev 	res = parsed_result;
102e977e419SKonstantin Ananyev 	memset(&prm, 0, sizeof(prm));
103e977e419SKonstantin Ananyev 	prm.xsym = bpf_xsym;
104e977e419SKonstantin Ananyev 	prm.nb_xsym = RTE_DIM(bpf_xsym);
105e977e419SKonstantin Ananyev 
106e977e419SKonstantin Ananyev 	bpf_parse_flags(res->flags, &prm.prog_arg, &flags);
107e977e419SKonstantin Ananyev 	fname = res->prm;
108e977e419SKonstantin Ananyev 	sname = ".text";
109e977e419SKonstantin Ananyev 
110e977e419SKonstantin Ananyev 	if (strcmp(res->dir, "rx") == 0) {
111e977e419SKonstantin Ananyev 		rc = rte_bpf_eth_rx_elf_load(res->port, res->queue, &prm,
112e977e419SKonstantin Ananyev 			fname, sname, flags);
113e977e419SKonstantin Ananyev 		printf("%d:%s\n", rc, strerror(-rc));
114e977e419SKonstantin Ananyev 	} else if (strcmp(res->dir, "tx") == 0) {
115e977e419SKonstantin Ananyev 		rc = rte_bpf_eth_tx_elf_load(res->port, res->queue, &prm,
116e977e419SKonstantin Ananyev 			fname, sname, flags);
117e977e419SKonstantin Ananyev 		printf("%d:%s\n", rc, strerror(-rc));
118e977e419SKonstantin Ananyev 	} else
11961a3b0e5SAndrew Rybchenko 		fprintf(stderr, "invalid value: %s\n", res->dir);
120e977e419SKonstantin Ananyev }
121e977e419SKonstantin Ananyev 
122ea0774ffSDavid Marchand static cmdline_parse_token_string_t cmd_load_bpf_start =
123e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
124e977e419SKonstantin Ananyev 			bpf, "bpf-load");
125ea0774ffSDavid Marchand static cmdline_parse_token_string_t cmd_load_bpf_dir =
126e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
127e977e419SKonstantin Ananyev 			dir, "rx#tx");
128ea0774ffSDavid Marchand static cmdline_parse_token_num_t cmd_load_bpf_port =
129c2341bb6SDmitry Kozlyuk 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, port, RTE_UINT8);
130ea0774ffSDavid Marchand static cmdline_parse_token_num_t cmd_load_bpf_queue =
131c2341bb6SDmitry Kozlyuk 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, queue, RTE_UINT16);
132ea0774ffSDavid Marchand static cmdline_parse_token_string_t cmd_load_bpf_flags =
133e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
134e977e419SKonstantin Ananyev 			flags, NULL);
135ea0774ffSDavid Marchand static cmdline_parse_token_string_t cmd_load_bpf_prm =
136e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
137e977e419SKonstantin Ananyev 			prm, NULL);
138e977e419SKonstantin Ananyev 
139e977e419SKonstantin Ananyev cmdline_parse_inst_t cmd_operate_bpf_ld_parse = {
140e977e419SKonstantin Ananyev 	.f = cmd_operate_bpf_ld_parsed,
141e977e419SKonstantin Ananyev 	.data = NULL,
142*34890bfaSChaoyong He 	.help_str = "bpf-load rx|tx <port> <queue> <J|M|-> <file_name>",
143e977e419SKonstantin Ananyev 	.tokens = {
144e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_start,
145e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_dir,
146e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_port,
147e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_queue,
148e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_flags,
149e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_prm,
150e977e419SKonstantin Ananyev 		NULL,
151e977e419SKonstantin Ananyev 	},
152e977e419SKonstantin Ananyev };
153e977e419SKonstantin Ananyev 
154e977e419SKonstantin Ananyev /* *** unload BPF program *** */
155e977e419SKonstantin Ananyev struct cmd_bpf_unld_result {
156e977e419SKonstantin Ananyev 	cmdline_fixed_string_t bpf;
157e977e419SKonstantin Ananyev 	cmdline_fixed_string_t dir;
1589b539662SChenbo Xia 	uint16_t port;
159e977e419SKonstantin Ananyev 	uint16_t queue;
160e977e419SKonstantin Ananyev };
161e977e419SKonstantin Ananyev 
cmd_operate_bpf_unld_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)162e977e419SKonstantin Ananyev static void cmd_operate_bpf_unld_parsed(void *parsed_result,
163f2fc83b4SThomas Monjalon 				__rte_unused struct cmdline *cl,
164f2fc83b4SThomas Monjalon 				__rte_unused void *data)
165e977e419SKonstantin Ananyev {
166e977e419SKonstantin Ananyev 	struct cmd_bpf_unld_result *res;
167e977e419SKonstantin Ananyev 
168e977e419SKonstantin Ananyev 	res = parsed_result;
169e977e419SKonstantin Ananyev 
170e977e419SKonstantin Ananyev 	if (strcmp(res->dir, "rx") == 0)
171e977e419SKonstantin Ananyev 		rte_bpf_eth_rx_unload(res->port, res->queue);
172e977e419SKonstantin Ananyev 	else if (strcmp(res->dir, "tx") == 0)
173e977e419SKonstantin Ananyev 		rte_bpf_eth_tx_unload(res->port, res->queue);
174e977e419SKonstantin Ananyev 	else
17561a3b0e5SAndrew Rybchenko 		fprintf(stderr, "invalid value: %s\n", res->dir);
176e977e419SKonstantin Ananyev }
177e977e419SKonstantin Ananyev 
178ea0774ffSDavid Marchand static cmdline_parse_token_string_t cmd_unload_bpf_start =
179e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result,
180e977e419SKonstantin Ananyev 			bpf, "bpf-unload");
181ea0774ffSDavid Marchand static cmdline_parse_token_string_t cmd_unload_bpf_dir =
182e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result,
183e977e419SKonstantin Ananyev 			dir, "rx#tx");
184ea0774ffSDavid Marchand static cmdline_parse_token_num_t cmd_unload_bpf_port =
185c2341bb6SDmitry Kozlyuk 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, port, RTE_UINT8);
186ea0774ffSDavid Marchand static cmdline_parse_token_num_t cmd_unload_bpf_queue =
187c2341bb6SDmitry Kozlyuk 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, queue, RTE_UINT16);
188e977e419SKonstantin Ananyev 
189e977e419SKonstantin Ananyev cmdline_parse_inst_t cmd_operate_bpf_unld_parse = {
190e977e419SKonstantin Ananyev 	.f = cmd_operate_bpf_unld_parsed,
191e977e419SKonstantin Ananyev 	.data = NULL,
192e977e419SKonstantin Ananyev 	.help_str = "bpf-unload rx|tx <port> <queue>",
193e977e419SKonstantin Ananyev 	.tokens = {
194e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_start,
195e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_dir,
196e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_port,
197e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_queue,
198e977e419SKonstantin Ananyev 		NULL,
199e977e419SKonstantin Ananyev 	},
200e977e419SKonstantin Ananyev };
201