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