summaryrefslogtreecommitdiffstats
path: root/src/vlib/node.c
diff options
context:
space:
mode:
authorMohammed Hawari <mohammed@hawari.fr>2024-08-29 14:01:06 +0200
committerDamjan Marion <dmarion@0xa5.net>2024-09-12 10:11:30 +0000
commit3b5a013103f0eff44afbdc4937407a82931edd00 (patch)
treedcace32773735e02fb26835f277d85b06b0f5313 /src/vlib/node.c
parent47968438dc42931952d39300fcc7b5e36239857b (diff)
vlib: introduce lazy next node initialization
This change allow a node registration A to name a next node B that does not exist yet at registration time. When node B is effectively created, vlib_node_main_lazy_next_update need to be called so that the vlib graph is updated accordingly. To enable this behavior, node A needs to bear the new VLIB_NODE_FLAG_ALLOW_LAZY_NEXT_NODES. Change-Id: I561d3a0de19a0b7bd1045760a2ba8e27d27caa9a Type: improvement Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
Diffstat (limited to 'src/vlib/node.c')
-rw-r--r--src/vlib/node.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/src/vlib/node.c b/src/vlib/node.c
index 8f6c852188b..c0572f3cf83 100644
--- a/src/vlib/node.c
+++ b/src/vlib/node.c
@@ -805,7 +805,8 @@ vlib_node_main_init (vlib_main_t * vm)
if (!a)
continue;
- if (~0 == vlib_node_add_named_next_with_slot (vm, n->index, a, i))
+ if (~0 == vlib_node_add_named_next_with_slot (vm, n->index, a, i) &&
+ !(n->flags & VLIB_NODE_FLAG_ALLOW_LAZY_NEXT_NODES))
{
error = clib_error_create
("node `%v' refers to unknown node `%s'", n->name, a);
@@ -813,7 +814,8 @@ vlib_node_main_init (vlib_main_t * vm)
}
}
- vec_free (n->next_node_names);
+ if (!(n->flags & VLIB_NODE_FLAG_ALLOW_LAZY_NEXT_NODES))
+ vec_free (n->next_node_names);
}
/* Set previous node pointers. */
@@ -851,14 +853,18 @@ vlib_node_main_init (vlib_main_t * vm)
for (i = 0; i < vec_len (n->next_nodes); i++)
{
- next = vlib_get_node (vm, n->next_nodes[i]);
+ if (n->flags & VLIB_NODE_FLAG_ALLOW_LAZY_NEXT_NODES &&
+ n->next_nodes[i] >= vec_len (nm->nodes))
+ continue;
- /* Validate node runtime indices are correctly initialized. */
- ASSERT (nf[i].node_runtime_index == next->runtime_index);
+ next = vlib_get_node (vm, n->next_nodes[i]);
- nf[i].flags = 0;
- if (next->flags & VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH)
- nf[i].flags |= VLIB_FRAME_NO_FREE_AFTER_DISPATCH;
+ /* Validate node runtime indices are correctly initialized. */
+ ASSERT (nf[i].node_runtime_index == next->runtime_index);
+
+ nf[i].flags = 0;
+ if (next->flags & VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH)
+ nf[i].flags |= VLIB_FRAME_NO_FREE_AFTER_DISPATCH;
}
}
}
@@ -927,6 +933,33 @@ vlib_node_set_march_variant (vlib_main_t *vm, u32 node_index,
}
return -1;
}
+
+clib_error_t *
+vlib_node_main_lazy_next_update (vlib_main_t *vm)
+{
+ vlib_node_main_t *nm = &vm->node_main;
+ uword ni;
+ vlib_node_t *n;
+ for (ni = 0; ni < vec_len (nm->nodes); ni++)
+ {
+ uword nni;
+ n = vec_elt (nm->nodes, ni);
+
+ if (!(n->flags & VLIB_NODE_FLAG_ALLOW_LAZY_NEXT_NODES))
+ continue;
+
+ for (nni = 0; nni < vec_len (n->next_node_names); nni++)
+ {
+ char *a = n->next_node_names[nni];
+
+ if (!a)
+ continue;
+
+ vlib_node_add_named_next_with_slot (vm, n->index, a, nni);
+ }
+ }
+ return 0;
+}
/*
* fd.io coding-style-patch-verification: ON
*