diff options
-rw-r--r-- | src/vlib/node.c | 20 | ||||
-rw-r--r-- | src/vlib/node_funcs.h | 3 | ||||
-rw-r--r-- | src/vnet/dpo/dpo.c | 17 |
3 files changed, 39 insertions, 1 deletions
diff --git a/src/vlib/node.c b/src/vlib/node.c index eecad2747ba..2cda0f06475 100644 --- a/src/vlib/node.c +++ b/src/vlib/node.c @@ -151,6 +151,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, diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h index 4d7cc1928f3..3c33041c11e 100644 --- a/src/vlib/node_funcs.h +++ b/src/vlib/node_funcs.h @@ -1068,6 +1068,9 @@ vlib_node_vectors_per_main_loop_as_integer (vlib_main_t * vm, u32 node_index) void vlib_frame_free (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_frame_t * f); +/* Return the edge index if present, ~0 otherwise */ +uword vlib_node_get_next (vlib_main_t * vm, uword node, uword next_node); + /* Add next node to given node in given slot. */ uword vlib_node_add_next_with_slot (vlib_main_t * vm, diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c index 28aa0c23351..389f995bb96 100644 --- a/src/vnet/dpo/dpo.c +++ b/src/vnet/dpo/dpo.c @@ -327,6 +327,8 @@ dpo_get_next_node (dpo_type_t child_type, vm = vlib_get_main(); + vlib_worker_thread_barrier_sync(vm); + ASSERT(NULL != dpo_nodes[child_type]); ASSERT(NULL != dpo_nodes[child_type][child_proto]); ASSERT(NULL != dpo_nodes[parent_type]); @@ -368,6 +370,8 @@ dpo_get_next_node (dpo_type_t child_type, } cc++; } + + vlib_worker_thread_barrier_release(vm); } return (dpo_edges[child_type][child_proto][parent_type][parent_proto]); @@ -445,10 +449,21 @@ dpo_stack_from_node (u32 child_node_index, parent_node = vlib_get_node_by_name(vm, (u8*) dpo_nodes[parent_type][parent_proto][0]); - edge = vlib_node_add_next(vm, + edge = vlib_node_get_next(vm, child_node_index, parent_node->index); + if (~0 == edge) + { + vlib_worker_thread_barrier_sync(vm); + + edge = vlib_node_add_next(vm, + child_node_index, + parent_node->index); + + vlib_worker_thread_barrier_release(vm); + } + dpo_stack_i(edge, dpo, parent); } |