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