From 1433185908daf98deb0a8f43c303b99382a87442 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Beno=C3=AEt=20Ganne?= Date: Thu, 15 Jul 2021 19:21:31 +0200 Subject: [PATCH] misc: do not capture tx packets twice MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 (-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 --- src/vnet/interface_output.c | 43 ++++++++++++++++++++++++++++++------------- 1 file 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; -- 2.16.6