diff options
Diffstat (limited to 'src/vnet/interface_output.c')
-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; |