FD.io VPP  v21.06
Vector Packet Processing
trace.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * trace.c: VLIB trace buffer.
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vlib/vlib.h>
41 #include <vlib/threads.h>
43 
45 
46 /* Helper function for nodes which only trace buffer data. */
47 void
50  u32 * buffers,
52  uword next_buffer_stride,
53  uword n_buffer_data_bytes_in_trace)
54 {
55  u32 n_left, *from;
56 
57  n_left = n_buffers;
58  from = buffers;
59 
60  while (n_left >= 4)
61  {
62  u32 bi0, bi1;
63  vlib_buffer_t *b0, *b1;
64  u8 *t0, *t1;
65 
66  /* Prefetch next iteration. */
67  vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
68  vlib_prefetch_buffer_with_index (vm, from[3], LOAD);
69 
70  bi0 = from[0];
71  bi1 = from[1];
72 
73  b0 = vlib_get_buffer (vm, bi0);
74  b1 = vlib_get_buffer (vm, bi1);
75 
76  if (b0->flags & VLIB_BUFFER_IS_TRACED)
77  {
78  t0 = vlib_add_trace (vm, node, b0, n_buffer_data_bytes_in_trace);
79  clib_memcpy_fast (t0, b0->data + b0->current_data,
80  n_buffer_data_bytes_in_trace);
81  }
82  if (b1->flags & VLIB_BUFFER_IS_TRACED)
83  {
84  t1 = vlib_add_trace (vm, node, b1, n_buffer_data_bytes_in_trace);
85  clib_memcpy_fast (t1, b1->data + b1->current_data,
86  n_buffer_data_bytes_in_trace);
87  }
88  from += 2;
89  n_left -= 2;
90  }
91 
92  while (n_left >= 1)
93  {
94  u32 bi0;
95  vlib_buffer_t *b0;
96  u8 *t0;
97 
98  bi0 = from[0];
99 
100  b0 = vlib_get_buffer (vm, bi0);
101 
102  if (b0->flags & VLIB_BUFFER_IS_TRACED)
103  {
104  t0 = vlib_add_trace (vm, node, b0, n_buffer_data_bytes_in_trace);
105  clib_memcpy_fast (t0, b0->data + b0->current_data,
106  n_buffer_data_bytes_in_trace);
107  }
108  from += 1;
109  n_left -= 1;
110  }
111 }
112 
113 /* Free up all trace buffer memory. */
114 void
116 {
117  int i;
118  vlib_trace_main_t *tm;
119 
121  {
122  tm = &this_vlib_main->trace_main;
123 
124  tm->trace_enable = 0;
125  vec_free (tm->nodes);
126  }
127 
129  {
130  tm = &this_vlib_main->trace_main;
131 
132  for (i = 0; i < vec_len (tm->trace_buffer_pool); i++)
134  vec_free (tm->trace_buffer_pool[i]);
136  }
137 }
138 
139 u8 *
140 format_vlib_trace (u8 * s, va_list * va)
141 {
142  vlib_main_t *vm = va_arg (*va, vlib_main_t *);
143  vlib_trace_header_t *h = va_arg (*va, vlib_trace_header_t *);
144  vlib_trace_header_t *e = vec_end (h);
145  vlib_node_t *node, *prev_node;
146  clib_time_t *ct = &vm->clib_time;
147  f64 t;
148 
149  prev_node = 0;
150  while (h < e)
151  {
152  node = vlib_get_node (vm, h->node_index);
153 
154  if (node != prev_node)
155  {
156  t =
158  s =
159  format (s, "\n%U: %v", format_time_interval, "h:m:s:u", t,
160  node->name);
161  }
162  prev_node = node;
163 
164  if (node->format_trace)
165  s = format (s, "\n %U", node->format_trace, vm, node, h->data);
166  else
167  s = format (s, "\n %U", node->format_buffer, h->data);
168 
169  h = vlib_trace_header_next (h);
170  }
171 
172  return s;
173 }
174 
175 /* Root of all trace cli commands. */
176 /* *INDENT-OFF* */
177 VLIB_CLI_COMMAND (trace_cli_command,static) = {
178  .path = "trace",
179  .short_help = "Packet tracer commands",
180 };
181 /* *INDENT-ON* */
182 
183 int
184 trace_time_cmp (void *a1, void *a2)
185 {
186  vlib_trace_header_t **t1 = a1;
187  vlib_trace_header_t **t2 = a2;
188  i64 dt = t1[0]->time - t2[0]->time;
189  return dt < 0 ? -1 : (dt > 0 ? +1 : 0);
190 }
191 
192 /*
193  * Return 1 if this packet passes the trace filter, or 0 otherwise
194  */
195 u32
197 {
198  vlib_trace_header_t *e = vec_end (h);
199 
200  if (tm->filter_flag == 0)
201  return 1;
202 
203  /*
204  * When capturing a post-mortem dispatch trace,
205  * toss all existing traces once per dispatch cycle.
206  * So we can trace 4 billion pkts without running out of
207  * memory...
208  */
210  return 0;
211 
212  if (tm->filter_flag == FILTER_FLAG_INCLUDE)
213  {
214  while (h < e)
215  {
216  if (h->node_index == tm->filter_node_index)
217  return 1;
218  h = vlib_trace_header_next (h);
219  }
220  return 0;
221  }
222  else /* FILTER_FLAG_EXCLUDE */
223  {
224  while (h < e)
225  {
226  if (h->node_index == tm->filter_node_index)
227  return 0;
228  h = vlib_trace_header_next (h);
229  }
230  return 1;
231  }
232 
233  return 0;
234 }
235 
236 /*
237  * Remove traces from the trace buffer pool that don't pass the filter
238  */
239 void
241 {
242  vlib_trace_main_t *tm = &vm->trace_main;
244  vlib_trace_header_t ***traces_to_remove = 0;
245  u32 index;
246  u32 trace_index;
247  u32 n_accepted;
248 
249  u32 accept;
250 
251  if (tm->filter_flag == FILTER_FLAG_NONE)
252  return;
253 
254  /*
255  * Ideally we would retain the first N traces that pass the filter instead
256  * of any N traces.
257  */
258  n_accepted = 0;
259  /* *INDENT-OFF* */
261  {
262  accept = filter_accept(tm, h[0]);
263 
264  if ((n_accepted == tm->filter_count) || !accept)
265  vec_add1 (traces_to_remove, h);
266  else
267  n_accepted++;
268  }
269  /* *INDENT-ON* */
270 
271  /* remove all traces that we don't want to keep */
272  for (index = 0; index < vec_len (traces_to_remove); index++)
273  {
274  trace_index = traces_to_remove[index] - tm->trace_buffer_pool;
275  _vec_len (tm->trace_buffer_pool[trace_index]) = 0;
276  pool_put_index (tm->trace_buffer_pool, trace_index);
277  }
278 
279  vec_free (traces_to_remove);
280 }
281 
282 static clib_error_t *
284  unformat_input_t * input, vlib_cli_command_t * cmd)
285 {
286  vlib_trace_main_t *tm;
287  vlib_trace_header_t **h, **traces;
288  u32 i, index = 0;
289  char *fmt;
290  u8 *s = 0;
291  u32 max;
292 
293  /*
294  * By default display only this many traces. To display more, explicitly
295  * specify a max. This prevents unexpectedly huge outputs.
296  */
297  max = 50;
299  {
300  if (unformat (input, "max %d", &max))
301  ;
302  else
303  return clib_error_create ("expected 'max COUNT', got `%U'",
304  format_unformat_error, input);
305  }
306 
307 
308  /* Get active traces from pool. */
309 
311  {
312  fmt = "------------------- Start of thread %d %s -------------------\n";
313  s = format (s, fmt, index, vlib_worker_threads[index].name);
314 
315  tm = &this_vlib_main->trace_main;
316 
317  trace_apply_filter (this_vlib_main);
318 
319  traces = 0;
321  {
322  vec_add1 (traces, h[0]);
323  }
324 
325  if (vec_len (traces) == 0)
326  {
327  s = format (s, "No packets in trace buffer\n");
328  goto done;
329  }
330 
331  /* Sort them by increasing time. */
333 
334  for (i = 0; i < vec_len (traces); i++)
335  {
336  if (i == max)
337  {
338  char *warn = "Limiting display to %d packets."
339  " To display more specify max.";
340  vlib_cli_output (vm, warn, max);
341  s = format (s, warn, max);
342  goto done;
343  }
344 
345  s = format (s, "Packet %d\n%U\n\n", i + 1, format_vlib_trace, vm,
346  traces[i]);
347  }
348 
349  done:
350  vec_free (traces);
351 
352  index++;
353  }
354 
355  vlib_cli_output (vm, "%v", s);
356  vec_free (s);
357  return 0;
358 }
359 
360 /* *INDENT-OFF* */
361 VLIB_CLI_COMMAND (show_trace_cli,static) = {
362  .path = "show trace",
363  .short_help = "Show trace buffer [max COUNT]",
364  .function = cli_show_trace_buffer,
365 };
366 /* *INDENT-ON* */
367 
368 int vlib_enable_disable_pkt_trace_filter (int enable) __attribute__ ((weak));
369 
370 int
372 {
373  return 0;
374 }
375 
376 void
378 {
379  vlib_enable_disable_pkt_trace_filter (0); /* disble tracing */
381 }
382 
383 
384 void
386 {
387  vlib_trace_main_t *tm;
388  vlib_trace_node_t *tn;
389 
390  if (add == ~0)
391  add = 50;
392 
394  {
395  tm = &this_vlib_main->trace_main;
396  tm->verbose = verbose;
397  vec_validate (tm->nodes, node_index);
398  tn = tm->nodes + node_index;
399 
400  /*
401  * Adding 0 makes no real sense, and there wa no other way
402  * to explicilty zero-out the limits and count, so make
403  * an "add 0" request really be "set to 0".
404  */
405  if (add == 0)
406  tn->limit = tn->count = 0;
407  else
408  tn->limit += add;
409  }
410 
412  {
413  tm = &this_vlib_main->trace_main;
414  tm->trace_enable = 1;
415  }
416 
418 }
419 
420 static clib_error_t *
422  unformat_input_t * input, vlib_cli_command_t * cmd)
423 {
424  unformat_input_t _line_input, *line_input = &_line_input;
425  vlib_node_t *node;
426  u32 node_index, add;
427  u8 verbose = 0;
428  int filter = 0;
429  clib_error_t *error = 0;
430 
431  if (!unformat_user (input, unformat_line_input, line_input))
432  return 0;
433 
434  if (vnet_trace_placeholder == 0)
437 
438  while (unformat_check_input (line_input) != (uword) UNFORMAT_END_OF_INPUT)
439  {
440  if (unformat (line_input, "%U %d",
441  unformat_vlib_node, vm, &node_index, &add))
442  ;
443  else if (unformat (line_input, "verbose"))
444  verbose = 1;
445  else if (unformat (line_input, "filter"))
446  filter = 1;
447  else
448  {
449  error = clib_error_create ("expected NODE COUNT, got `%U'",
450  format_unformat_error, line_input);
451  goto done;
452  }
453  }
454 
455  node = vlib_get_node (vm, node_index);
456 
457  if ((node->flags & VLIB_NODE_FLAG_TRACE_SUPPORTED) == 0)
458  {
459  error = clib_error_create ("node '%U' doesn't support per-node "
460  "tracing. There may be another way to "
461  "initiate trace on this node.",
462  format_vlib_node_name, vm, node_index);
463  goto done;
464  }
465 
466  u32 filter_table = classify_get_trace_chain ();
467  if (filter && filter_table == ~0)
468  {
469  error = clib_error_create ("No packet trace filter configured...");
470  goto done;
471  }
472 
473  trace_update_capture_options (add, node_index, filter, verbose);
474 
475 done:
476  unformat_free (line_input);
477 
478  return error;
479 }
480 
481 /* *INDENT-OFF* */
482 VLIB_CLI_COMMAND (add_trace_cli,static) = {
483  .path = "trace add",
484  .short_help = "trace add <input-graph-node> <add'l-pkts-for-node-> [filter] [verbose]",
485  .function = cli_add_trace_buffer,
486 };
487 /* *INDENT-ON* */
488 
489 /*
490  * Configure a filter for packet traces.
491  *
492  * This supplements the packet trace feature so that only packets matching
493  * the filter are included in the trace. Currently the only filter is to
494  * keep packets that include a certain node in the trace or exclude a certain
495  * node in the trace.
496  *
497  * The count of traced packets in the "trace add" command is still used to
498  * create a certain number of traces. The "trace filter" command specifies
499  * how many of those packets should be retained in the trace.
500  *
501  * For example, 1Mpps of traffic is arriving and one of those packets is being
502  * dropped. To capture the trace for only that dropped packet, you can do:
503  * trace filter include error-drop 1
504  * trace add dpdk-input 1000000
505  * <wait one second>
506  * show trace
507  *
508  * Note that the filter could be implemented by capturing all traces and just
509  * reducing traces displayed by the "show trace" function. But that would
510  * require a lot of memory for storing the traces, making that infeasible.
511  *
512  * To remove traces from the trace pool that do not include a certain node
513  * requires that the trace be "complete" before applying the filter. To
514  * accomplish this, the trace pool is filtered upon each iteraction of the
515  * main vlib loop. Doing so keeps the number of allocated traces down to a
516  * reasonably low number. This requires that tracing for a buffer is not
517  * performed after the vlib main loop interation completes. i.e. you can't
518  * save away a buffer temporarily then inject it back into the graph and
519  * expect that the trace_index is still valid (such as a traffic manager might
520  * do). A new trace buffer should be allocated for those types of packets.
521  *
522  * The filter can be extended to support multiple nodes and other match
523  * criteria (e.g. input sw_if_index, mac address) but for now just checks if
524  * a specified node is in the trace or not in the trace.
525  */
526 
527 void
529 {
531  {
532  vlib_trace_main_t *tm;
533 
534  tm = &this_vlib_main->trace_main;
536  tm->filter_flag = flag;
537  tm->filter_count = count;
538 
539  /*
540  * Clear the trace limits to stop any in-progress tracing
541  * Prevents runaway trace allocations when the filter changes
542  * (or is removed)
543  */
544  vec_free (tm->nodes);
545  }
546 }
547 
548 
549 static clib_error_t *
551  unformat_input_t * input, vlib_cli_command_t * cmd)
552 {
553  u32 filter_node_index;
554  u32 filter_flag;
555  u32 filter_count;
556 
557  if (unformat (input, "include %U %d",
558  unformat_vlib_node, vm, &filter_node_index, &filter_count))
559  {
560  filter_flag = FILTER_FLAG_INCLUDE;
561  }
562  else if (unformat (input, "exclude %U %d",
563  unformat_vlib_node, vm, &filter_node_index,
564  &filter_count))
565  {
566  filter_flag = FILTER_FLAG_EXCLUDE;
567  }
568  else if (unformat (input, "none"))
569  {
570  filter_flag = FILTER_FLAG_NONE;
571  filter_node_index = 0;
572  filter_count = 0;
573  }
574  else
575  return
577  ("expected 'include NODE COUNT' or 'exclude NODE COUNT' or 'none', got `%U'",
578  format_unformat_error, input);
579 
580  trace_filter_set (filter_node_index, filter_flag, filter_count);
581 
582  return 0;
583 }
584 
585 /* *INDENT-OFF* */
586 VLIB_CLI_COMMAND (filter_trace_cli,static) = {
587  .path = "trace filter",
588  .short_help = "trace filter none | [include|exclude] NODE COUNT",
589  .function = cli_filter_trace,
590 };
591 /* *INDENT-ON* */
592 
593 static clib_error_t *
595  unformat_input_t * input, vlib_cli_command_t * cmd)
596 {
598  return 0;
599 }
600 
601 /* *INDENT-OFF* */
602 VLIB_CLI_COMMAND (clear_trace_cli,static) = {
603  .path = "clear trace",
604  .short_help = "Clear trace buffer and free memory",
605  .function = cli_clear_trace_buffer,
606 };
607 /* *INDENT-ON* */
608 
609 /* Placeholder function to get us linked in. */
610 void
612 {
613 }
614 
615 int
617  u32 classify_table_index, int func)
618 __attribute__ ((weak));
619 
620 int
622 {
623  clib_warning ("BUG: STUB called");
624  return 1;
625 }
626 
627 void *
629  vlib_node_runtime_t * r, vlib_buffer_t * b, u32 n_data_bytes)
630 {
631  return vlib_add_trace_inline (vm, r, b, n_data_bytes);
632 }
633 
634 
635 
636 /*
637  * fd.io coding-style-patch-verification: ON
638  *
639  * Local Variables:
640  * eval: (c-set-style "gnu")
641  * End:
642  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:133
u32 filter_flag
Definition: trace.h:90
void vlib_trace_cli_reference(void)
Definition: trace.c:611
format_function_t format_vlib_node_name
Definition: node_funcs.h:1235
vnet_hw_if_output_node_runtime_t * r
vlib_trace_node_t * nodes
Definition: trace.h:101
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
static clib_error_t * cli_clear_trace_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: trace.c:594
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
static vlib_trace_header_t * vlib_trace_header_next(vlib_trace_header_t *h)
Definition: trace_funcs.h:117
#define VLIB_NODE_FLAG_TRACE_SUPPORTED
Definition: node.h:296
static void * vlib_add_trace_inline(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
format_function_t * format_trace
Definition: node.h:353
u16 flags
Definition: node.h:279
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
void trace_filter_set(u32 node_index, u32 flag, u32 count)
Definition: trace.c:528
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
string name[64]
Definition: fib.api:25
clib_time_t clib_time
Definition: main.h:106
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:535
void trace_update_capture_options(u32 add, u32 node_index, u32 filter, u8 verbose)
Definition: trace.c:385
unsigned char u8
Definition: types.h:56
u32 filter_node_index
Definition: trace.h:89
double f64
Definition: types.h:142
unsigned int u32
Definition: types.h:88
#define foreach_vlib_main()
Definition: threads.h:237
static clib_error_t * cli_show_trace_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: trace.c:283
vlib_trace_header_t ** trace_buffer_pool
Definition: trace.h:86
u32 trace_enable
Definition: trace.h:98
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
Definition: buffer_funcs.h:507
description fragment has unexpected format
Definition: map.api:433
#define vec_end(v)
End (last data address) of vector.
#define clib_error_create(args...)
Definition: error.h:96
u64 cpu_time_main_loop_start
Definition: main.h:115
u32 filter_accept(vlib_trace_main_t *tm, vlib_trace_header_t *h)
Definition: trace.c:196
u8 * vnet_trace_placeholder
Definition: trace.c:44
unformat_function_t unformat_line_input
Definition: format.h:275
Definition: cJSON.c:88
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:35
#define FILTER_FLAG_EXCLUDE
Definition: trace.h:93
u8 * format_vlib_trace(u8 *s, va_list *va)
Definition: trace.c:140
struct _unformat_input_t unformat_input_t
signed long i64
Definition: types.h:78
#define FILTER_FLAG_NONE
Definition: trace.h:91
f64 seconds_per_clock
Definition: time.h:58
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
format_function_t * format_buffer
Definition: node.h:349
void vlib_trace_stop_and_clear(void)
Definition: trace.c:377
u32 n_left
int cJSON_bool fmt
Definition: cJSON.h:160
u8 * name
Definition: node.h:254
u32 filter_count
Definition: trace.h:95
#define pool_free(p)
Free a pool.
Definition: pool.h:447
u32 classify_table_index
Definition: fib_types.api:68
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
void classify_get_trace_chain(void)
static clib_error_t * cli_filter_trace(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: trace.c:550
static clib_error_t * cli_add_trace_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: trace.c:421
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
u32 index
Definition: flow_types.api:221
#define clib_warning(format, args...)
Definition: error.h:59
#define FILTER_FLAG_POST_MORTEM
Definition: trace.h:94
u8 data[]
Packet data.
Definition: buffer.h:204
int trace_time_cmp(void *a1, void *a2)
Definition: trace.c:184
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
u32 n_buffers
vlib_trace_main_t trace_main
Definition: main.h:174
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
void vlib_trace_frame_buffers_only(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, uword n_buffers, uword next_buffer_stride, uword n_buffer_data_bytes_in_trace)
Definition: trace.c:48
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
int vlib_enable_disable_pkt_trace_filter(int enable)
Enable / disable packet trace filter.
Definition: trace.c:371
VLIB buffer representation.
Definition: buffer.h:111
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1098
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
int vnet_is_packet_traced(vlib_buffer_t *b, u32 classify_table_index, int func)
Definition: trace.c:621
node node_index
u8 * format_time_interval(u8 *s, va_list *args)
Definition: std-formats.c:138
unformat_function_t unformat_vlib_node
Definition: node_funcs.h:1241
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:86
u8 count
Definition: dhcp.api:208
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
void clear_trace_buffer(void)
Definition: trace.c:115
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
void trace_apply_filter(vlib_main_t *vm)
Definition: trace.c:240
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
#define FILTER_FLAG_INCLUDE
Definition: trace.h:92