bpf_trace_filter: allow pcap filtering without classifier
Type: improvement Change-Id: I7ca860dbee0d0a24b7f00943142d8c878ed90e80 Signed-off-by: Hadi Rayan Al-Sandid <halsandi@cisco.com>
This commit is contained in:
parent
dd02eb893b
commit
fb8f51697c
@ -46,7 +46,7 @@ vnet_is_packet_pcaped (vnet_pcap_t *pp, vlib_buffer_t *b, u32 sw_if_index)
|
||||
if (pcap_error_index != (vlib_error_t) ~0 && pcap_error_index != b->error)
|
||||
return 0; /* wrong error */
|
||||
|
||||
if (filter_classify_table_index != ~0 &&
|
||||
if (pp->pcap_filter_enable &&
|
||||
pp->current_filter_function (b, filter_classify_table_index,
|
||||
0 /* full classify */) != 1)
|
||||
return 0; /* not matching the filter, skip */
|
||||
|
@ -2041,6 +2041,12 @@ format_vnet_pcap (u8 * s, va_list * args)
|
||||
s = format (s, "drop");
|
||||
printed = 1;
|
||||
}
|
||||
|
||||
if (printed && pp->pcap_filter_enable)
|
||||
{
|
||||
s = format (s, "with filter");
|
||||
printed = 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
s = format (s, "unknown type %d!", type);
|
||||
@ -2092,12 +2098,6 @@ vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t * a)
|
||||
&& (pm->n_packets_to_capture != a->packets_to_capture))
|
||||
return VNET_API_ERROR_INVALID_VALUE_2;
|
||||
|
||||
/* Classify filter specified, but no classify filter configured */
|
||||
if ((a->rx_enable + a->tx_enable + a->drop_enable) && a->filter &&
|
||||
(!cm->classify_table_index_by_sw_if_index ||
|
||||
cm->classify_table_index_by_sw_if_index[0] == ~0))
|
||||
return VNET_API_ERROR_NO_SUCH_LABEL;
|
||||
|
||||
if (a->rx_enable + a->tx_enable + a->drop_enable)
|
||||
{
|
||||
void *save_pcap_data;
|
||||
@ -2151,11 +2151,13 @@ vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t * a)
|
||||
}
|
||||
pm->n_packets_to_capture = a->packets_to_capture;
|
||||
pp->pcap_sw_if_index = a->sw_if_index;
|
||||
if (a->filter)
|
||||
if (a->filter && cm->classify_table_index_by_sw_if_index &&
|
||||
cm->classify_table_index_by_sw_if_index[0] != ~0)
|
||||
pp->filter_classify_table_index =
|
||||
cm->classify_table_index_by_sw_if_index[0];
|
||||
else
|
||||
pp->filter_classify_table_index = ~0;
|
||||
pp->pcap_filter_enable = a->filter;
|
||||
pp->pcap_error_index = a->drop_err;
|
||||
pp->pcap_rx_enable = a->rx_enable;
|
||||
pp->pcap_tx_enable = a->tx_enable;
|
||||
@ -2164,6 +2166,7 @@ vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t * a)
|
||||
}
|
||||
else
|
||||
{
|
||||
pp->pcap_filter_enable = 0;
|
||||
pp->pcap_rx_enable = 0;
|
||||
pp->pcap_tx_enable = 0;
|
||||
pp->pcap_drop_enable = 0;
|
||||
@ -2312,10 +2315,6 @@ pcap_trace_command_fn (vlib_main_t * vm,
|
||||
return clib_error_return (0,
|
||||
"Max bytes per pkt must be > 32, < 9000...");
|
||||
|
||||
case VNET_API_ERROR_NO_SUCH_LABEL:
|
||||
return clib_error_return
|
||||
(0, "No classify filter configured, see 'classify filter...'");
|
||||
|
||||
default:
|
||||
vlib_cli_output (vm, "WARNING: trace configure returned %d", rv);
|
||||
break;
|
||||
|
@ -66,7 +66,7 @@ typedef struct
|
||||
u8 pcap_tx_enable;
|
||||
/* Trace drop pkts */
|
||||
u8 pcap_drop_enable;
|
||||
u8 pad1;
|
||||
u8 pcap_filter_enable;
|
||||
u32 max_bytes_per_pkt;
|
||||
u32 pcap_sw_if_index;
|
||||
pcap_main_t pcap_main;
|
||||
|
@ -1,5 +1,7 @@
|
||||
from framework import VppTestCase
|
||||
from asfframework import VppTestRunner
|
||||
from vpp_papi_provider import CliFailedCommandError
|
||||
import os
|
||||
import unittest
|
||||
from config import config
|
||||
from scapy.layers.l2 import Ether
|
||||
@ -77,6 +79,17 @@ class TestBpfTraceFilter(VppTestCase):
|
||||
"Unexpected packets in the trace buffer",
|
||||
)
|
||||
|
||||
# verify that bpf trace filter has been selected for pcap
|
||||
self.vapi.cli("set pcap filter function bpf_trace_filter")
|
||||
self.vapi.cli("pcap trace rx tx max 1000 intfc any filter")
|
||||
|
||||
# verify that packets are filtered in not captured in pcap
|
||||
self.pg0.add_stream(packets)
|
||||
self.pg_start()
|
||||
|
||||
with self.assertRaises(CliFailedCommandError):
|
||||
self.vapi.cli("pcap trace rx tx off")
|
||||
|
||||
reply = self.vapi.cli("show bpf trace filter")
|
||||
self.assertIn("(000)", reply, "Unexpected bpf filter dump")
|
||||
|
||||
@ -103,6 +116,29 @@ class TestBpfTraceFilter(VppTestCase):
|
||||
"Unexpected packets in the trace buffer",
|
||||
)
|
||||
|
||||
# verify that bpf trace filter has been selected for pcap
|
||||
self.vapi.pcap_set_filter_function(filter_function_name="bpf_trace_filter")
|
||||
reply = self.vapi.cli("show pcap filter function")
|
||||
self.assertIn(
|
||||
"(*) name:bpf_trace_filter",
|
||||
reply,
|
||||
"BPF Trace filter is not selected for Pcap",
|
||||
)
|
||||
|
||||
# verify that packets are filtered in not captured in pcap
|
||||
self.vapi.pcap_trace_on(
|
||||
capture_rx=True,
|
||||
capture_tx=True,
|
||||
max_packets=1000,
|
||||
filter=True,
|
||||
sw_if_index=0,
|
||||
filename="bpf_trace.pcap",
|
||||
)
|
||||
self.pg0.add_stream(packets)
|
||||
self.pg_start()
|
||||
with self.vapi.assert_negative_api_retval():
|
||||
self.vapi.pcap_trace_off()
|
||||
|
||||
def test_bpf_trace_filter_vapi_v2(self):
|
||||
"""BPF Trace filter test [VAPI v2]"""
|
||||
self.vapi.bpf_trace_filter_set_v2(filter="tcp or dst port 5678")
|
||||
@ -131,6 +167,30 @@ class TestBpfTraceFilter(VppTestCase):
|
||||
"Unexpected packets in the trace buffer",
|
||||
)
|
||||
|
||||
# verify that bpf trace filter has been selected for pcap
|
||||
self.vapi.pcap_set_filter_function(filter_function_name="bpf_trace_filter")
|
||||
reply = self.vapi.cli("show pcap filter function")
|
||||
self.assertIn(
|
||||
"(*) name:bpf_trace_filter",
|
||||
reply,
|
||||
"BPF Trace filter is not selected for Pcap",
|
||||
)
|
||||
|
||||
# verify that packets are captured in pcap with filter
|
||||
self.vapi.pcap_trace_on(
|
||||
capture_rx=True,
|
||||
capture_tx=True,
|
||||
max_packets=1000,
|
||||
filter=True,
|
||||
sw_if_index=0,
|
||||
filename="bpf_trace.pcap",
|
||||
)
|
||||
self.pg0.add_stream(packets)
|
||||
self.pg_start()
|
||||
self.vapi.pcap_trace_off()
|
||||
self.assertTrue(os.path.exists("/tmp/bpf_trace.pcap"))
|
||||
os.remove("/tmp/bpf_trace.pcap")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(testRunner=VppTestRunner)
|
||||
|
@ -75,11 +75,13 @@ class TestPcap(VppTestCase):
|
||||
"pa en",
|
||||
"pcap dispatch trace off",
|
||||
"pcap trace rx tx max 1000 intfc any",
|
||||
"pcap trace status",
|
||||
"pa en",
|
||||
"pcap trace status",
|
||||
"pcap trace rx tx off",
|
||||
"classify filter pcap mask l3 ip4 src match l3 ip4 src 11.22.33.44",
|
||||
"pcap trace rx tx max 1000 intfc any file filt.pcap filter",
|
||||
"pcap trace status",
|
||||
"show cla t verbose 2",
|
||||
"show cla t verbose",
|
||||
"show cla t",
|
||||
@ -123,6 +125,21 @@ class TestPcap(VppTestCase):
|
||||
self.pg_send(self.pg0, pkt * 10)
|
||||
self.vapi.pcap_trace_off()
|
||||
|
||||
# Launching trace with filter & no classifier table specified
|
||||
# should result in no packet capture
|
||||
self.vapi.pcap_trace_on(
|
||||
capture_rx=True,
|
||||
capture_tx=True,
|
||||
max_packets=1000,
|
||||
filter=True,
|
||||
sw_if_index=0,
|
||||
filename="trace_any_invalid_filter.pcap",
|
||||
)
|
||||
self.pg_send(self.pg0, pkt * 10)
|
||||
with self.vapi.assert_negative_api_retval():
|
||||
self.vapi.pcap_trace_off()
|
||||
self.assertFalse(os.path.exists("/tmp/trace_any_invalid_filter.pcap"))
|
||||
|
||||
self.vapi.cli(
|
||||
f"classify filter pcap mask l3 ip4 src match l3 ip4 src {self.pg0.local_ip4}"
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user