+ return rv;
+}
+
+u32
+vbi (vlib_buffer_t * b)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vlib_buffer_main_t *bm = vm->buffer_main;
+ u32 bi = pointer_to_uword (b) - bm->buffer_mem_start;
+ bi >>= CLIB_LOG2_CACHE_LINE_BYTES;
+ return bi;
+}
+
+int
+gdb_validate_buffer (vlib_buffer_t * b)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ u32 bi = vbi (b);
+ u8 *s =
+ vlib_validate_buffers (vm, &bi, 0, 1, VLIB_BUFFER_KNOWN_ALLOCATED, 1);
+ if (s)
+ {
+ fformat (stderr, "gdb_validate_buffer(): %v", s);
+ return -1;
+ }
+ fformat (stderr, "gdb_validate_buffer(): no error found\n");
+ return 0;
+}
+
+/**
+ * Dump a trajectory trace, reasonably easy to call from gdb
+ */
+void
+gdb_dump_trajectory_trace (u32 bi)
+{
+#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
+ vlib_main_t *vm = vlib_get_main ();
+ vlib_node_main_t *vnm = &vm->node_main;
+ vlib_buffer_t *b;
+ u16 *trace;
+ u8 i;
+
+ b = vlib_get_buffer (vm, bi);
+
+ trace = b->trajectory_trace;
+
+ fformat (stderr, "Context trace for bi %d b 0x%llx, visited %d\n", bi, b,
+ b->trajectory_nb);
+
+ for (i = 0; i < b->trajectory_nb; i++)
+ {
+ u32 node_index;
+
+ node_index = trace[i];
+
+ if (node_index >= vec_len (vnm->nodes))
+ {
+ fformat (stderr, "Skip bogus node index %d\n", node_index);
+ continue;
+ }
+
+ fformat (stderr, "%v (%d)\n", vnm->nodes[node_index]->name, node_index);
+ }
+#else
+ fformat (stderr, "in vlib/buffers.h, "
+ "#define VLIB_BUFFER_TRACE_TRAJECTORY 1\n");
+
+#endif
+}
+
+void
+gdb_dump_buffer (vlib_buffer_t *b)
+{
+ fformat (stderr, "%U\n", format_vnet_buffer, b);