diff options
author | Benoît Ganne <bganne@cisco.com> | 2021-07-15 19:21:31 +0200 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2021-08-10 15:03:13 +0000 |
commit | 1433185908daf98deb0a8f43c303b99382a87442 (patch) | |
tree | 2a6d81adafbcb08717cfbbe561f1088b4fdb9180 /src | |
parent | 31a4aa7b354dcef292c0ddaf8fbae915938a5d23 (diff) |
misc: do not capture tx packets twice
When a packet goes through interface-output, whether it should be
captured or not will be evaluated twice: in interface-output and in
interface-output-template (<interface_name>-out) node.
interface-output should only capture packets if there is an interface
filter, otherwise it should defer evaluation to
interface-output-template.
Type: fix
Change-Id: Ia720c5d184a236335e1d7d44d8c04caf87af5630
Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/interface_output.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/vnet/interface_output.c b/src/vnet/interface_output.c index 0de2714ed61..cc4997a3b49 100644 --- a/src/vnet/interface_output.c +++ b/src/vnet/interface_output.c @@ -285,25 +285,33 @@ vnet_interface_output_node_inline (vlib_main_t *vm, u32 sw_if_index, return n_bytes; } -static_always_inline void vnet_interface_pcap_tx_trace - (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, - int sw_if_index_from_buffer) +static_always_inline void +vnet_interface_pcap_tx_trace (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, int in_interface_ouput) { vnet_main_t *vnm = vnet_get_main (); u32 n_left_from, *from; - u32 sw_if_index; + u32 sw_if_index = ~0, hw_if_index = ~0; vnet_pcap_t *pp = &vnm->pcap; if (PREDICT_TRUE (pp->pcap_tx_enable == 0)) return; - if (sw_if_index_from_buffer == 0) + if (in_interface_ouput) + { + /* interface-output is called right before interface-output-template. + * We only want to capture packets here if there is a per-interface + * filter, in case it matches the sub-interface sw_if_index. + * If there is no per-interface filter configured, let the + * interface-output-template node deal with it */ + if (pp->pcap_sw_if_index == 0) + return; + } + else { vnet_interface_output_runtime_t *rt = (void *) node->runtime_data; sw_if_index = rt->sw_if_index; } - else - sw_if_index = ~0; n_left_from = frame->n_vectors; from = vlib_frame_vector_args (frame); @@ -315,8 +323,19 @@ static_always_inline void vnet_interface_pcap_tx_trace from++; n_left_from--; - if (sw_if_index_from_buffer) - sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + if (in_interface_ouput) + { + const u32 sii = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + if (PREDICT_FALSE (sii != sw_if_index)) + { + const vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, sii); + hw_if_index = hi->sw_if_index; + sw_if_index = sii; + } + if (hw_if_index == sw_if_index) + continue; /* defer to interface-output-template */ + } if (vnet_is_packet_pcaped (pp, b0, sw_if_index)) pcap_add_buffer (&pp->pcap_main, vm, bi0, pp->max_bytes_per_pkt); @@ -420,8 +439,7 @@ VLIB_NODE_FN (vnet_interface_output_node) /* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP, node->node_index, VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED); - vnet_interface_pcap_tx_trace (vm, node, frame, - 0 /* sw_if_index_from_buffer */ ); + vnet_interface_pcap_tx_trace (vm, node, frame, 0 /* in_interface_ouput */); vlib_get_buffers (vm, from, bufs, n_buffers); @@ -504,8 +522,7 @@ VLIB_NODE_FN (vnet_per_buffer_interface_output_node) (vlib_main_t * vm, u32 n_left_to_next, *from, *to_next; u32 n_left_from, next_index; - vnet_interface_pcap_tx_trace (vm, node, frame, - 1 /* sw_if_index_from_buffer */ ); + vnet_interface_pcap_tx_trace (vm, node, frame, 1 /* in_interface_ouput */); n_left_from = frame->n_vectors; |