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