X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Ffeature%2Ffeature.c;h=e1d172e5707ac68b4c739ed249c61fa8addc99fb;hb=7490a752814187ed03c0deca4d836b0dca09fb4b;hp=bfdea3db41f5bbaeb39d4a4a965abff48244817b;hpb=05bb1dd7a9b356df1acb73bc13b6a30dae67be55;p=vpp.git diff --git a/vnet/vnet/feature/feature.c b/vnet/vnet/feature/feature.c index bfdea3db41f..e1d172e5707 100644 --- a/vnet/vnet/feature/feature.c +++ b/vnet/vnet/feature/feature.c @@ -34,6 +34,8 @@ vnet_feature_init (vlib_main_t * vm) char *s; int i = 0; areg->feature_arc_index = arc_index; + if (areg->arc_index_ptr) + *areg->arc_index_ptr = arc_index; hash_set_mem (fm->arc_index_by_name, areg->arc_name, pointer_to_uword (areg)); @@ -59,6 +61,7 @@ vnet_feature_init (vlib_main_t * vm) freg = fm->next_feature; while (freg) { + vnet_feature_registration_t *next; uword *p = hash_get_mem (fm->arc_index_by_name, freg->arc_name); if (p == 0) return clib_error_return (0, "Unknown feature arc '%s'", @@ -67,12 +70,15 @@ vnet_feature_init (vlib_main_t * vm) areg = uword_to_pointer (p[0], vnet_feature_arc_registration_t *); arc_index = areg->feature_arc_index; - vec_add1 (fm->next_feature_by_arc[arc_index], *freg); + next = freg->next; + freg->next = fm->next_feature_by_arc[arc_index]; + fm->next_feature_by_arc[arc_index] = freg; /* next */ - freg = freg->next; + freg = next; } + areg = fm->next_arc; while (areg) { clib_error_t *error; @@ -107,8 +113,6 @@ vnet_feature_init (vlib_main_t * vm) arc_index++; } - fm->device_input_feature_arc_index = - vnet_get_feature_arc_index ("device-input"); return 0; } @@ -148,6 +152,27 @@ vnet_get_feature_arc_index (const char *s) return reg->feature_arc_index; } +vnet_feature_registration_t * +vnet_get_feature_reg (const char *arc_name, const char *node_name) +{ + u8 arc_index; + + arc_index = vnet_get_feature_arc_index (arc_name); + if (arc_index == (u8) ~ 0) + return 0; + + vnet_feature_main_t *fm = &feature_main; + vnet_feature_registration_t *reg; + uword *p; + + p = hash_get_mem (fm->next_feature_by_name[arc_index], node_name); + if (p == 0) + return 0; + + reg = uword_to_pointer (p[0], vnet_feature_registration_t *); + return reg; +} + u32 vnet_get_feature_index (u8 arc, const char *s) { @@ -160,31 +185,34 @@ vnet_get_feature_index (u8 arc, const char *s) return ~0; reg = uword_to_pointer (p[0], vnet_feature_registration_t *); - return reg->feature_index_u32; + return reg->feature_index; } -void -vnet_feature_enable_disable (const char *arc_name, const char *node_name, - u32 sw_if_index, int enable_disable, - void *feature_config, u32 n_feature_config_bytes) +int +vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, + u32 sw_if_index, int enable_disable, + void *feature_config, + u32 n_feature_config_bytes) { vnet_feature_main_t *fm = &feature_main; vnet_feature_config_main_t *cm; - u32 feature_index, ci; - u8 arc_index; - - arc_index = vnet_get_feature_arc_index (arc_name); + u32 ci; if (arc_index == (u8) ~ 0) - return; + return VNET_API_ERROR_INVALID_VALUE; + + if (feature_index == ~0) + return VNET_API_ERROR_INVALID_VALUE_2; cm = &fm->feature_config_mains[arc_index]; vec_validate_init_empty (cm->config_index_by_sw_if_index, sw_if_index, ~0); - feature_index = vnet_get_feature_index (arc_index, node_name); - if (feature_index == ~0) - return; ci = cm->config_index_by_sw_if_index[sw_if_index]; + vec_validate (fm->feature_count_by_sw_if_index[arc_index], sw_if_index); + if (!enable_disable + && fm->feature_count_by_sw_if_index[arc_index][sw_if_index] < 1) + return 0; + ci = (enable_disable ? vnet_config_add_feature : vnet_config_del_feature) @@ -195,6 +223,28 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name, vnet_config_update_feature_count (fm, arc_index, sw_if_index, enable_disable); + return 0; +} + +int +vnet_feature_enable_disable (const char *arc_name, const char *node_name, + u32 sw_if_index, int enable_disable, + void *feature_config, u32 n_feature_config_bytes) +{ + u32 feature_index; + u8 arc_index; + + arc_index = vnet_get_feature_arc_index (arc_name); + + if (arc_index == (u8) ~ 0) + return VNET_API_ERROR_INVALID_VALUE; + + feature_index = vnet_get_feature_index (arc_index, node_name); + + return vnet_feature_enable_disable_with_index (arc_index, feature_index, + sw_if_index, enable_disable, + feature_config, + n_feature_config_bytes); } @@ -216,10 +266,12 @@ show_features_command_fn (vlib_main_t * vm, while (areg) { vlib_cli_output (vm, "%s:", areg->arc_name); - vec_foreach (freg, fm->next_feature_by_arc[areg->feature_arc_index]) - { - vlib_cli_output (vm, " %s\n", freg->node_name); - } + freg = fm->next_feature_by_arc[areg->feature_arc_index]; + while (freg) + { + vlib_cli_output (vm, " %s\n", freg->node_name); + freg = freg->next; + } /* next */ @@ -311,6 +363,89 @@ vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index) } } +static clib_error_t * +set_interface_features_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + vnet_main_t *vnm = vnet_get_main (); + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; + + u8 *arc_name = 0; + u8 *feature_name = 0; + u32 sw_if_index = ~0; + u8 enable = 1; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + goto done; + + 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)) + ; + else if (unformat (line_input, "disable")) + enable = 0; + else + { + error = unformat_parse_error (line_input); + goto done; + } + } + + if (sw_if_index == ~0) + { + error = clib_error_return (0, "Interface not specified..."); + goto done; + } + + vec_add1 (arc_name, 0); + vec_add1 (feature_name, 0); + + 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..."); + goto done; + } + if (reg->enable_disable_cb) + error = reg->enable_disable_cb (sw_if_index, enable); + if (!error) + vnet_feature_enable_disable ((const char *) arc_name, + (const char *) feature_name, sw_if_index, + enable, 0, 0); + +done: + vec_free (feature_name); + vec_free (arc_name); + return error; +} + +/*? + * Set feature for given interface + * + * @cliexpar + * Example: + * @cliexcmd{set interface feature GigabitEthernet2/0/0 ip4_flow_classify arc ip4_unicast} + * @cliexend + * @endparblock +?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (set_interface_feature_command, static) = { + .path = "set interface feature", + .short_help = "set interface feature arc ", + .function = set_interface_features_command_fn, +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON *