summaryrefslogtreecommitdiffstats
path: root/src/vnet/interface_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/interface_output.c')
-rw-r--r--src/vnet/interface_output.c43
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;