VPP-243 - Coding style changes - updated emacs LISP styleify
[vpp.git] / vnet / vnet / ip / ip_feature_registration.c
index 02699c4..5f0d58e 100644 (file)
@@ -119,6 +119,12 @@ ip_feature_init_cast (vlib_main_t * vm,
         return clib_error_return (0, "comma_split failed!");
       
       p = hash_get_mem (index_by_name, a_name);
+      /* 
+       * Note: the next two errors mean that the xxx_FEATURE_INIT macros are
+       * b0rked. As in: if you code "A depends on B," and you forget
+       * to define a FEATURE_INIT macro for B, you lose. 
+       * Nonexistent graph nodes are tolerated.
+       */
       if (p == 0)
         return clib_error_return (0, "feature node '%s' not found", a_name);
       a_index = p[0];
@@ -163,7 +169,9 @@ ip_feature_init_cast (vlib_main_t * vm,
 
   /* see if we got a partial order... */
   if (vec_len (result) != n_features)
-    return clib_error_return (0, "ip4_feature_init_cast (cast=%d), no PO!");
+      return clib_error_return 
+        (0, "ip%s_feature_init_cast (cast=%d), no partial order!",
+         is_ip4 ? "4" : "6", cast);
 
   /* 
    * We win.
@@ -189,6 +197,12 @@ ip_feature_init_cast (vlib_main_t * vm,
                     feature_nodes, 
                     vec_len(feature_nodes));
 
+  /* Save a copy for show command */
+  if (is_ip4)
+    im4->feature_nodes[cast] = feature_nodes;
+  else
+    im6->feature_nodes[cast] = feature_nodes;
+
   /* Finally, clean up all the shit we allocated */
   hash_foreach_pair (hp, index_by_name,
   ({
@@ -205,3 +219,119 @@ ip_feature_init_cast (vlib_main_t * vm,
   return 0;
 }
 
+#define foreach_af_cast                         \
+_(4, VNET_UNICAST, "ip4 unicast")               \
+_(4, VNET_MULTICAST, "ip4 multicast")           \
+_(6, VNET_UNICAST, "ip6 unicast")               \
+_(6, VNET_MULTICAST, "ip6 multicast")
+
+static clib_error_t *
+show_ip_features_command_fn (vlib_main_t * vm,
+                unformat_input_t * input,
+                vlib_cli_command_t * cmd)
+{
+  ip4_main_t * im4 = &ip4_main;
+  ip6_main_t * im6 = &ip6_main;
+  int i;
+  char ** features;
+
+  vlib_cli_output (vm, "Available IP feature nodes");
+
+#define _(a,c,s)                                        \
+  do {                                                  \
+    features = im##a->feature_nodes[c];                 \
+    vlib_cli_output (vm, "%s:", s);                     \
+    for (i = 0; i < vec_len(features); i++)             \
+      vlib_cli_output (vm, "  %s\n", features[i]);      \
+  } while(0);
+  foreach_af_cast;
+#undef _
+
+  return 0;
+}
+
+VLIB_CLI_COMMAND (show_ip_features_command, static) = {
+  .path = "show ip features",
+  .short_help = "show ip features",
+  .function = show_ip_features_command_fn,
+};
+
+static clib_error_t *
+show_ip_interface_features_command_fn (vlib_main_t * vm,
+                                       unformat_input_t * input,
+                                       vlib_cli_command_t * cmd)
+{
+  vnet_main_t * vnm = vnet_get_main();
+  ip4_main_t * im4 = &ip4_main;
+  ip_lookup_main_t * lm4 = &im4->lookup_main;
+  ip6_main_t * im6 = &ip6_main;
+  ip_lookup_main_t * lm6 = &im6->lookup_main;
+  
+  ip_lookup_main_t * lm;
+  ip_config_main_t * cm;
+  vnet_config_main_t * vcm;
+  vnet_config_t * cfg;
+  u32 cfg_index;
+  vnet_config_feature_t * feat;
+  vlib_node_t * n;
+  u32 sw_if_index;
+  u32 node_index;
+  u32 current_config_index;
+  int i, af;
+  u32 cast;
+
+  if (! unformat (input, "%U", unformat_vnet_sw_interface, 
+                  vnm, &sw_if_index))
+    return clib_error_return (0, "Interface not specified...");
+
+  vlib_cli_output (vm, "IP feature paths configured on %U...",
+                   format_vnet_sw_if_index_name, vnm, sw_if_index);
+
+  
+  for (af = 0; af < 2; af++)
+    {
+      if (af == 0)
+        lm = lm4;
+      else
+        lm = lm6;
+
+      for (cast = VNET_UNICAST; cast < VNET_N_CAST; cast++)
+        {
+          cm = lm->rx_config_mains + cast;
+          vcm = &cm->config_main;
+      
+          vlib_cli_output (vm, "\nipv%s %scast:", 
+                           (af == 0) ? "4" : "6",
+                           cast == VNET_UNICAST ?
+                           "uni": "multi");
+
+          current_config_index = vec_elt (cm->config_index_by_sw_if_index, 
+                                          sw_if_index);
+
+          ASSERT(current_config_index 
+                 < vec_len (vcm->config_pool_index_by_user_index));
+          
+          cfg_index = 
+            vcm->config_pool_index_by_user_index[current_config_index];
+          cfg = pool_elt_at_index (vcm->config_pool, cfg_index);
+
+          for (i = 0; i < vec_len(cfg->features); i++)
+            {
+              feat = cfg->features + i;
+              node_index = feat->node_index;
+              n = vlib_get_node (vm, node_index);
+              vlib_cli_output (vm, "  %v", n->name);
+            }
+        }
+    }
+
+  return 0;
+}
+
+VLIB_CLI_COMMAND (show_ip_interface_features_command, static) = {
+  .path = "show ip interface features",
+  .short_help = "show ip interface features <intfc>",
+  .function = show_ip_interface_features_command_fn,
+};
+
+