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