Add buffer tracing to the dispatch tracer

Change-Id: I56f25d653b71a25c70e6c5c1a93dd9c5158f2079
Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
Dave Barach
2018-11-20 12:08:39 -05:00
committed by Florin Coras
parent 41684c2d78
commit 1201a805db
4 changed files with 85 additions and 7 deletions

View File

@ -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* */

View File

@ -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 */
/*

View File

@ -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 *);

View File

@ -89,6 +89,8 @@ typedef struct
int verbose;
} vlib_trace_main_t;
format_function_t format_vlib_trace;
#endif /* included_vlib_trace_h */
/*