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