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));
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'",
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;
arc_index++;
}
- fm->device_input_feature_arc_index =
- vnet_get_feature_arc_index ("device-input");
return 0;
}
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)
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);
}
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 */