bpf_trace_filter: allow use whithout classifier
[vpp.git] / src / plugins / bpf_trace_filter / bpf_trace_filter.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2023 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #include <vlib/vlib.h>
19 #include <bpf_trace_filter/bpf_trace_filter.h>
20
21 clib_error_t *
22 bpf_trace_filter_init (vlib_main_t *vm)
23 {
24   bpf_trace_filter_main_t *btm = &bpf_trace_filter_main;
25   btm->pcap = pcap_open_dead (DLT_EN10MB, 65535);
26
27   return 0;
28 }
29
30 int vnet_is_packet_traced (vlib_buffer_t *b, u32 classify_table_index,
31                            int func);
32
33 clib_error_t *
34 bpf_trace_filter_set_unset (const char *bpf_expr, u8 is_del)
35 {
36   bpf_trace_filter_main_t *btm = &bpf_trace_filter_main;
37   if (is_del)
38     {
39       if (btm->prog_set)
40         {
41           btm->prog_set = 0;
42           pcap_freecode (&btm->prog);
43         }
44     }
45   else if (bpf_expr)
46     {
47       if (btm->prog_set)
48         pcap_freecode (&btm->prog);
49       btm->prog_set = 0;
50       if (pcap_compile (btm->pcap, &btm->prog, (char *) bpf_expr, 0,
51                         PCAP_NETMASK_UNKNOWN))
52         {
53           return clib_error_return (0, "Failed pcap_compile of %s", bpf_expr);
54         }
55       btm->prog_set = 1;
56     }
57   return 0;
58 };
59
60 int
61 bpf_is_packed_traced (vlib_buffer_t *b, u32 classify_table_index, int func)
62 {
63   bpf_trace_filter_main_t *bfm = &bpf_trace_filter_main;
64   struct pcap_pkthdr phdr = { 0 };
65   int res;
66   int res1;
67
68   if (classify_table_index != ~0 &&
69       (res1 = vnet_is_packet_traced (b, classify_table_index, 0)) != 1)
70     return res1;
71
72   if (!bfm->prog_set)
73     return 1;
74
75   phdr.caplen = b->current_length;
76   phdr.len = b->current_length;
77   res = pcap_offline_filter (&bfm->prog, &phdr, vlib_buffer_get_current (b));
78   return res != 0;
79 }
80
81 VLIB_REGISTER_TRACE_FILTER_FUNCTION (bpf_trace_filter_fn, static) = {
82   .name = "bpf_trace_filter",
83   .description = "bpf based trace filter",
84   .priority = 10,
85   .function = bpf_is_packed_traced
86 };
87
88 VLIB_INIT_FUNCTION (bpf_trace_filter_init);
89 bpf_trace_filter_main_t bpf_trace_filter_main;
90 /*
91  * fd.io coding-style-patch-verification: ON
92  *
93  * Local Variables:
94  * eval: (c-set-style "gnu")
95  * End:
96  */