From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 736414F9C for ; Fri, 30 Mar 2018 19:33:06 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Mar 2018 10:33:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,382,1517904000"; d="scan'208";a="46664538" Received: from sivswdev02.ir.intel.com (HELO localhost.localdomain) ([10.237.217.46]) by orsmga002.jf.intel.com with ESMTP; 30 Mar 2018 10:33:04 -0700 From: Konstantin Ananyev To: dev@dpdk.org Cc: Konstantin Ananyev Date: Fri, 30 Mar 2018 18:32:42 +0100 Message-Id: <1522431163-25621-7-git-send-email-konstantin.ananyev@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1520613725-9176-1-git-send-email-konstantin.ananyev@intel.com> References: <1520613725-9176-1-git-send-email-konstantin.ananyev@intel.com> Subject: [dpdk-dev] [PATCH v2 6/7] testpmd: new commands to load/unload BPF filters X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Mar 2018 17:33:06 -0000 Introduce new testpmd commands to load/unload RX/TX BPF-based filters. Signed-off-by: Konstantin Ananyev --- app/test-pmd/bpf_sup.h | 25 ++++++++ app/test-pmd/cmdline.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/meson.build | 2 +- 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 app/test-pmd/bpf_sup.h diff --git a/app/test-pmd/bpf_sup.h b/app/test-pmd/bpf_sup.h new file mode 100644 index 000000000..35f91a07f --- /dev/null +++ b/app/test-pmd/bpf_sup.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _BPF_SUP_H_ +#define _BPF_SUP_H_ + +#include +#include +#include + +static const struct rte_bpf_xsym bpf_xsym[] = { + { + .name = RTE_STR(stdout), + .type = RTE_BPF_XTYPE_VAR, + .var = &stdout, + }, + { + .name = RTE_STR(rte_pktmbuf_dump), + .type = RTE_BPF_XTYPE_FUNC, + .func = (void *)rte_pktmbuf_dump, + }, +}; + +#endif /* _BPF_SUP_H_ */ diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 40b31ad7e..d0ad27871 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -75,6 +75,7 @@ #include "testpmd.h" #include "cmdline_mtr.h" #include "cmdline_tm.h" +#include "bpf_sup.h" static struct cmdline *testpmd_cl; @@ -16030,6 +16031,149 @@ cmdline_parse_inst_t cmd_load_from_file = { }, }; +/* *** load BPF program *** */ +struct cmd_bpf_ld_result { + cmdline_fixed_string_t bpf; + cmdline_fixed_string_t dir; + uint8_t port; + uint16_t queue; + cmdline_fixed_string_t op; + cmdline_fixed_string_t flags; + cmdline_fixed_string_t prm; +}; + +static void +bpf_parse_flags(const char *str, enum rte_bpf_prog_type *ptype, uint32_t *flags) +{ + uint32_t i, v; + + *flags = RTE_BPF_ETH_F_NONE; + *ptype = RTE_BPF_PROG_TYPE_UNSPEC; + + for (i = 0; str[i] != 0; i++) { + v = toupper(str[i]); + if (v == 'J') + *flags |= RTE_BPF_ETH_F_JIT; + else if (v == 'M') + *ptype = RTE_BPF_PROG_TYPE_MBUF; + else if (v == '-') + continue; + else + printf("unknown flag: \'%c\'", v); + } +} + +static void cmd_operate_bpf_ld_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + int32_t rc; + uint32_t flags; + struct cmd_bpf_ld_result *res; + struct rte_bpf_prm prm; + const char *fname, *sname; + + res = parsed_result; + memset(&prm, 0, sizeof(prm)); + prm.xsym = bpf_xsym; + prm.nb_xsym = RTE_DIM(bpf_xsym); + + bpf_parse_flags(res->flags, &prm.prog_type, &flags); + fname = res->prm; + sname = ".text"; + + if (strcmp(res->dir, "rx") == 0) { + rc = rte_bpf_eth_rx_elf_load(res->port, res->queue, &prm, + fname, sname, flags); + printf("%d:%s\n", rc, strerror(-rc)); + } else if (strcmp(res->dir, "tx") == 0) { + rc = rte_bpf_eth_tx_elf_load(res->port, res->queue, &prm, + fname, sname, flags); + printf("%d:%s\n", rc, strerror(-rc)); + } else + printf("invalid value: %s\n", res->dir); +} + +cmdline_parse_token_string_t cmd_load_bpf_start = + TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result, + bpf, "bpf-load"); +cmdline_parse_token_string_t cmd_load_bpf_dir = + TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result, + dir, "rx#tx"); +cmdline_parse_token_num_t cmd_load_bpf_port = + TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, port, UINT8); +cmdline_parse_token_num_t cmd_load_bpf_queue = + TOKEN_NUM_INITIALIZER(struct cmd_bpf_ld_result, queue, UINT16); +cmdline_parse_token_string_t cmd_load_bpf_flags = + TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result, + flags, NULL); +cmdline_parse_token_string_t cmd_load_bpf_prm = + TOKEN_STRING_INITIALIZER(struct cmd_bpf_ld_result, + prm, NULL); + +cmdline_parse_inst_t cmd_operate_bpf_ld_parse = { + .f = cmd_operate_bpf_ld_parsed, + .data = NULL, + .help_str = "bpf-load rx|tx ", + .tokens = { + (void *)&cmd_load_bpf_start, + (void *)&cmd_load_bpf_dir, + (void *)&cmd_load_bpf_port, + (void *)&cmd_load_bpf_queue, + (void *)&cmd_load_bpf_flags, + (void *)&cmd_load_bpf_prm, + NULL, + }, +}; + +/* *** unload BPF program *** */ +struct cmd_bpf_unld_result { + cmdline_fixed_string_t bpf; + cmdline_fixed_string_t dir; + uint8_t port; + uint16_t queue; +}; + +static void cmd_operate_bpf_unld_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_bpf_unld_result *res; + + res = parsed_result; + + if (strcmp(res->dir, "rx") == 0) + rte_bpf_eth_rx_unload(res->port, res->queue); + else if (strcmp(res->dir, "tx") == 0) + rte_bpf_eth_tx_unload(res->port, res->queue); + else + printf("invalid value: %s\n", res->dir); +} + +cmdline_parse_token_string_t cmd_unload_bpf_start = + TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result, + bpf, "bpf-unload"); +cmdline_parse_token_string_t cmd_unload_bpf_dir = + TOKEN_STRING_INITIALIZER(struct cmd_bpf_unld_result, + dir, "rx#tx"); +cmdline_parse_token_num_t cmd_unload_bpf_port = + TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, port, UINT8); +cmdline_parse_token_num_t cmd_unload_bpf_queue = + TOKEN_NUM_INITIALIZER(struct cmd_bpf_unld_result, queue, UINT16); + +cmdline_parse_inst_t cmd_operate_bpf_unld_parse = { + .f = cmd_operate_bpf_unld_parsed, + .data = NULL, + .help_str = "bpf-unload rx|tx ", + .tokens = { + (void *)&cmd_unload_bpf_start, + (void *)&cmd_unload_bpf_dir, + (void *)&cmd_unload_bpf_port, + (void *)&cmd_unload_bpf_queue, + NULL, + }, +}; + /* ******************************************************************************** */ /* list of instructions */ @@ -16272,6 +16416,8 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_del_port_tm_node, (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent, (cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit, + (cmdline_parse_inst_t *)&cmd_operate_bpf_ld_parse, + (cmdline_parse_inst_t *)&cmd_operate_bpf_unld_parse, NULL, }; diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index b47537642..602e20ac3 100644 --- a/app/test-pmd/meson.build +++ b/app/test-pmd/meson.build @@ -21,7 +21,7 @@ sources = files('cmdline.c', 'testpmd.c', 'txonly.c') -deps = ['ethdev', 'gro', 'gso', 'cmdline', 'metrics', 'meter', 'bus_pci'] +deps = ['ethdev', 'gro', 'gso', 'cmdline', 'metrics', 'meter', 'bus_pci', 'bpf'] if dpdk_conf.has('RTE_LIBRTE_PDUMP') deps += 'pdump' endif -- 2.13.6