tcp: avoid fr segments less than mss if possible
[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 u8 *
34 format_bpf_trace_filter (u8 *s, va_list *a)
35 {
36   bpf_trace_filter_main_t *btm = va_arg (*a, bpf_trace_filter_main_t *);
37   struct bpf_insn *insn;
38
39   if (!btm->prog_set)
40     return format (s, "bpf trace filter is not set");
41
42   insn = btm->prog.bf_insns;
43   for (int i = 0; i < btm->prog.bf_len; insn++, i++)
44     s = format (s, "%s\n", bpf_image (insn, i));
45
46   return s;
47 }
48
49 clib_error_t *
50 bpf_trace_filter_set_unset (const char *bpf_expr, u8 is_del, u8 optimize)
51 {
52   bpf_trace_filter_main_t *btm = &bpf_trace_filter_main;
53   if (is_del)
54     {
55       if (btm->prog_set)
56         {
57           btm->prog_set = 0;
58           pcap_freecode (&btm->prog);
59         }
60     }
61   else if (bpf_expr)
62     {
63       if (btm->prog_set)
64         pcap_freecode (&btm->prog);
65       btm->prog_set = 0;
66       if (pcap_compile (btm->pcap, &btm->prog, (char *) bpf_expr, optimize,
67                         PCAP_NETMASK_UNKNOWN))
68         {
69           return clib_error_return (0, "Failed pcap_compile of %s", bpf_expr);
70         }
71       btm->prog_set = 1;
72     }
73   return 0;
74 };
75
76 int
77 bpf_is_packet_traced (vlib_buffer_t *b, u32 classify_table_index, int func)
78 {
79   bpf_trace_filter_main_t *bfm = &bpf_trace_filter_main;
80   struct pcap_pkthdr phdr = { 0 };
81   int res;
82   int res1;
83
84   if (classify_table_index != ~0 &&
85       (res1 = vnet_is_packet_traced (b, classify_table_index, 0)) != 1)
86     return res1;
87
88   if (!bfm->prog_set)
89     return 1;
90
91   phdr.caplen = b->current_length;
92   phdr.len = b->current_length;
93   res = pcap_offline_filter (&bfm->prog, &phdr, vlib_buffer_get_current (b));
94   return res != 0;
95 }
96
97 VLIB_REGISTER_TRACE_FILTER_FUNCTION (bpf_trace_filter_fn, static) = {
98   .name = "bpf_trace_filter",
99   .description = "bpf based trace filter",
100   .priority = 10,
101   .function = bpf_is_packet_traced
102 };
103
104 VLIB_INIT_FUNCTION (bpf_trace_filter_init);
105 bpf_trace_filter_main_t bpf_trace_filter_main;
106 /*
107  * fd.io coding-style-patch-verification: ON
108  *
109  * Local Variables:
110  * eval: (c-set-style "gnu")
111  * End:
112  */