X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fnode.c;h=17dd2ea87d42e76271fb37d3be1e7cf61ec60812;hb=1f6e9288536ee30db3911ccea1ea10af4b6b3e5e;hp=eecad2747ba7bdbf75ac1487eb00efc5c4d042ed;hpb=93992a9048cb6e5dcd22de5091e72de778122627;p=vpp.git diff --git a/src/vlib/node.c b/src/vlib/node.c index eecad2747ba..17dd2ea87d4 100644 --- a/src/vlib/node.c +++ b/src/vlib/node.c @@ -72,6 +72,32 @@ node_set_elog_name (vlib_main_t * vm, uword node_index) n->name_elog_string = elog_string (&vm->elog_main, "%v%c", n->name, 0); } +static void +vlib_worker_thread_node_rename (u32 node_index) +{ + int i; + vlib_main_t *vm; + vlib_node_t *n; + + if (vec_len (vlib_mains) == 1) + return; + + vm = vlib_mains[0]; + n = vlib_get_node (vm, node_index); + + ASSERT (vlib_get_thread_index () == 0); + ASSERT (*vlib_worker_threads->wait_at_barrier == 1); + + for (i = 1; i < vec_len (vlib_mains); i++) + { + vlib_main_t *vm_worker = vlib_mains[i]; + vlib_node_t *n_worker = vlib_get_node (vm_worker, node_index); + + n_worker->name = n->name; + n_worker->name_elog_string = n->name_elog_string; + } +} + void vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) { @@ -87,6 +113,9 @@ vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) hash_set (nm->node_by_name, n->name, n->index); node_set_elog_name (vm, node_index); + + /* Propagate the change to all worker threads */ + vlib_worker_thread_node_rename (node_index); } static void @@ -151,6 +180,26 @@ vlib_node_runtime_update (vlib_main_t * vm, u32 node_index, u32 next_index) vlib_worker_thread_barrier_release (vm); } +uword +vlib_node_get_next (vlib_main_t * vm, uword node_index, uword next_node_index) +{ + vlib_node_main_t *nm = &vm->node_main; + vlib_node_t *node; + uword *p; + + node = vec_elt (nm->nodes, node_index); + + /* Runtime has to be initialized. */ + ASSERT (nm->flags & VLIB_NODE_MAIN_RUNTIME_STARTED); + + if ((p = hash_get (node->next_slot_by_node, next_node_index))) + { + return p[0]; + } + + return (~0); +} + /* Add next node to given node in given slot. */ uword vlib_node_add_next_with_slot (vlib_main_t * vm, @@ -494,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) {