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