summaryrefslogtreecommitdiffstats
path: root/src/vlib/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vlib/node.c')
-rw-r--r--src/vlib/node.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/vlib/node.c b/src/vlib/node.c
index e6739dc7cf9..17dd2ea87d4 100644
--- a/src/vlib/node.c
+++ b/src/vlib/node.c
@@ -543,6 +543,60 @@ vlib_register_all_static_nodes (vlib_main_t * vm)
}
}
+vlib_node_t ***
+vlib_node_get_nodes (vlib_main_t * vm, u32 max_threads, int include_stats)
+{
+ vlib_node_main_t *nm = &vm->node_main;
+ vlib_node_t *n;
+ static vlib_node_t ***node_dups;
+ vlib_node_t **nodes;
+ static vlib_main_t **stat_vms;
+ vlib_main_t *stat_vm;
+ uword i, j;
+ u32 threads_to_serialize;
+
+ vec_reset_length (node_dups);
+
+ if (vec_len (stat_vms) == 0)
+ {
+ for (i = 0; i < vec_len (vlib_mains); i++)
+ {
+ stat_vm = vlib_mains[i];
+ if (stat_vm)
+ vec_add1 (stat_vms, stat_vm);
+ }
+ }
+
+ threads_to_serialize = clib_min (max_threads, vec_len (stat_vms));
+
+ /*
+ * Barrier sync across stats scraping.
+ * Otherwise, the counts will be grossly inaccurate.
+ */
+ vlib_worker_thread_barrier_sync (vm);
+
+ for (j = 0; j < threads_to_serialize; j++)
+ {
+ stat_vm = stat_vms[j];
+ nm = &stat_vm->node_main;
+
+ if (include_stats)
+ {
+ for (i = 0; i < vec_len (nm->nodes); i++)
+ {
+ n = nm->nodes[i];
+ vlib_node_sync_stats (stat_vm, n);
+ }
+ }
+
+ nodes = vec_dup (nm->nodes);
+ vec_add1 (node_dups, nodes);
+ }
+ vlib_worker_thread_barrier_release (vm);
+
+ return node_dups;
+}
+
clib_error_t *
vlib_node_main_init (vlib_main_t * vm)
{