X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffeature%2Fregistration.c;h=030486a748993b605ea00c0fc74077ad7efe6553;hb=e5d34919b;hp=1deeeef904cf0f19ab6984aefbf2af0b0e90d704;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/feature/registration.c b/src/vnet/feature/registration.c index 1deeeef904c..030486a7489 100644 --- a/src/vnet/feature/registration.c +++ b/src/vnet/feature/registration.c @@ -107,6 +107,9 @@ comma_split (u8 * s, u8 ** a, u8 ** b) * @param first_reg first element in * [an __attribute__((constructor)) function built, or * otherwise created] singly-linked list of feature registrations + * @param first_const first element in + * [an __attribute__((constructor)) function built, or + * otherwise created] singly-linked list of bulk order constraints * @param [out] in_feature_nodes returned vector of * topologically-sorted feature node names, for use in * show commands @@ -119,13 +122,16 @@ vnet_feature_arc_init (vlib_main_t * vm, vnet_config_main_t * vcm, char **feature_start_nodes, int num_feature_start_nodes, + char *last_in_arc, vnet_feature_registration_t * first_reg, - char ***in_feature_nodes) + vnet_feature_constraint_registration_t * + first_const_set, char ***in_feature_nodes) { uword *index_by_name; uword *reg_by_index; u8 **node_names = 0; u8 *node_name; + char *prev_name; char **these_constraints; char *this_constraint_c; u8 **constraints = 0; @@ -139,6 +145,7 @@ vnet_feature_arc_init (vlib_main_t * vm, int n_features; u32 *result = 0; vnet_feature_registration_t *this_reg = 0; + vnet_feature_constraint_registration_t *this_const_set = 0; char **feature_nodes = 0; hash_pair_t *hp; u8 **keys_to_delete = 0; @@ -148,6 +155,27 @@ vnet_feature_arc_init (vlib_main_t * vm, this_reg = first_reg; + /* Autogenerate before constraints */ + if (last_in_arc) + { + while (this_reg) + { + /* If this isn't the last node in the arc... */ + if (clib_strcmp (this_reg->node_name, last_in_arc)) + { + /* + * Add an explicit constraint so this feature will run + * before the last node in the arc + */ + constraint_tuple = format (0, "%s,%s%c", this_reg->node_name, + last_in_arc, 0); + vec_add1 (constraints, constraint_tuple); + } + this_reg = this_reg->next_in_arc; + } + this_reg = first_reg; + } + /* pass 1, collect feature node names, construct a before b pairs */ while (this_reg) { @@ -180,7 +208,45 @@ vnet_feature_arc_init (vlib_main_t * vm, these_constraints++; } - this_reg = this_reg->next; + this_reg = this_reg->next_in_arc; + } + + /* pass 2, collect bulk "a then b then c then d" constraints */ + this_const_set = first_const_set; + while (this_const_set) + { + these_constraints = this_const_set->node_names; + + prev_name = 0; + /* Across the list of constraints */ + while (these_constraints && these_constraints[0]) + { + this_constraint_c = these_constraints[0]; + p = hash_get_mem (index_by_name, this_constraint_c); + if (p == 0) + { + clib_warning + ("bulk constraint feature node '%s' not found for arc '%s'", + this_constraint_c); + these_constraints++; + continue; + } + + if (prev_name == 0) + { + prev_name = this_constraint_c; + these_constraints++; + continue; + } + + constraint_tuple = format (0, "%s,%s%c", prev_name, + this_constraint_c, 0); + vec_add1 (constraints, constraint_tuple); + prev_name = this_constraint_c; + these_constraints++; + } + + this_const_set = this_const_set->next_in_arc; } n_features = vec_len (node_names); @@ -201,12 +267,20 @@ vnet_feature_arc_init (vlib_main_t * vm, * Nonexistent graph nodes are tolerated. */ if (p == 0) - return clib_error_return (0, "feature node '%s' not found", a_name); + { + clib_warning ("feature node '%s' not found (before '%s', arc '%s')", + a_name, b_name, first_reg->arc_name); + continue; + } a_index = p[0]; p = hash_get_mem (index_by_name, b_name); if (p == 0) - return clib_error_return (0, "feature node '%s' not found", b_name); + { + clib_warning ("feature node '%s' not found (after '%s', arc '%s')", + b_name, a_name, first_reg->arc_name); + continue; + } b_index = p[0]; /* add a before b to the original set of constraints */ @@ -244,7 +318,9 @@ again: /* see if we got a partial order... */ if (vec_len (result) != n_features) - return clib_error_return (0, "%d feature_init_cast no partial order!"); + return clib_error_return + (0, "Arc '%s': failed to find a suitable feature order!", + first_reg->arc_name); /* * We win.