aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/vlib')
-rw-r--r--src/vlib/main.c3
-rw-r--r--src/vlib/node.c118
-rw-r--r--src/vlib/node.h56
-rw-r--r--src/vlib/node_cli.c47
-rw-r--r--src/vlib/node_format.c21
-rw-r--r--src/vlib/node_funcs.h10
-rw-r--r--src/vlib/node_init.c156
7 files changed, 218 insertions, 193 deletions
diff --git a/src/vlib/main.c b/src/vlib/main.c
index 111941ce90a..02fdc89ad99 100644
--- a/src/vlib/main.c
+++ b/src/vlib/main.c
@@ -1962,6 +1962,9 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
goto done;
}
+ /* Register node ifunction variants */
+ vlib_register_all_node_march_variants (vm);
+
/* Register static nodes so that init functions may use them. */
vlib_register_all_static_nodes (vm);
diff --git a/src/vlib/node.c b/src/vlib/node.c
index 25e249bdda9..618baecfde0 100644
--- a/src/vlib/node.c
+++ b/src/vlib/node.c
@@ -290,6 +290,43 @@ node_elog_init (vlib_main_t * vm, uword ni)
#define STACK_ALIGN CLIB_CACHE_LINE_BYTES
#endif
+vlib_node_function_t *
+vlib_node_get_preferred_node_fn_variant (vlib_main_t *vm,
+ vlib_node_fn_registration_t *regs)
+{
+ vlib_node_main_t *nm = &vm->node_main;
+ vlib_node_fn_registration_t *r;
+ vlib_node_fn_variant_t *v;
+ vlib_node_function_t *fn = 0;
+ int priority = -1;
+
+ if (nm->node_fn_default_march_variant != ~0)
+ {
+ r = regs;
+ while (r)
+ {
+ if (r->march_variant == nm->node_fn_default_march_variant)
+ return r->function;
+ r = r->next_registration;
+ }
+ }
+
+ r = regs;
+ while (r)
+ {
+ v = vec_elt_at_index (nm->variants, r->march_variant);
+ if (v->priority > priority)
+ {
+ priority = v->priority;
+ fn = r->function;
+ }
+ r = r->next_registration;
+ }
+
+ ASSERT (fn);
+ return fn;
+}
+
static void
register_node (vlib_main_t * vm, vlib_node_registration_t * r)
{
@@ -306,22 +343,12 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r)
if (r->node_fn_registrations)
{
- vlib_node_fn_registration_t *fnr = r->node_fn_registrations;
- int priority = -1;
-
/* to avoid confusion, please remove ".function " statiement from
CLIB_NODE_REGISTRATION() if using function function candidates */
ASSERT (r->function == 0);
- while (fnr)
- {
- if (fnr->priority > priority)
- {
- priority = fnr->priority;
- r->function = fnr->function;
- }
- fnr = fnr->next_registration;
- }
+ r->function =
+ vlib_node_get_preferred_node_fn_variant (vm, r->node_fn_registrations);
}
ASSERT (r->function != 0);
@@ -483,6 +510,7 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r)
vec_free (n->runtime_data);
}
+#undef _
}
/* Register new packet processing node. */
@@ -507,6 +535,40 @@ null_node_fn (vlib_main_t * vm,
}
void
+vlib_register_all_node_march_variants (vlib_main_t *vm)
+{
+ vlib_node_main_t *nm = &vm->node_main;
+ vlib_node_fn_variant_t *v;
+ int prio = -1;
+
+ nm->node_fn_default_march_variant = ~0;
+ ASSERT (nm->variants == 0);
+ vec_add2 (nm->variants, v, 1);
+ v->desc = v->suffix = "default";
+ v->index = CLIB_MARCH_VARIANT_TYPE;
+
+#define _(s, n) \
+ vec_add2 (nm->variants, v, 1); \
+ v->suffix = #s; \
+ v->index = CLIB_MARCH_VARIANT_TYPE_##s; \
+ v->priority = clib_cpu_march_priority_##s (); \
+ v->desc = n;
+
+ foreach_march_variant;
+#undef _
+
+ nm->node_fn_march_variant_by_suffix = hash_create_string (0, sizeof (u32));
+
+ vec_foreach (v, nm->variants)
+ {
+ ASSERT (v->index == v - nm->variants);
+ hash_set (nm->node_fn_march_variant_by_suffix, v->suffix, v->index);
+ if (v->priority > prio)
+ prio = v->priority;
+ }
+}
+
+void
vlib_register_all_static_nodes (vlib_main_t * vm)
{
vlib_node_registration_t *r;
@@ -755,6 +817,38 @@ vlib_process_create (vlib_main_t * vm, char *name,
return (r.index);
}
+int
+vlib_node_set_march_variant (vlib_main_t *vm, u32 node_index,
+ clib_march_variant_type_t march_variant)
+{
+ vlib_node_fn_registration_t *fnr;
+ vlib_node_fn_variant_t *v;
+ vlib_node_t *n = vlib_get_node (vm, node_index);
+
+ if (n->node_fn_registrations == 0)
+ return -1;
+
+ fnr = n->node_fn_registrations;
+ v = vec_elt_at_index (vm->node_main.variants, march_variant);
+
+ while (fnr)
+ {
+ if (fnr->march_variant == v->index)
+ {
+ n->function = fnr->function;
+
+ for (int i = 0; i < vec_len (vlib_mains); i++)
+ {
+ vlib_node_runtime_t *nrt;
+ nrt = vlib_node_get_runtime (vlib_mains[i], n->index);
+ nrt->function = fnr->function;
+ }
+ return 0;
+ }
+ fnr = fnr->next_registration;
+ }
+ return -1;
+}
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vlib/node.h b/src/vlib/node.h
index 0c815eaa4d2..9a3bb8370af 100644
--- a/src/vlib/node.h
+++ b/src/vlib/node.h
@@ -89,9 +89,8 @@ typedef enum
typedef struct _vlib_node_fn_registration
{
vlib_node_function_t *function;
- int priority;
+ clib_march_variant_type_t march_variant;
struct _vlib_node_fn_registration *next_registration;
- char *name;
} vlib_node_fn_registration_t;
typedef struct _vlib_node_registration
@@ -200,24 +199,24 @@ static __clib_unused vlib_node_registration_t __clib_unused_##x
#define CLIB_MARCH_VARIANT_STR _CLIB_MARCH_VARIANT_STR(CLIB_MARCH_VARIANT)
#endif
-#define VLIB_NODE_FN(node) \
-uword CLIB_MARCH_SFX (node##_fn)(); \
-static vlib_node_fn_registration_t \
- CLIB_MARCH_SFX(node##_fn_registration) = \
- { .function = &CLIB_MARCH_SFX (node##_fn), }; \
- \
-static void __clib_constructor \
-CLIB_MARCH_SFX (node##_multiarch_register) (void) \
-{ \
- extern vlib_node_registration_t node; \
- vlib_node_fn_registration_t *r; \
- r = & CLIB_MARCH_SFX (node##_fn_registration); \
- r->priority = CLIB_MARCH_FN_PRIORITY(); \
- r->name = CLIB_MARCH_VARIANT_STR; \
- r->next_registration = node.node_fn_registrations; \
- node.node_fn_registrations = r; \
-} \
-uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn)
+#define VLIB_NODE_FN(node) \
+ uword CLIB_MARCH_SFX (node##_fn) (); \
+ static vlib_node_fn_registration_t CLIB_MARCH_SFX ( \
+ node##_fn_registration) = { \
+ .function = &CLIB_MARCH_SFX (node##_fn), \
+ }; \
+ \
+ static void __clib_constructor CLIB_MARCH_SFX (node##_multiarch_register) ( \
+ void) \
+ { \
+ extern vlib_node_registration_t node; \
+ vlib_node_fn_registration_t *r; \
+ r = &CLIB_MARCH_SFX (node##_fn_registration); \
+ r->march_variant = CLIB_MARCH_SFX (CLIB_MARCH_VARIANT_TYPE); \
+ r->next_registration = node.node_fn_registrations; \
+ node.node_fn_registrations = r; \
+ } \
+ uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn)
unformat_function_t unformat_vlib_node_variant;
@@ -657,6 +656,14 @@ vlib_timing_wheel_data_get_index (u32 d)
typedef struct
{
+ clib_march_variant_type_t index;
+ int priority;
+ char *suffix;
+ char *desc;
+} vlib_node_fn_variant_t;
+
+typedef struct
+{
/* Public nodes. */
vlib_node_t **nodes;
@@ -727,6 +734,15 @@ typedef struct
/* Node index from error code */
u32 *node_by_error;
+
+ /* Node Function Variants */
+ vlib_node_fn_variant_t *variants;
+
+ /* Node Function Default Variant Index */
+ u32 node_fn_default_march_variant;
+
+ /* Node Function march Variant by Suffix Hash */
+ uword *node_fn_march_variant_by_suffix;
} vlib_node_main_t;
typedef u16 vlib_error_t;
diff --git a/src/vlib/node_cli.c b/src/vlib/node_cli.c
index c5458b218bf..1c0780517b5 100644
--- a/src/vlib/node_cli.c
+++ b/src/vlib/node_cli.c
@@ -618,13 +618,15 @@ show_node (vlib_main_t * vm, unformat_input_t * input,
if (n->node_fn_registrations)
{
vlib_node_fn_registration_t *fnr = n->node_fn_registrations;
+ vlib_node_fn_variant_t *v;
while (fnr)
{
+ v = vec_elt_at_index (vm->node_main.variants, fnr->march_variant);
if (vec_len (s) == 0)
- s = format (s, "\n %-15s %=8s %6s",
- "Name", "Priority", "Active");
- s = format (s, "\n %-15s %8d %=6s", fnr->name, fnr->priority,
- fnr->function == n->function ? "yes" : "");
+ s = format (s, "\n %-15s %=8s %6s %s", "Name", "Priority",
+ "Active", "Description");
+ s = format (s, "\n %-15s %8d %=6s %s", v->suffix, v->priority,
+ fnr->function == n->function ? "yes" : "", v->desc);
fnr = fnr->next_registration;
}
}
@@ -712,11 +714,9 @@ static clib_error_t *
set_node_fn(vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
- u32 node_index;
+ u32 node_index, march_variant;
vlib_node_t *n;
clib_error_t *err = 0;
- vlib_node_fn_registration_t *fnr;
- u8 *variant = 0;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
@@ -727,9 +727,9 @@ set_node_fn(vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd
goto done;
}
- if (!unformat (line_input, "%U", unformat_vlib_node_variant, &variant))
+ if (!unformat (line_input, "%U", unformat_vlib_node_variant, &march_variant))
{
- err = clib_error_return (0, "please specify node functional variant");
+ err = clib_error_return (0, "please specify node function variant");
goto done;
}
@@ -737,36 +737,21 @@ set_node_fn(vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd
if (n->node_fn_registrations == 0)
{
- err = clib_error_return (0, "node doesn't have functional variants");
+ err = clib_error_return (0, "node doesn't have function variants");
goto done;
}
- fnr = n->node_fn_registrations;
- vec_add1 (variant, 0);
-
- while (fnr)
+ if (vlib_node_set_march_variant (vm, node_index, march_variant))
{
- if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1))
- {
- int i;
-
- n->function = fnr->function;
-
- for (i = 0; i < vec_len (vlib_mains); i++)
- {
- vlib_node_runtime_t *nrt;
- nrt = vlib_node_get_runtime (vlib_mains[i], n->index);
- nrt->function = fnr->function;
- }
- goto done;
- }
- fnr = fnr->next_registration;
+ vlib_node_fn_variant_t *v;
+ v = vec_elt_at_index (vm->node_main.variants, march_variant);
+ err = clib_error_return (0, "node function variant '%s' not found",
+ v->suffix);
+ goto done;
}
- err = clib_error_return (0, "node functional variant '%s' not found", variant);
done:
- vec_free (variant);
unformat_free (line_input);
return err;
}
diff --git a/src/vlib/node_format.c b/src/vlib/node_format.c
index 822a8f64e1a..54cea9ff804 100644
--- a/src/vlib/node_format.c
+++ b/src/vlib/node_format.c
@@ -178,6 +178,27 @@ format_vlib_cpu_time (u8 * s, va_list * va)
return format (s, "%U", format_vlib_time, vm, dt);
}
+uword
+unformat_vlib_node_variant (unformat_input_t *input, va_list *args)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ u32 *march_variant = va_arg (*args, u32 *);
+ uword *p;
+ u8 *str = 0;
+
+ if (unformat (input, "%s", &str) == 0)
+ return 0;
+
+ p = hash_get (vm->node_main.node_fn_march_variant_by_suffix, str);
+
+ vec_free (str);
+
+ if (p)
+ *march_variant = p[0];
+
+ return p ? 1 : 0;
+}
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h
index a12aea4e462..386e9168fa0 100644
--- a/src/vlib/node_funcs.h
+++ b/src/vlib/node_funcs.h
@@ -1189,6 +1189,9 @@ void vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...);
macro. */
u32 vlib_register_node (vlib_main_t * vm, vlib_node_registration_t * r);
+/* Register all node function variants */
+void vlib_register_all_node_march_variants (vlib_main_t *vm);
+
/* Register all static nodes registered via VLIB_REGISTER_NODE. */
void vlib_register_all_static_nodes (vlib_main_t * vm);
@@ -1239,6 +1242,13 @@ vlib_node_set_dispatch_wrapper (vlib_main_t *vm, vlib_node_function_t *fn)
return 0;
}
+int vlib_node_set_march_variant (vlib_main_t *vm, u32 node_index,
+ clib_march_variant_type_t march_variant);
+
+vlib_node_function_t *
+vlib_node_get_preferred_node_fn_variant (vlib_main_t *vm,
+ vlib_node_fn_registration_t *regs);
+
#endif /* included_vlib_node_funcs_h */
/*
diff --git a/src/vlib/node_init.c b/src/vlib/node_init.c
index 265e88f525c..a0318a11dcd 100644
--- a/src/vlib/node_init.c
+++ b/src/vlib/node_init.c
@@ -41,108 +41,15 @@
#include <fcntl.h>
#include <vlib/vlib.h>
-typedef struct _vlib_node_march_variant
-{
- struct _vlib_node_march_variant *next_variant;
- char *name;
-} vlib_node_march_variant_t;
-
-#define VLIB_VARIANT_REGISTER() \
- static vlib_node_march_variant_t \
- CLIB_MARCH_VARIANT##variant; \
- \
- static void __clib_constructor \
- CLIB_MARCH_VARIANT##_register (void) \
- { \
- extern vlib_node_march_variant_t *variants; \
- vlib_node_march_variant_t *v; \
- v = & CLIB_MARCH_VARIANT##variant; \
- v->name = CLIB_MARCH_VARIANT_STR; \
- v->next_variant = variants; \
- variants = v; \
- } \
-
-VLIB_VARIANT_REGISTER ();
-
-#ifndef CLIB_MARCH_VARIANT
-
-vlib_node_march_variant_t *variants = 0;
-
-uword
-unformat_vlib_node_variant (unformat_input_t * input, va_list * args)
-{
- u8 **variant = va_arg (*args, u8 **);
- vlib_node_march_variant_t *v = variants;
-
- if (!unformat (input, "%v", variant))
- return 0;
-
- while (v)
- {
- if (!strncmp (v->name, (char *) *variant, vec_len (*variant)))
- return 1;
-
- v = v->next_variant;
- }
-
- return 0;
-}
-
-static_always_inline void
-vlib_update_nr_variant_default (vlib_node_registration_t *nr, u8 *variant)
-{
- vlib_node_fn_registration_t *fnr = nr->node_fn_registrations;
- vlib_node_fn_registration_t *p_reg = 0;
- vlib_node_fn_registration_t *v_reg = 0;
- u32 tmp;
-
- while (fnr)
- {
- /* which is the highest priority registration */
- if (!p_reg || fnr->priority > p_reg->priority)
- p_reg = fnr;
-
- /* which is the variant we want to prioritize */
- if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1))
- v_reg = fnr;
-
- fnr = fnr->next_registration;
- }
-
- /* node doesn't have the variants */
- if (!v_reg)
- return;
-
- ASSERT (p_reg != 0 && v_reg != 0);
-
- /* swap priorities */
- tmp = p_reg->priority;
- p_reg->priority = v_reg->priority;
- v_reg->priority = tmp;
-
-}
-
static clib_error_t *
-vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
+vlib_node_config (vlib_main_t *vm, unformat_input_t *input)
{
clib_error_t *error = 0;
- vlib_node_registration_t *nr, **all;
unformat_input_t sub_input;
- uword *hash = 0, *p;
- u8 *variant = 0;
- u8 *s = 0;
-
- all = 0;
- hash = hash_create_string (0, sizeof (uword));
-
- nr = vm->node_main.node_registrations;
- while (nr)
- {
- hash_set_mem (hash, nr->name, vec_len (all));
- vec_add1 (all, nr);
-
- nr = nr->next_registration;
- }
+ u32 *march_variant_by_node = 0;
+ clib_march_variant_type_t march_variant;
+ u32 node_index;
+ int i;
/* specify prioritization defaults for all graph nodes */
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -153,48 +60,34 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
{
if (!unformat (&sub_input, "variant %U",
- unformat_vlib_node_variant, &variant))
+ unformat_vlib_node_variant, &march_variant))
return clib_error_return (0,
"please specify a valid node variant");
- vec_add1 (variant, 0);
-
- nr = vm->node_main.node_registrations;
- while (nr)
- {
- vlib_update_nr_variant_default (nr, variant);
- nr = nr->next_registration;
- }
- vec_free (variant);
+ vec_validate_init_empty (march_variant_by_node,
+ vec_len (vm->node_main.nodes) - 1, ~0);
+ vec_foreach_index (i, march_variant_by_node)
+ march_variant_by_node[i] = march_variant;
+ vm->node_main.node_fn_default_march_variant = march_variant;
+ unformat_free (&sub_input);
}
}
else /* specify prioritization for an individual graph node */
- if (unformat (input, "%s", &s))
+ if (unformat (input, "%U", unformat_vlib_node, vm, &node_index))
{
- if (!(p = hash_get_mem (hash, s)))
- {
- error = clib_error_return (0,
- "node variants: unknown graph node '%s'",
- s);
- break;
- }
-
- nr = vec_elt (all, p[0]);
-
if (unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
{
while (unformat_check_input (&sub_input) !=
UNFORMAT_END_OF_INPUT)
{
if (!unformat (&sub_input, "variant %U",
- unformat_vlib_node_variant, &variant))
+ unformat_vlib_node_variant, &march_variant))
return clib_error_return (0,
"please specify a valid node variant");
- vec_add1 (variant, 0);
-
- vlib_update_nr_variant_default (nr, variant);
-
- vec_free (variant);
+ vec_validate_init_empty (march_variant_by_node, node_index,
+ ~0);
+ march_variant_by_node[node_index] = march_variant;
+ unformat_free (&sub_input);
}
}
}
@@ -204,16 +97,19 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
}
}
- hash_free (hash);
- vec_free (all);
+ if (march_variant_by_node)
+ {
+ vec_foreach_index (i, march_variant_by_node)
+ if (march_variant_by_node[i] != ~0)
+ vlib_node_set_march_variant (vm, i, march_variant_by_node[i]);
+ vec_free (march_variant_by_node);
+ }
unformat_free (input);
return error;
}
-VLIB_EARLY_CONFIG_FUNCTION (vlib_early_node_config, "node");
-
-#endif
+VLIB_CONFIG_FUNCTION (vlib_node_config, "node");
/*
* fd.io coding-style-patch-verification: ON