VPP-1294: add missing feature arc constraint
[vpp.git] / src / vnet / feature / feature.c
index 714e20e..e1cea21 100644 (file)
@@ -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;
        }