dpdk/app/test-pmd/bpf_cmd.c
<<
>>
Prefs
   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
  18static 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 *** */
  55struct 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
  65static void
  66bpf_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
  89static 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
 120cmdline_parse_token_string_t cmd_load_bpf_start =
 121        TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
 122                        bpf, "bpf-load");
 123cmdline_parse_token_string_t cmd_load_bpf_dir =
 124        TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
 125                        dir, "rx#tx");
 126cmdline_parse_token_num_t cmd_load_bpf_port =
 127        TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, port, RTE_UINT8);
 128cmdline_parse_token_num_t cmd_load_bpf_queue =
 129        TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, queue, RTE_UINT16);
 130cmdline_parse_token_string_t cmd_load_bpf_flags =
 131        TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
 132                        flags, NULL);
 133cmdline_parse_token_string_t cmd_load_bpf_prm =
 134        TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result,
 135                        prm, NULL);
 136
 137cmdline_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 *** */
 153struct 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
 160static 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
 176cmdline_parse_token_string_t cmd_unload_bpf_start =
 177        TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result,
 178                        bpf, "bpf-unload");
 179cmdline_parse_token_string_t cmd_unload_bpf_dir =
 180        TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result,
 181                        dir, "rx#tx");
 182cmdline_parse_token_num_t cmd_unload_bpf_port =
 183        TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, port, RTE_UINT8);
 184cmdline_parse_token_num_t cmd_unload_bpf_queue =
 185        TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, queue, RTE_UINT16);
 186
 187cmdline_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