X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffeature%2Ffeature.c;h=0f0bfeb11d27296b718eb1fddd49253cfe09488a;hb=a4e2e7cc95250220e0d892eb11dcc0adc9fd7e22;hp=6525bcbdce551835832a7e9e0f77192c622a5c3a;hpb=3b4a6a1bb0cc5059b1965282463c03ef4d14f874;p=vpp.git diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c index 6525bcbdce5..0f0bfeb11d2 100644 --- a/src/vnet/feature/feature.c +++ b/src/vnet/feature/feature.c @@ -14,16 +14,46 @@ */ #include -#include + vnet_feature_main_t feature_main; +typedef struct vnet_feature_upd_registration_t_ +{ + vnet_feature_update_cb_t cb; + void *data; +} vnet_feature_upd_registration_t; + +static vnet_feature_upd_registration_t *regs; + +void +vnet_feature_register (vnet_feature_update_cb_t cb, void *data) +{ + vnet_feature_upd_registration_t *reg; + + vec_add2 (regs, reg, 1); + + reg->cb = cb; + reg->data = data; +} + +static void +vent_feature_reg_invoke (u32 sw_if_index, u8 arc_index, u8 is_enable) +{ + vnet_feature_upd_registration_t *reg; + + vec_foreach (reg, regs) + reg->cb (sw_if_index, arc_index, is_enable, reg->data); +} + + static clib_error_t * vnet_feature_init (vlib_main_t * vm) { vnet_feature_main_t *fm = &feature_main; vnet_feature_registration_t *freg; vnet_feature_arc_registration_t *areg; + vnet_feature_constraint_registration_t *creg; u32 arc_index = 0; fm->arc_index_by_name = hash_create_string (0, sizeof (uword)); @@ -58,6 +88,7 @@ vnet_feature_init (vlib_main_t * vm) vec_validate (fm->next_feature_by_name, arc_index - 1); vec_validate (fm->sw_if_index_has_features, arc_index - 1); vec_validate (fm->feature_count_by_sw_if_index, arc_index - 1); + vec_validate (fm->next_constraint_by_arc, arc_index - 1); freg = fm->next_feature; while (freg) @@ -82,26 +113,66 @@ vnet_feature_init (vlib_main_t * vm) freg = next; } + /* Move bulk constraints to the constraint by arc lists */ + creg = fm->next_constraint; + while (creg) + { + vnet_feature_constraint_registration_t *next; + uword *p = hash_get_mem (fm->arc_index_by_name, creg->arc_name); + if (p == 0) + { + /* Don't start vpp with broken features arcs */ + clib_warning ("Unknown feature arc '%s'", creg->arc_name); + os_exit (1); + } + + areg = uword_to_pointer (p[0], vnet_feature_arc_registration_t *); + arc_index = areg->feature_arc_index; + + next = creg->next; + creg->next_in_arc = fm->next_constraint_by_arc[arc_index]; + fm->next_constraint_by_arc[arc_index] = creg; + + /* next */ + creg = next; + } + + areg = fm->next_arc; while (areg) { clib_error_t *error; vnet_feature_config_main_t *cm; vnet_config_main_t *vcm; + char **features_in_order, *last_feature; arc_index = areg->feature_arc_index; cm = &fm->feature_config_mains[arc_index]; vcm = &cm->config_main; - if ((error = vnet_feature_arc_init (vm, vcm, - areg->start_nodes, - areg->n_start_nodes, - fm->next_feature_by_arc[arc_index], - &fm->feature_nodes[arc_index]))) + if ((error = vnet_feature_arc_init + (vm, vcm, areg->start_nodes, areg->n_start_nodes, + areg->last_in_arc, + fm->next_feature_by_arc[arc_index], + fm->next_constraint_by_arc[arc_index], + &fm->feature_nodes[arc_index]))) { clib_error_report (error); os_exit (1); } + features_in_order = fm->feature_nodes[arc_index]; + + /* If specified, verify that the last node in the arc is actually last */ + if (areg->last_in_arc && vec_len (features_in_order) > 0) + { + last_feature = features_in_order[vec_len (features_in_order) - 1]; + if (strncmp (areg->last_in_arc, last_feature, + strlen (areg->last_in_arc))) + clib_warning + ("WARNING: %s arc: last node is %s, but expected %s!", + areg->arc_name, last_feature, areg->last_in_arc); + } + fm->next_feature_by_name[arc_index] = hash_create_string (0, sizeof (uword)); freg = fm->next_feature_by_arc[arc_index]; @@ -223,7 +294,7 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, fm->sw_if_index_has_features[arc_index] = clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index, (feature_count > 0)); - adj_feature_update (sw_if_index, arc_index, (feature_count > 0)); + vent_feature_reg_invoke (sw_if_index, arc_index, (feature_count > 0)); fm->feature_count_by_sw_if_index[arc_index][sw_if_index] = feature_count; return 0; @@ -325,7 +396,7 @@ show_features_command_fn (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_features_command, static) = { .path = "show features", - .short_help = "show features", + .short_help = "show features [verbose]", .function = show_features_command_fn, }; /* *INDENT-ON* */ @@ -419,21 +490,22 @@ set_interface_features_command_fn (vlib_main_t * vm, while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat - (line_input, "%U %v", unformat_vnet_sw_interface, vnm, &sw_if_index, - &feature_name)) - ; - else if (unformat (line_input, "arc %v", &arc_name)) + (line_input, "%U %s arc %s", unformat_vnet_sw_interface, vnm, + &sw_if_index, &feature_name, &arc_name)) ; else if (unformat (line_input, "disable")) enable = 0; else { - if (feature_name && arc_name) - break; error = unformat_parse_error (line_input); goto done; } } + if (!feature_name || !arc_name) + { + error = clib_error_return (0, "Both feature name and arc required..."); + goto done; + } if (sw_if_index == ~0) { @@ -444,13 +516,28 @@ set_interface_features_command_fn (vlib_main_t * vm, vec_add1 (arc_name, 0); vec_add1 (feature_name, 0); + u8 arc_index; + + arc_index = vnet_get_feature_arc_index ((const char *) arc_name); + + if (arc_index == (u8) ~ 0) + { + error = + clib_error_return (0, "Unknown arc name (%s)... ", + (const char *) arc_name); + goto done; + } + vnet_feature_registration_t *reg; reg = vnet_get_feature_reg ((const char *) arc_name, (const char *) feature_name); if (reg == 0) { - error = clib_error_return (0, "Unknown feature..."); + error = + clib_error_return (0, + "Feature (%s) not registered to arc (%s)... See 'show features verbose' for valid feature/arc combinations. ", + feature_name, arc_name); goto done; } if (reg->enable_disable_cb)