summaryrefslogtreecommitdiffstats
path: root/src/vnet/feature
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/feature')
-rw-r--r--src/vnet/feature/feature.c46
-rw-r--r--src/vnet/feature/feature.h3
2 files changed, 42 insertions, 7 deletions
diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c
index 714e20e8e72..e1cea21d7b6 100644
--- a/src/vnet/feature/feature.c
+++ b/src/vnet/feature/feature.c
@@ -250,6 +250,14 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name,
n_feature_config_bytes);
}
+static int
+feature_cmp (void *a1, void *a2)
+{
+ vnet_feature_registration_t *reg1 = a1;
+ vnet_feature_registration_t *reg2 = a2;
+
+ return (int) reg1->feature_index - reg2->feature_index;
+}
/** Display the set of available driver features.
Useful for verifying that expected features are present
@@ -262,24 +270,45 @@ show_features_command_fn (vlib_main_t * vm,
vnet_feature_main_t *fm = &feature_main;
vnet_feature_arc_registration_t *areg;
vnet_feature_registration_t *freg;
+ vnet_feature_registration_t *feature_regs = 0;
+ int verbose = 0;
+
+ if (unformat (input, "verbose"))
+ verbose = 1;
vlib_cli_output (vm, "Available feature paths");
areg = fm->next_arc;
while (areg)
{
- vlib_cli_output (vm, "%s:", areg->arc_name);
+ if (verbose)
+ vlib_cli_output (vm, "[%2d] %s:", areg->feature_arc_index,
+ areg->arc_name);
+ else
+ vlib_cli_output (vm, "%s:", areg->arc_name);
+
freg = fm->next_feature_by_arc[areg->feature_arc_index];
while (freg)
{
- vlib_cli_output (vm, " %s\n", freg->node_name);
+ vec_add1 (feature_regs, freg[0]);
freg = freg->next_in_arc;
}
+ vec_sort_with_function (feature_regs, feature_cmp);
+ vec_foreach (freg, feature_regs)
+ {
+ if (verbose)
+ vlib_cli_output (vm, " [%2d]: %s\n", freg->feature_index,
+ freg->node_name);
+ else
+ vlib_cli_output (vm, " %s\n", freg->node_name);
+ }
+ vec_reset_length (feature_regs);
/* next */
areg = areg->next;
}
+ vec_free (feature_regs);
return 0;
}
@@ -289,7 +318,7 @@ show_features_command_fn (vlib_main_t * vm,
*
* @cliexpar
* Example:
- * @cliexcmd{show ip features}
+ * @cliexcmd{show features [verbose]}
* @cliexend
* @endparblock
?*/
@@ -306,7 +335,7 @@ VLIB_CLI_COMMAND (show_features_command, static) = {
*/
void
-vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index)
+vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index, int verbose)
{
vnet_feature_main_t *fm = &feature_main;
u32 node_index, current_config_index;
@@ -320,7 +349,7 @@ vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index)
vlib_node_t *n;
int i;
- vlib_cli_output (vm, "Driver feature paths configured on %U...",
+ vlib_cli_output (vm, "Feature paths configured on %U...",
format_vnet_sw_if_index_name,
vnet_get_main (), sw_if_index);
@@ -361,7 +390,10 @@ vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index)
feat = cfg->features + i;
node_index = feat->node_index;
n = vlib_get_node (vm, node_index);
- vlib_cli_output (vm, " %v", n->name);
+ if (verbose)
+ vlib_cli_output (vm, " [%2d] %v", feat->feature_index, n->name);
+ else
+ vlib_cli_output (vm, " %v", n->name);
}
}
}
@@ -396,6 +428,8 @@ set_interface_features_command_fn (vlib_main_t * vm,
enable = 0;
else
{
+ if (feature_name && arc_name)
+ break;
error = unformat_parse_error (line_input);
goto done;
}
diff --git a/src/vnet/feature/feature.h b/src/vnet/feature/feature.h
index ce9e2ca3570..81224ebf0e2 100644
--- a/src/vnet/feature/feature.h
+++ b/src/vnet/feature/feature.h
@@ -397,7 +397,8 @@ clib_error_t *vnet_feature_arc_init (vlib_main_t * vm,
vnet_feature_registration_t *
first_reg, char ***feature_nodes);
-void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index);
+void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index,
+ int verbose);
#endif /* included_feature_h */