xref: /dpdk/app/test-pmd/bpf_cmd.c (revision e977e4199a8d6bab72cf94e154adcad1fb964e5e)
1*e977e419SKonstantin Ananyev /* SPDX-License-Identifier: BSD-3-Clause
2*e977e419SKonstantin Ananyev  * Copyright(c) 2018 Intel Corporation
3*e977e419SKonstantin Ananyev  */
4*e977e419SKonstantin Ananyev 
5*e977e419SKonstantin Ananyev #include <stdio.h>
6*e977e419SKonstantin Ananyev #include <rte_mbuf.h>
7*e977e419SKonstantin Ananyev #include <rte_ethdev.h>
8*e977e419SKonstantin Ananyev #include <rte_flow.h>
9*e977e419SKonstantin Ananyev #include <rte_bpf_ethdev.h>
10*e977e419SKonstantin Ananyev 
11*e977e419SKonstantin Ananyev #include <cmdline.h>
12*e977e419SKonstantin Ananyev #include <cmdline_parse.h>
13*e977e419SKonstantin Ananyev #include <cmdline_parse_num.h>
14*e977e419SKonstantin Ananyev #include <cmdline_parse_string.h>
15*e977e419SKonstantin Ananyev 
16*e977e419SKonstantin Ananyev #include "testpmd.h"
17*e977e419SKonstantin Ananyev 
18*e977e419SKonstantin Ananyev static const struct rte_bpf_xsym bpf_xsym[] = {
19*e977e419SKonstantin Ananyev 	{
20*e977e419SKonstantin Ananyev 		.name = RTE_STR(stdout),
21*e977e419SKonstantin Ananyev 		.type = RTE_BPF_XTYPE_VAR,
22*e977e419SKonstantin Ananyev 		.var = &stdout,
23*e977e419SKonstantin Ananyev 	},
24*e977e419SKonstantin Ananyev 	{
25*e977e419SKonstantin Ananyev 		.name = RTE_STR(rte_pktmbuf_dump),
26*e977e419SKonstantin Ananyev 		.type = RTE_BPF_XTYPE_FUNC,
27*e977e419SKonstantin Ananyev 		.func = (void *)rte_pktmbuf_dump,
28*e977e419SKonstantin Ananyev 	},
29*e977e419SKonstantin Ananyev };
30*e977e419SKonstantin Ananyev 
31*e977e419SKonstantin Ananyev /* *** load BPF program *** */
32*e977e419SKonstantin Ananyev struct cmd_bpf_ld_result {
33*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t bpf;
34*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t dir;
35*e977e419SKonstantin Ananyev 	uint8_t port;
36*e977e419SKonstantin Ananyev 	uint16_t queue;
37*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t op;
38*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t flags;
39*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t prm;
40*e977e419SKonstantin Ananyev };
41*e977e419SKonstantin Ananyev 
42*e977e419SKonstantin Ananyev static void
43*e977e419SKonstantin Ananyev bpf_parse_flags(const char *str, struct rte_bpf_arg *arg, uint32_t *flags)
44*e977e419SKonstantin Ananyev {
45*e977e419SKonstantin Ananyev 	uint32_t i, v;
46*e977e419SKonstantin Ananyev 
47*e977e419SKonstantin Ananyev 	*flags = RTE_BPF_ETH_F_NONE;
48*e977e419SKonstantin Ananyev 	arg->type = RTE_BPF_ARG_PTR;
49*e977e419SKonstantin Ananyev 	arg->size = mbuf_data_size;
50*e977e419SKonstantin Ananyev 
51*e977e419SKonstantin Ananyev 	for (i = 0; str[i] != 0; i++) {
52*e977e419SKonstantin Ananyev 		v = toupper(str[i]);
53*e977e419SKonstantin Ananyev 		if (v == 'J')
54*e977e419SKonstantin Ananyev 			*flags |= RTE_BPF_ETH_F_JIT;
55*e977e419SKonstantin Ananyev 		else if (v == 'M') {
56*e977e419SKonstantin Ananyev 			arg->type = RTE_BPF_ARG_PTR_MBUF;
57*e977e419SKonstantin Ananyev 			arg->size = sizeof(struct rte_mbuf);
58*e977e419SKonstantin Ananyev 			arg->buf_size = mbuf_data_size;
59*e977e419SKonstantin Ananyev 		} else if (v == '-')
60*e977e419SKonstantin Ananyev 			continue;
61*e977e419SKonstantin Ananyev 		else
62*e977e419SKonstantin Ananyev 			printf("unknown flag: \'%c\'", v);
63*e977e419SKonstantin Ananyev 	}
64*e977e419SKonstantin Ananyev }
65*e977e419SKonstantin Ananyev 
66*e977e419SKonstantin Ananyev static void cmd_operate_bpf_ld_parsed(void *parsed_result,
67*e977e419SKonstantin Ananyev 				__attribute__((unused)) struct cmdline *cl,
68*e977e419SKonstantin Ananyev 				__attribute__((unused)) void *data)
69*e977e419SKonstantin Ananyev {
70*e977e419SKonstantin Ananyev 	int32_t rc;
71*e977e419SKonstantin Ananyev 	uint32_t flags;
72*e977e419SKonstantin Ananyev 	struct cmd_bpf_ld_result *res;
73*e977e419SKonstantin Ananyev 	struct rte_bpf_prm prm;
74*e977e419SKonstantin Ananyev 	const char *fname, *sname;
75*e977e419SKonstantin Ananyev 
76*e977e419SKonstantin Ananyev 	res = parsed_result;
77*e977e419SKonstantin Ananyev 	memset(&prm, 0, sizeof(prm));
78*e977e419SKonstantin Ananyev 	prm.xsym = bpf_xsym;
79*e977e419SKonstantin Ananyev 	prm.nb_xsym = RTE_DIM(bpf_xsym);
80*e977e419SKonstantin Ananyev 
81*e977e419SKonstantin Ananyev 	bpf_parse_flags(res->flags, &prm.prog_arg, &flags);
82*e977e419SKonstantin Ananyev 	fname = res->prm;
83*e977e419SKonstantin Ananyev 	sname = ".text";
84*e977e419SKonstantin Ananyev 
85*e977e419SKonstantin Ananyev 	if (strcmp(res->dir, "rx") == 0) {
86*e977e419SKonstantin Ananyev 		rc = rte_bpf_eth_rx_elf_load(res->port, res->queue, &prm,
87*e977e419SKonstantin Ananyev 			fname, sname, flags);
88*e977e419SKonstantin Ananyev 		printf("%d:%s\n", rc, strerror(-rc));
89*e977e419SKonstantin Ananyev 	} else if (strcmp(res->dir, "tx") == 0) {
90*e977e419SKonstantin Ananyev 		rc = rte_bpf_eth_tx_elf_load(res->port, res->queue, &prm,
91*e977e419SKonstantin Ananyev 			fname, sname, flags);
92*e977e419SKonstantin Ananyev 		printf("%d:%s\n", rc, strerror(-rc));
93*e977e419SKonstantin Ananyev 	} else
94*e977e419SKonstantin Ananyev 		printf("invalid value: %s\n", res->dir);
95*e977e419SKonstantin Ananyev }
96*e977e419SKonstantin Ananyev 
97*e977e419SKonstantin Ananyev cmdline_parse_token_string_t cmd_load_bpf_start =
98*e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
99*e977e419SKonstantin Ananyev 			bpf, "bpf-load");
100*e977e419SKonstantin Ananyev cmdline_parse_token_string_t cmd_load_bpf_dir =
101*e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
102*e977e419SKonstantin Ananyev 			dir, "rx#tx");
103*e977e419SKonstantin Ananyev cmdline_parse_token_num_t cmd_load_bpf_port =
104*e977e419SKonstantin Ananyev 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, port, UINT8);
105*e977e419SKonstantin Ananyev cmdline_parse_token_num_t cmd_load_bpf_queue =
106*e977e419SKonstantin Ananyev 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, queue, UINT16);
107*e977e419SKonstantin Ananyev cmdline_parse_token_string_t cmd_load_bpf_flags =
108*e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
109*e977e419SKonstantin Ananyev 			flags, NULL);
110*e977e419SKonstantin Ananyev cmdline_parse_token_string_t cmd_load_bpf_prm =
111*e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
112*e977e419SKonstantin Ananyev 			prm, NULL);
113*e977e419SKonstantin Ananyev 
114*e977e419SKonstantin Ananyev cmdline_parse_inst_t cmd_operate_bpf_ld_parse = {
115*e977e419SKonstantin Ananyev 	.f = cmd_operate_bpf_ld_parsed,
116*e977e419SKonstantin Ananyev 	.data = NULL,
117*e977e419SKonstantin Ananyev 	.help_str = "bpf-load rx|tx <port> <queue> <J|M|B> <file_name>",
118*e977e419SKonstantin Ananyev 	.tokens = {
119*e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_start,
120*e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_dir,
121*e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_port,
122*e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_queue,
123*e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_flags,
124*e977e419SKonstantin Ananyev 		(void *)&cmd_load_bpf_prm,
125*e977e419SKonstantin Ananyev 		NULL,
126*e977e419SKonstantin Ananyev 	},
127*e977e419SKonstantin Ananyev };
128*e977e419SKonstantin Ananyev 
129*e977e419SKonstantin Ananyev /* *** unload BPF program *** */
130*e977e419SKonstantin Ananyev struct cmd_bpf_unld_result {
131*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t bpf;
132*e977e419SKonstantin Ananyev 	cmdline_fixed_string_t dir;
133*e977e419SKonstantin Ananyev 	uint8_t port;
134*e977e419SKonstantin Ananyev 	uint16_t queue;
135*e977e419SKonstantin Ananyev };
136*e977e419SKonstantin Ananyev 
137*e977e419SKonstantin Ananyev static void cmd_operate_bpf_unld_parsed(void *parsed_result,
138*e977e419SKonstantin Ananyev 				__attribute__((unused)) struct cmdline *cl,
139*e977e419SKonstantin Ananyev 				__attribute__((unused)) void *data)
140*e977e419SKonstantin Ananyev {
141*e977e419SKonstantin Ananyev 	struct cmd_bpf_unld_result *res;
142*e977e419SKonstantin Ananyev 
143*e977e419SKonstantin Ananyev 	res = parsed_result;
144*e977e419SKonstantin Ananyev 
145*e977e419SKonstantin Ananyev 	if (strcmp(res->dir, "rx") == 0)
146*e977e419SKonstantin Ananyev 		rte_bpf_eth_rx_unload(res->port, res->queue);
147*e977e419SKonstantin Ananyev 	else if (strcmp(res->dir, "tx") == 0)
148*e977e419SKonstantin Ananyev 		rte_bpf_eth_tx_unload(res->port, res->queue);
149*e977e419SKonstantin Ananyev 	else
150*e977e419SKonstantin Ananyev 		printf("invalid value: %s\n", res->dir);
151*e977e419SKonstantin Ananyev }
152*e977e419SKonstantin Ananyev 
153*e977e419SKonstantin Ananyev cmdline_parse_token_string_t cmd_unload_bpf_start =
154*e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result,
155*e977e419SKonstantin Ananyev 			bpf, "bpf-unload");
156*e977e419SKonstantin Ananyev cmdline_parse_token_string_t cmd_unload_bpf_dir =
157*e977e419SKonstantin Ananyev 	TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result,
158*e977e419SKonstantin Ananyev 			dir, "rx#tx");
159*e977e419SKonstantin Ananyev cmdline_parse_token_num_t cmd_unload_bpf_port =
160*e977e419SKonstantin Ananyev 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, port, UINT8);
161*e977e419SKonstantin Ananyev cmdline_parse_token_num_t cmd_unload_bpf_queue =
162*e977e419SKonstantin Ananyev 	TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, queue, UINT16);
163*e977e419SKonstantin Ananyev 
164*e977e419SKonstantin Ananyev cmdline_parse_inst_t cmd_operate_bpf_unld_parse = {
165*e977e419SKonstantin Ananyev 	.f = cmd_operate_bpf_unld_parsed,
166*e977e419SKonstantin Ananyev 	.data = NULL,
167*e977e419SKonstantin Ananyev 	.help_str = "bpf-unload rx|tx <port> <queue>",
168*e977e419SKonstantin Ananyev 	.tokens = {
169*e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_start,
170*e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_dir,
171*e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_port,
172*e977e419SKonstantin Ananyev 		(void *)&cmd_unload_bpf_queue,
173*e977e419SKonstantin Ananyev 		NULL,
174*e977e419SKonstantin Ananyev 	},
175*e977e419SKonstantin Ananyev };
176