diff options
-rw-r--r-- | src/vnet/pg/output.c | 28 | ||||
-rw-r--r-- | src/vnet/pg/pg.h | 7 | ||||
-rw-r--r-- | src/vnet/pg/stream.c | 20 |
3 files changed, 46 insertions, 9 deletions
diff --git a/src/vnet/pg/output.c b/src/vnet/pg/output.c index 3d1f2660..ab57deef 100644 --- a/src/vnet/pg/output.c +++ b/src/vnet/pg/output.c @@ -37,6 +37,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include <vppinfra/string.h> #include <vlib/vlib.h> #include <vnet/vnet.h> #include <vnet/pg/pg.h> @@ -56,19 +57,28 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) while (__sync_lock_test_and_set (pif->lockp, 1)) ; - if (pif->pcap_file_name != 0) + while (n_left > 0) { - while (n_left > 0) - { - n_left--; - u32 bi0 = buffers[0]; - buffers++; + n_left--; + u32 bi0 = buffers[0]; + vlib_buffer_t *b = vlib_get_buffer (vm, bi0); + buffers++; - pcap_add_buffer (&pif->pcap_main, vm, bi0, - ETHERNET_MAX_PACKET_BYTES); + if (b->flags & VLIB_BUFFER_IS_TRACED) + { + pg_output_trace_t *t = vlib_add_trace (vm, node, b, sizeof (*t)); + t->buffer_index = bi0; + clib_memcpy (&t->buffer, b, sizeof (b[0]) - sizeof (b->pre_data)); + clib_memcpy (t->buffer.pre_data, b->data + b->current_data, + sizeof (t->buffer.pre_data)); } - pcap_write (&pif->pcap_main); + + if (pif->pcap_file_name != 0) + pcap_add_buffer (&pif->pcap_main, vm, bi0, ETHERNET_MAX_PACKET_BYTES); } + if (pif->pcap_file_name != 0) + pcap_write (&pif->pcap_main); + vlib_buffer_free (vm, vlib_frame_args (frame), n_buffers); if (PREDICT_FALSE (pif->lockp != 0)) diff --git a/src/vnet/pg/pg.h b/src/vnet/pg/pg.h index a4027834..111df91a 100644 --- a/src/vnet/pg/pg.h +++ b/src/vnet/pg/pg.h @@ -372,6 +372,13 @@ typedef struct clib_error_t *pg_capture (pg_capture_args_t * a); +typedef struct +{ + vlib_buffer_t buffer; + u32 buffer_index; +} +pg_output_trace_t; + #endif /* included_vlib_pg_h */ /* diff --git a/src/vnet/pg/stream.c b/src/vnet/pg/stream.c index 1ed7189f..c46875e1 100644 --- a/src/vnet/pg/stream.c +++ b/src/vnet/pg/stream.c @@ -95,6 +95,25 @@ pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s, int want_enabled) } static u8 * +format_pg_output_trace (u8 * s, va_list * va) +{ + CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *); + CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *); + pg_output_trace_t *t = va_arg (*va, pg_output_trace_t *); + uword indent = format_get_indent (s); + + s = format (s, "%Ubuffer 0x%x: %U", + format_white_space, indent, + t->buffer_index, format_vlib_buffer, &t->buffer); + + s = format (s, "\n%U%U", format_white_space, indent, + format_ethernet_header_with_length, t->buffer.pre_data, + sizeof (t->buffer.pre_data)); + + return s; +} + +static u8 * format_pg_interface_name (u8 * s, va_list * args) { pg_main_t *pg = &pg_main; @@ -125,6 +144,7 @@ VNET_DEVICE_CLASS (pg_dev_class) = { .name = "pg", .tx_function = pg_output, .format_device_name = format_pg_interface_name, + .format_tx_trace = format_pg_output_trace, .admin_up_down_function = pg_interface_admin_up_down, }; /* *INDENT-ON* */ |