aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammed Hawari <mohammed@hawari.fr>2023-06-09 16:50:56 +0200
committerBeno�t Ganne <bganne@cisco.com>2023-06-30 11:53:06 +0000
commitccd30709585939c3202c05af0dfda2aca670e8b7 (patch)
tree0224822cb25b32579dd73a5af98499b342e00575
parent52fa5f21b911aaf1c50feb560dd3683b83625d2f (diff)
bpf_trace_filter: plugin for BPF Trace Filtering
Change-Id: I342de0a375b783725aa2b621c1c70bc8bf646450 Signed-off-by: Mohammed Hawari <mohammed@hawari.fr> Type: improvement
-rw-r--r--MAINTAINERS5
-rw-r--r--Makefile1
l---------docs/developer/plugins/bpf_trace_filter.rst1
-rw-r--r--docs/developer/plugins/index.rst1
-rw-r--r--docs/spelling_wordlist.txt1
-rw-r--r--src/plugins/bpf_trace_filter/CMakeLists.txt45
-rw-r--r--src/plugins/bpf_trace_filter/FEATURE.yaml8
-rw-r--r--src/plugins/bpf_trace_filter/api.c74
-rw-r--r--src/plugins/bpf_trace_filter/bpf_trace_filter.api26
-rw-r--r--src/plugins/bpf_trace_filter/bpf_trace_filter.c96
-rw-r--r--src/plugins/bpf_trace_filter/bpf_trace_filter.h40
-rw-r--r--src/plugins/bpf_trace_filter/bpf_trace_filter.rst4
-rw-r--r--src/plugins/bpf_trace_filter/cli.c68
-rw-r--r--src/plugins/bpf_trace_filter/plugin.c33
-rw-r--r--src/vnet/classify/trace_classify.h2
15 files changed, 405 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 1117b6da415..a07eb27e798 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -806,6 +806,11 @@ I: prom
M: Florin Coras <fcoras@cisco.com>
F: src/plugins/prom
+Plugin - BPF Trace Filter
+I: bpf_trace_filter
+M: Mohammed Hawari <mohammed@hawari.fr>
+F: src/plugins/bpf_trace_filter
+
cJSON
I: cjson
M: Ole Troan <ot@cisco.com>
diff --git a/Makefile b/Makefile
index 2b781fbcdfc..ee7d9699b02 100644
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,7 @@ DEB_DEPENDS += libelf-dev libpcap-dev # for libxdp (af_xdp)
DEB_DEPENDS += iperf3 # for 'make test TEST=vcl'
DEB_DEPENDS += nasm
DEB_DEPENDS += iperf ethtool # for 'make test TEST=vm_vpp_interfaces'
+DEB_DEPENDS += libpcap-dev
LIBFFI=libffi6 # works on all but 20.04 and debian-testing
diff --git a/docs/developer/plugins/bpf_trace_filter.rst b/docs/developer/plugins/bpf_trace_filter.rst
new file mode 120000
index 00000000000..934d3afd6ac
--- /dev/null
+++ b/docs/developer/plugins/bpf_trace_filter.rst
@@ -0,0 +1 @@
+../../../src/plugins/bpf_trace_filter/bpf_trace_filter.rst \ No newline at end of file
diff --git a/docs/developer/plugins/index.rst b/docs/developer/plugins/index.rst
index 4af8c4c67be..91af95f3318 100644
--- a/docs/developer/plugins/index.rst
+++ b/docs/developer/plugins/index.rst
@@ -41,3 +41,4 @@ For more on plugins please refer to :ref:`add_plugin`.
acl_lookup_context
bufmon_doc
ip_session_redirect_doc
+ bpf_trace_filter
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index d28c6df56ca..a0f80fa8927 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -102,6 +102,7 @@ bms
Bn
boolean
bootup
+bpf
Brockners
bsid
bss
diff --git a/src/plugins/bpf_trace_filter/CMakeLists.txt b/src/plugins/bpf_trace_filter/CMakeLists.txt
new file mode 100644
index 00000000000..4268022c281
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (c) 2023 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+vpp_find_path(PCAP_INCLUDE_DIR NAMES pcap.h)
+if (NOT PCAP_INCLUDE_DIR)
+ message(WARNING "libpcap headers not found - bpf_trace_filter plugin disabled")
+ return()
+endif()
+
+vpp_plugin_find_library(bpf_trace_filter PCAP_LIB libpcap.so)
+
+if (NOT PCAP_LIB)
+ message(WARNING "bpf_trace_filter plugin - missing libraries - bpf_trace_filter plugin disabled")
+ return()
+endif()
+
+set(CMAKE_REQUIRED_FLAGS "-fPIC")
+set(CMAKE_REQUIRED_INCLUDES "${PCAP_INCLUDE_DIR}")
+set(CMAKE_REQUIRED_LIBRARIES "${PCAP_LIB}")
+
+include_directories(${PCAP_INCLUDE_DIR})
+
+add_vpp_plugin(bpf_trace_filter
+ SOURCES
+ cli.c
+ plugin.c
+ bpf_trace_filter.c
+ api.c
+
+ API_FILES
+ bpf_trace_filter.api
+
+ LINK_LIBRARIES
+ ${PCAP_LIB}
+)
diff --git a/src/plugins/bpf_trace_filter/FEATURE.yaml b/src/plugins/bpf_trace_filter/FEATURE.yaml
new file mode 100644
index 00000000000..101572f731d
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/FEATURE.yaml
@@ -0,0 +1,8 @@
+---
+name: BPF Trace Filter
+maintainer: Mohammed Hawari <mohammed@hawari.fr>
+features:
+ - BPF Trace Filtering
+description: "BPF Trace Filtering"
+state: experimental
+properties: [CLI, API]
diff --git a/src/plugins/bpf_trace_filter/api.c b/src/plugins/bpf_trace_filter/api.c
new file mode 100644
index 00000000000..9e15c61ef07
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/api.c
@@ -0,0 +1,74 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2023 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#include <vlib/vlib.h>
+#include <bpf_trace_filter/bpf_trace_filter.h>
+#include <vlibapi/api.h>
+#include <vlibmemory/api.h>
+
+/* define message IDs */
+#include <bpf_trace_filter/bpf_trace_filter.api_enum.h>
+#include <bpf_trace_filter/bpf_trace_filter.api_types.h>
+
+#define REPLY_MSG_ID_BASE (bm->msg_id_base)
+#include <vlibapi/api_helper_macros.h>
+
+static void
+vl_api_bpf_trace_filter_set_t_handler (vl_api_bpf_trace_filter_set_t *mp)
+{
+ bpf_trace_filter_main_t *bm = &bpf_trace_filter_main;
+ vl_api_bpf_trace_filter_set_reply_t *rmp;
+ clib_error_t *err = 0;
+ int rv = 0;
+ u8 is_del;
+ char *bpf_expr;
+ is_del = !mp->is_add;
+
+ bpf_expr = vl_api_from_api_to_new_c_string (&mp->filter);
+ err = bpf_trace_filter_set_unset (bpf_expr, is_del);
+
+ if (err)
+ {
+ rv = -1;
+ clib_error_report (err);
+ }
+ vec_free (bpf_expr);
+
+ REPLY_MACRO (VL_API_BPF_TRACE_FILTER_SET_REPLY);
+}
+
+#include <bpf_trace_filter/bpf_trace_filter.api.c>
+
+static clib_error_t *
+bpf_trace_filter_plugin_api_hookup (vlib_main_t *vm)
+{
+ bpf_trace_filter_main_t *bm = &bpf_trace_filter_main;
+
+ /* ask for a correctly-sized block of API message decode slots */
+ bm->msg_id_base = setup_message_id_table ();
+ return 0;
+}
+
+VLIB_API_INIT_FUNCTION (bpf_trace_filter_plugin_api_hookup);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */ \ No newline at end of file
diff --git a/src/plugins/bpf_trace_filter/bpf_trace_filter.api b/src/plugins/bpf_trace_filter/bpf_trace_filter.api
new file mode 100644
index 00000000000..53f1b176a21
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/bpf_trace_filter.api
@@ -0,0 +1,26 @@
+/*
+ * bpf_trace_filter.api - BPF Trace filter API
+ *
+ * Copyright (c) 2023 Cisco and/or its affiliates
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ option version = "0.1.0";
+
+ autoreply define bpf_trace_filter_set
+ {
+ u32 client_index;
+ u32 context;
+ bool is_add [default = true];
+ string filter[];
+ }; \ No newline at end of file
diff --git a/src/plugins/bpf_trace_filter/bpf_trace_filter.c b/src/plugins/bpf_trace_filter/bpf_trace_filter.c
new file mode 100644
index 00000000000..ff08d2cdb80
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/bpf_trace_filter.c
@@ -0,0 +1,96 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2023 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#include <vlib/vlib.h>
+#include <bpf_trace_filter/bpf_trace_filter.h>
+
+clib_error_t *
+bpf_trace_filter_init (vlib_main_t *vm)
+{
+ bpf_trace_filter_main_t *btm = &bpf_trace_filter_main;
+ btm->pcap = pcap_open_dead (DLT_EN10MB, 65535);
+
+ return 0;
+}
+
+int vnet_is_packet_traced (vlib_buffer_t *b, u32 classify_table_index,
+ int func);
+
+clib_error_t *
+bpf_trace_filter_set_unset (const char *bpf_expr, u8 is_del)
+{
+ bpf_trace_filter_main_t *btm = &bpf_trace_filter_main;
+ if (is_del)
+ {
+ if (btm->prog_set)
+ {
+ btm->prog_set = 0;
+ pcap_freecode (&btm->prog);
+ }
+ }
+ else if (bpf_expr)
+ {
+ if (btm->prog_set)
+ pcap_freecode (&btm->prog);
+ btm->prog_set = 0;
+ if (pcap_compile (btm->pcap, &btm->prog, (char *) bpf_expr, 0,
+ PCAP_NETMASK_UNKNOWN))
+ {
+ return clib_error_return (0, "Failed pcap_compile of %s", bpf_expr);
+ }
+ btm->prog_set = 1;
+ }
+ return 0;
+};
+
+int
+bpf_is_packed_traced (vlib_buffer_t *b, u32 classify_table_index, int func)
+{
+ bpf_trace_filter_main_t *bfm = &bpf_trace_filter_main;
+ struct pcap_pkthdr phdr = { 0 };
+ int res;
+ int res1;
+ res1 = vnet_is_packet_traced (b, classify_table_index, 0);
+
+ if (res1 != 1)
+ return res1;
+
+ if (!bfm->prog_set)
+ return 1;
+
+ phdr.caplen = b->current_length;
+ phdr.len = b->current_length;
+ res = pcap_offline_filter (&bfm->prog, &phdr, vlib_buffer_get_current (b));
+ return res != 0;
+}
+
+VLIB_REGISTER_TRACE_FILTER_FUNCTION (bpf_trace_filter_fn, static) = {
+ .name = "bpf_trace_filter",
+ .description = "bpf based trace filter",
+ .priority = 10,
+ .function = bpf_is_packed_traced
+};
+
+VLIB_INIT_FUNCTION (bpf_trace_filter_init);
+bpf_trace_filter_main_t bpf_trace_filter_main;
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/bpf_trace_filter/bpf_trace_filter.h b/src/plugins/bpf_trace_filter/bpf_trace_filter.h
new file mode 100644
index 00000000000..a031f98cbdb
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/bpf_trace_filter.h
@@ -0,0 +1,40 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2023 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#ifndef _BPF_TRACE_FILTER_H_
+#define _BPF_TRACE_FILTER_H_
+#include <vlib/vlib.h>
+#include <pcap.h>
+typedef struct
+{
+ pcap_t *pcap;
+ u16 msg_id_base;
+ u8 prog_set;
+ struct bpf_program prog;
+} bpf_trace_filter_main_t;
+
+extern bpf_trace_filter_main_t bpf_trace_filter_main;
+clib_error_t *bpf_trace_filter_set_unset (const char *bpf_expr, u8 is_del);
+#endif /* _BPF_TRACE_FILTER_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */ \ No newline at end of file
diff --git a/src/plugins/bpf_trace_filter/bpf_trace_filter.rst b/src/plugins/bpf_trace_filter/bpf_trace_filter.rst
new file mode 100644
index 00000000000..63deddbc5ab
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/bpf_trace_filter.rst
@@ -0,0 +1,4 @@
+BPF Trace Filter Function
+============================
+This plugin provides a trace filter function that relies on a BPF interpreter to select which packets
+must be traced. \ No newline at end of file
diff --git a/src/plugins/bpf_trace_filter/cli.c b/src/plugins/bpf_trace_filter/cli.c
new file mode 100644
index 00000000000..906ca71d5f3
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/cli.c
@@ -0,0 +1,68 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2023 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+#include <stdint.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <inttypes.h>
+
+#include <vlib/vlib.h>
+#include <bpf_trace_filter/bpf_trace_filter.h>
+#include <pcap.h>
+
+static clib_error_t *
+set_bpf_trace_filter_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u8 *bpf_expr = 0;
+ u8 is_del = 0;
+ clib_error_t *err = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "del"))
+ is_del = 1;
+ else if (unformat (line_input, "%s", &bpf_expr))
+ ;
+ else
+ return clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ }
+
+ err = bpf_trace_filter_set_unset ((char *) bpf_expr, is_del);
+ unformat_free (line_input);
+
+ return err;
+}
+
+VLIB_CLI_COMMAND (set_bpf_trace_filter, static) = {
+ .path = "set bpf trace filter",
+ .short_help = "set bpf trace filter {<pcap string>}",
+ .function = set_bpf_trace_filter_command_fn,
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/bpf_trace_filter/plugin.c b/src/plugins/bpf_trace_filter/plugin.c
new file mode 100644
index 00000000000..db5d6111d85
--- /dev/null
+++ b/src/plugins/bpf_trace_filter/plugin.c
@@ -0,0 +1,33 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2023 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/plugin/plugin.h>
+#include <vpp/app/version.h>
+
+VLIB_PLUGIN_REGISTER () = {
+ .version = VPP_BUILD_VER,
+ .description = "BPF Trace Filter Plugin",
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/classify/trace_classify.h b/src/vnet/classify/trace_classify.h
index bc25ecd0ff7..fea4ddee7e7 100644
--- a/src/vnet/classify/trace_classify.h
+++ b/src/vnet/classify/trace_classify.h
@@ -29,6 +29,8 @@
* @param u32 classify_table_index - classifier table index
* @return 0 => no trace, 1 => trace, -1 => error
*/
+int vnet_is_packet_traced (vlib_buffer_t *b, u32 classify_table_index,
+ int func);
static inline int
vnet_is_packet_traced_inline (vlib_buffer_t * b,