summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2018-11-20 12:08:39 -0500
committerFlorin Coras <florin.coras@gmail.com>2018-11-20 22:35:08 +0000
commit1201a805db89cedfa833f5d4d41866b7d1a7c0c5 (patch)
tree1352b6f4dc5e69819e4e22739ae113ba87035e45
parent41684c2d78d5cefa94dcb4e19bcd8eb7feb00bd0 (diff)
Add buffer tracing to the dispatch tracer
Change-Id: I56f25d653b71a25c70e6c5c1a93dd9c5158f2079 Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/vlib/main.c85
-rw-r--r--src/vlib/main.h3
-rw-r--r--src/vlib/trace.c2
-rw-r--r--src/vlib/trace.h2
4 files changed, 85 insertions, 7 deletions
diff --git a/src/vlib/main.c b/src/vlib/main.c
index 77dc573fc5d..d1babdb9da6 100644
--- a/src/vlib/main.c
+++ b/src/vlib/main.c
@@ -953,12 +953,16 @@ dispatch_pcap_trace (vlib_main_t * vm,
vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **bufp, *b;
u8 name_tlv[64];
pcap_main_t *pm = &vm->dispatch_pcap_main;
+ vlib_trace_main_t *tm = &vm->trace_main;
u32 capture_size;
vlib_node_t *n;
+ u8 *packet_trace = 0;
i32 n_left;
f64 time_now = vlib_time_now (vm);
u32 *from;
u32 name_length;
+ u16 trace_length;
+ u8 version[2];
u8 *d;
/* Input nodes don't have frames yet */
@@ -985,13 +989,38 @@ dispatch_pcap_trace (vlib_main_t * vm,
{
b = bufp[i];
+ version[0] = VLIB_PCAP_MAJOR_VERSION;
+ version[1] = VLIB_PCAP_MINOR_VERSION;
+
+ vec_reset_length (packet_trace);
+
+ /* Is this packet traced? */
+ if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ vlib_trace_header_t **h
+ = pool_elt_at_index (tm->trace_buffer_pool, b->trace_index);
+
+ packet_trace = format (packet_trace, "%U%c",
+ format_vlib_trace, vm, h[0], 0);
+ }
+
/* Figure out how many bytes we're capturing */
- capture_size = (sizeof (vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE) + vlib_buffer_length_in_chain (vm, b) + sizeof (u32) + +(name_length + 2); /* +2: count plus NULL byte */
+ /* *INDENT-OFF* */
+ capture_size = (sizeof (vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE)
+ + sizeof (version)
+ + vlib_buffer_length_in_chain (vm, b)
+ + sizeof (u32) + (name_length + 2) /* +2: count plus NULL byte */
+ + (vec_len (packet_trace) + 2); /* +2: trace count */
+ /* *INDENT-ON* */
clib_spinlock_lock_if_init (&pm->lock);
- n_left = clib_min (capture_size, 512);
+ n_left = clib_min (capture_size, 16384);
d = pcap_add_packet (pm, time_now, n_left, capture_size);
+ /* Copy the (major, minor) version numbers */
+ clib_memcpy_fast (d, version, sizeof (version));
+ d += sizeof (version);
+
/* Copy the buffer index */
clib_memcpy_fast (d, &from[i], sizeof (u32));
d += 4;
@@ -1004,8 +1033,22 @@ dispatch_pcap_trace (vlib_main_t * vm,
clib_memcpy_fast (d, b, sizeof (*b) - VLIB_BUFFER_PRE_DATA_SIZE);
d += sizeof (*b) - VLIB_BUFFER_PRE_DATA_SIZE;
- n_left = clib_min (vlib_buffer_length_in_chain (vm, b),
- 512 - (sizeof (*b) - VLIB_BUFFER_PRE_DATA_SIZE));
+ trace_length = vec_len (packet_trace);
+ /* Copy the trace data length (may be zero) */
+ clib_memcpy_fast (d, &trace_length, sizeof (trace_length));
+ d += 2;
+
+ /* Copy packet trace data (if any) */
+ if (vec_len (packet_trace))
+ clib_memcpy_fast (d, packet_trace, vec_len (packet_trace));
+
+ d += vec_len (packet_trace);
+
+ n_left = clib_min
+ (vlib_buffer_length_in_chain (vm, b),
+ 16384 -
+ ((sizeof (*b) - VLIB_BUFFER_PRE_DATA_SIZE) +
+ (trace_length + 2)));
/* Copy the packet data */
while (1)
{
@@ -1021,6 +1064,7 @@ dispatch_pcap_trace (vlib_main_t * vm,
clib_spinlock_unlock_if_init (&pm->lock);
}
}
+ vec_free (packet_trace);
}
static_always_inline u64
@@ -1991,6 +2035,9 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
int enabled = 0;
int errorFlag = 0;
clib_error_t *error = 0;
+ u32 node_index, add;
+ vlib_trace_main_t *tm;
+ vlib_trace_node_t *tn;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
@@ -2087,6 +2134,27 @@ pcap_dispatch_trace_command_internal (vlib_main_t * vm,
}
break;
}
+ else if (unformat (line_input, "buffer-trace %U %d",
+ unformat_vlib_node, vm, &node_index, &add))
+ {
+ if (vnet_trace_dummy == 0)
+ vec_validate_aligned (vnet_trace_dummy, 2048,
+ CLIB_CACHE_LINE_BYTES);
+ vlib_cli_output (vm, "Buffer tracing of %d pkts from %U enabled...",
+ add, format_vlib_node_name, vm, node_index);
+
+ /* *INDENT-OFF* */
+ foreach_vlib_main ((
+ {
+ tm = &this_vlib_main->trace_main;
+ tm->verbose = 0; /* not sure this ever did anything... */
+ vec_validate (tm->nodes, node_index);
+ tn = tm->nodes + node_index;
+ tn->limit += add;
+ tm->trace_enable = 1;
+ }));
+ /* *INDENT-ON* */
+ }
else
{
@@ -2174,7 +2242,11 @@ pcap_dispatch_trace_command_fn (vlib_main_t * vm,
* @cliexend
* Example of how to start a dispatch trace capture:
* @cliexstart{pcap dispatch trace on max 35 file dispatchTrace.pcap}
- * pcap dispatc capture on...
+ * pcap dispatch capture on...
+ * @cliexend
+ * Example of how to start a dispatch trace capture with buffer tracing
+ * @cliexstart{pcap dispatch trace on max 10000 file dispatchTrace.pcap buffer-trace dpdk-input 1000}
+ * pcap dispatch capture on...
* @cliexend
* Example of how to display the status of a tx packet capture in progress:
* @cliexstart{pcap tx trace status}
@@ -2191,7 +2263,8 @@ pcap_dispatch_trace_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (pcap_dispatch_trace_command, static) = {
.path = "pcap dispatch trace",
.short_help =
- "pcap dispatch trace [on|off] [max <nn>] [file <name>] [status]",
+ "pcap dispatch trace [on|off] [max <nn>] [file <name>] [status]\n"
+ " [buffer-trace <input-node-name> <nn>]",
.function = pcap_dispatch_trace_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vlib/main.h b/src/vlib/main.h
index 9e7538e9f00..9fa294e96f5 100644
--- a/src/vlib/main.h
+++ b/src/vlib/main.h
@@ -371,6 +371,9 @@ u32 vlib_app_num_thread_stacks_needed (void) __attribute__ ((weak));
extern void vlib_node_sync_stats (vlib_main_t * vm, vlib_node_t * n);
+#define VLIB_PCAP_MAJOR_VERSION 1
+#define VLIB_PCAP_MINOR_VERSION 0
+
#endif /* included_vlib_main_h */
/*
diff --git a/src/vlib/trace.c b/src/vlib/trace.c
index e3b289879da..70621135c68 100644
--- a/src/vlib/trace.c
+++ b/src/vlib/trace.c
@@ -131,7 +131,7 @@ clear_trace_buffer (void)
/* *INDENT-ON* */
}
-static u8 *
+u8 *
format_vlib_trace (u8 * s, va_list * va)
{
vlib_main_t *vm = va_arg (*va, vlib_main_t *);
diff --git a/src/vlib/trace.h b/src/vlib/trace.h
index 0560913c588..b5634031f96 100644
--- a/src/vlib/trace.h
+++ b/src/vlib/trace.h
@@ -89,6 +89,8 @@ typedef struct
int verbose;
} vlib_trace_main_t;
+format_function_t format_vlib_trace;
+
#endif /* included_vlib_trace_h */
/*