vnet classifier debug CLI enhancements 73/573/1
authorDave Barach <dave@barachs.net>
Sun, 20 Mar 2016 14:14:45 +0000 (10:14 -0400)
committerDave Barach <dave@barachs.net>
Sun, 20 Mar 2016 14:15:24 +0000 (10:15 -0400)
Extensible next-index and opaque unformat function scheme. Added
next-index-by-node-name and sw_if_index->opaque functions.

Allow dynamic graph arcs to be added to ip4/6-inacl.

Change-Id: Ie434335399a0708772eb82563a154df19c63b622
Signed-off-by: Dave Barach <dave@barachs.net>
vnet/vnet/classify/vnet_classify.c
vnet/vnet/classify/vnet_classify.h
vnet/vnet/ip/ip.h
vnet/vnet/ip/ip_input_acl.c
vnet/vnet/mpls-gre/policy_encap.c
vpp/vnet/main.c

index 7f7138a..2a77701 100644 (file)
@@ -18,6 +18,8 @@
 #include <vnet/api_errno.h>     /* for API error numbers */
 #include <vnet/l2/l2_classify.h> /* for L2_CLASSIFY_NEXT_xxx */
 
+vnet_classify_main_t vnet_classify_main;
+
 #if VALIDATION_SCAFFOLDING
 /* Validation scaffolding */
 void mv (vnet_classify_table_t * t)
@@ -64,6 +66,35 @@ void mv (vnet_classify_table_t * t) { }
 void rogue (vnet_classify_table_t * t) { }
 #endif
 
+void vnet_classify_register_unformat_l2_next_index_fn (unformat_function_t * fn)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+
+  vec_add1 (cm->unformat_l2_next_index_fns, fn);
+}
+
+void vnet_classify_register_unformat_ip_next_index_fn (unformat_function_t * fn)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+
+  vec_add1 (cm->unformat_ip_next_index_fns, fn);
+}
+
+void 
+vnet_classify_register_unformat_acl_next_index_fn (unformat_function_t * fn)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+
+  vec_add1 (cm->unformat_acl_next_index_fns, fn);
+}
+
+void vnet_classify_register_unformat_opaque_index_fn (unformat_function_t * fn)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+
+  vec_add1 (cm->unformat_opaque_index_fns, fn);
+}
+
 vnet_classify_table_t * 
 vnet_classify_new_table (vnet_classify_main_t *cm,
                          u8 * mask, u32 nbuckets, u32 memory_size,
@@ -990,10 +1021,22 @@ _(li, LI)
 
 uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
 {
+  vnet_classify_main_t * cm = &vnet_classify_main;
   u32 * miss_next_indexp = va_arg (*args, u32 *);
   u32 next_index = 0;
   u32 tmp;
+  int i;
   
+  /* First try registered unformat fns, allowing override... */
+  for (i = 0; i < vec_len (cm->unformat_l2_next_index_fns); i++)
+    {
+      if (unformat (input, "%U", cm->unformat_l2_next_index_fns[i], &tmp))
+        {
+          next_index = tmp;
+          goto out;
+        }
+    }
+
 #define _(n,N) \
   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
   foreach_l2_next;
@@ -1021,9 +1064,21 @@ _(rewrite, REWRITE)
 uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
 {
   u32 * miss_next_indexp = va_arg (*args, u32 *);
+  vnet_classify_main_t * cm = &vnet_classify_main;
   u32 next_index = 0;
   u32 tmp;
+  int i;
   
+  /* First try registered unformat fns, allowing override... */
+  for (i = 0; i < vec_len (cm->unformat_ip_next_index_fns); i++)
+    {
+      if (unformat (input, "%U", cm->unformat_ip_next_index_fns[i], &tmp))
+        {
+          next_index = tmp;
+          goto out;
+        }
+    }
+
 #define _(n,N) \
   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
   foreach_ip_next;
@@ -1047,9 +1102,21 @@ _(deny, DENY)
 
 uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
 {
-  u32 * miss_next_indexp = va_arg (*args, u32 *);
+  u32 * next_indexp = va_arg (*args, u32 *);
+  vnet_classify_main_t * cm = &vnet_classify_main;
   u32 next_index = 0;
   u32 tmp;
+  int i;
+
+  /* First try registered unformat fns, allowing override... */
+  for (i = 0; i < vec_len (cm->unformat_acl_next_index_fns); i++)
+    {
+      if (unformat (input, "%U", cm->unformat_acl_next_index_fns[i], &tmp))
+        {
+          next_index = tmp;
+          goto out;
+        }
+    }
 
 #define _(n,N) \
   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
@@ -1070,7 +1137,7 @@ uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
   return 0;
 
  out:
-  *miss_next_indexp = next_index;
+  *next_indexp = next_index;
   return 1;
 }
 
@@ -1678,10 +1745,10 @@ classify_session_command_fn (vlib_main_t * vm,
   int is_add = 1;
   u32 table_index = ~0;
   u32 hit_next_index = ~0;
-  u32 opaque_index = ~0;
+  u64 opaque_index = ~0;
   u8 * match = 0;
   i32 advance = 0;
-  int rv;
+  int i, rv;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
     {
@@ -1696,7 +1763,7 @@ classify_session_command_fn (vlib_main_t * vm,
       else if (unformat (input, "acl-hit-next %U", unformat_acl_next_index,
                          &hit_next_index))
         ;
-      else if (unformat (input, "opaque-index %d", &opaque_index))
+      else if (unformat (input, "opaque-index %lld", &opaque_index))
         ;
       else if (unformat (input, "match %U", unformat_classify_match,
                          cm, &match, table_index))
@@ -1706,7 +1773,18 @@ classify_session_command_fn (vlib_main_t * vm,
       else if (unformat (input, "table-index %d", &table_index))
         ;
       else
-        break;
+        {
+          /* Try registered opaque-index unformat fns */
+          for (i = 0; i < vec_len (cm->unformat_opaque_index_fns); i++)
+            {
+              if (unformat (input, "%U", cm->unformat_opaque_index_fns[i], 
+                            &opaque_index))
+                goto found_opaque;
+            }
+          break;
+        }
+    found_opaque:
+      ;
     }
 
   if (table_index == ~0)
@@ -1740,6 +1818,113 @@ VLIB_CLI_COMMAND (classify_session_command, static) = {
     .function = classify_session_command_fn,
 };
 
+static uword 
+unformat_opaque_sw_if_index (unformat_input_t * input, va_list * args)
+{
+  u64 * opaquep = va_arg (*args, u64 *);
+  u32 sw_if_index;
+
+  if (unformat (input, "opaque-sw_if_index %U", unformat_vnet_sw_interface,
+                vnet_get_main(), &sw_if_index))
+    {
+      *opaquep = sw_if_index;
+      return 1;
+    }
+  return 0;
+}
+
+static uword 
+unformat_ip_next_node (unformat_input_t * input, va_list * args)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+  u32 * next_indexp = va_arg (*args, u32 *);
+  u32 node_index;
+  u32 next_index, rv;
+
+  if (unformat (input, "node %U", unformat_vlib_node,
+                cm->vlib_main, &node_index))
+    {
+      rv = next_index = vlib_node_add_next 
+        (cm->vlib_main, ip4_classify_node.index, node_index);
+      next_index = vlib_node_add_next 
+        (cm->vlib_main, ip6_classify_node.index, node_index);
+      ASSERT(rv == next_index);
+
+      *next_indexp = next_index;
+      return 1;
+    }
+  return 0;
+}
+
+static uword 
+unformat_acl_next_node (unformat_input_t * input, va_list * args)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+  u32 * next_indexp = va_arg (*args, u32 *);
+  u32 node_index;
+  u32 next_index, rv;
+
+  if (unformat (input, "node %U", unformat_vlib_node,
+                cm->vlib_main, &node_index))
+    {
+      rv = next_index = vlib_node_add_next 
+        (cm->vlib_main, ip4_inacl_node.index, node_index);
+      next_index = vlib_node_add_next 
+        (cm->vlib_main, ip6_inacl_node.index, node_index);
+      ASSERT(rv == next_index);
+
+      *next_indexp = next_index;
+      return 1;
+    }
+  return 0;
+}
+
+static uword 
+unformat_l2_next_node (unformat_input_t * input, va_list * args)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+  u32 * next_indexp = va_arg (*args, u32 *);
+  u32 node_index;
+  u32 next_index;
+
+  if (unformat (input, "node %U", unformat_vlib_node,
+                cm->vlib_main, &node_index))
+    {
+      next_index = vlib_node_add_next 
+        (cm->vlib_main, l2_classify_node.index, node_index);
+
+      *next_indexp = next_index;
+      return 1;
+    }
+  return 0;
+}
+
+
+static clib_error_t * 
+vnet_classify_init (vlib_main_t * vm)
+{
+  vnet_classify_main_t * cm = &vnet_classify_main;
+
+  cm->vlib_main = vm;
+  cm->vnet_main = vnet_get_main();
+
+  vnet_classify_register_unformat_opaque_index_fn 
+    (unformat_opaque_sw_if_index);
+
+  vnet_classify_register_unformat_ip_next_index_fn
+    (unformat_ip_next_node);
+
+  vnet_classify_register_unformat_l2_next_index_fn
+    (unformat_l2_next_node);
+
+  vnet_classify_register_unformat_acl_next_index_fn
+    (unformat_acl_next_node);
+
+  return 0;
+}
+
+VLIB_INIT_FUNCTION (vnet_classify_init);
+
 #define TEST_CODE 1
 
 #if TEST_CODE > 0
index e33e6da..b7056c5 100644 (file)
@@ -158,12 +158,18 @@ struct _vnet_classify_main {
   /* Table pool */
   vnet_classify_table_t * tables;
   
+  /* Registered next-index, opaque unformat fcns */
+  unformat_function_t ** unformat_l2_next_index_fns;
+  unformat_function_t ** unformat_ip_next_index_fns;
+  unformat_function_t ** unformat_acl_next_index_fns;
+  unformat_function_t ** unformat_opaque_index_fns;
+
   /* convenience variables */
   vlib_main_t * vlib_main;
   vnet_main_t * vnet_main;
 };
 
-vnet_classify_main_t vnet_classify_main;
+extern vnet_classify_main_t vnet_classify_main;
 
 u8 * format_classify_table (u8 * s, va_list * args);
 
@@ -469,4 +475,15 @@ unformat_function_t unformat_vlan_tag;
 unformat_function_t unformat_l2_match;
 unformat_function_t unformat_classify_match;
 
+void vnet_classify_register_unformat_ip_next_index_fn 
+(unformat_function_t * fn);
+
+void vnet_classify_register_unformat_l2_next_index_fn 
+(unformat_function_t * fn);
+
+void vnet_classify_register_unformat_acl_next_index_fn 
+(unformat_function_t * fn);
+
+void vnet_classify_register_unformat_opaque_index_fn (unformat_function_t * fn);
+
 #endif /* __included_vnet_classify_h__ */
index 35159bf..76a2552 100644 (file)
@@ -218,4 +218,7 @@ ip_incremental_checksum_buffer (vlib_main_t * vm, vlib_buffer_t * first_buffer,
 
 void ip_del_all_interface_addresses (vlib_main_t *vm, u32 sw_if_index);
 
+extern vlib_node_registration_t ip4_inacl_node;
+extern vlib_node_registration_t ip6_inacl_node;
+
 #endif /* included_ip_main_h */
index 75aa9ef..fb7255e 100644 (file)
@@ -71,6 +71,9 @@ ip_inacl_inline (vlib_main_t * vm,
   u32 chain_hits = 0;
   input_acl_table_id_t tid;
   vlib_node_runtime_t * error_node;
+  u32 n_next_nodes;
+
+  n_next_nodes = node->n_next_nodes;
 
   if (is_ip4)
     {
@@ -245,7 +248,7 @@ ip_inacl_inline (vlib_main_t * vm,
                 {
                   vlib_buffer_advance (b0, e0->advance);
 
-                  next0 = (e0->next_index < ACL_NEXT_INDEX_N_NEXT)?
+                  next0 = (e0->next_index < n_next_nodes)?
                            e0->next_index:next0;
 
                   hits++;
@@ -267,7 +270,7 @@ ip_inacl_inline (vlib_main_t * vm,
                                                 t0->next_table_index);
                       else
                         {
-                          next0 = (t0->miss_next_index < ACL_NEXT_INDEX_N_NEXT)?
+                          next0 = (t0->miss_next_index < n_next_nodes)?
                                    t0->miss_next_index:next0;
 
                           misses++;
@@ -288,7 +291,7 @@ ip_inacl_inline (vlib_main_t * vm,
                       if (e0)
                         {
                           vlib_buffer_advance (b0, e0->advance);
-                          next0 = (e0->next_index < ACL_NEXT_INDEX_N_NEXT)?
+                          next0 = (e0->next_index < n_next_nodes)?
                                    e0->next_index:next0;
                           hits++;
                           chain_hits++;
index 5341151..850cdc1 100644 (file)
@@ -158,6 +158,7 @@ mpls_policy_encap_init (vlib_main_t * vm)
 {
   mpls_main_t * mm = &mpls_main;
   clib_error_t * error;
+  u32 ip6_next_index;
 
   if ((error = vlib_call_init_function (vm, mpls_init)))
     return error;
@@ -166,6 +167,21 @@ mpls_policy_encap_init (vlib_main_t * vm)
     vlib_node_add_next (mm->vlib_main,
                         ip4_classify_node.index, 
                         mpls_policy_encap_node.index);
+
+  /* 
+   * Must add the same arc to ip6_classify so the
+   * next-index vectors are congruent
+   */
+  ip6_next_index = 
+    vlib_node_add_next (mm->vlib_main,
+                        ip6_classify_node.index, 
+                        mpls_policy_encap_node.index);
+
+  if (ip6_next_index != mm->ip_classify_mpls_policy_encap_next_index)
+    return clib_error_return 
+      (0, "ip4/ip6 classifier next vector botch: %d vs %d", 
+       ip6_next_index, mm->ip_classify_mpls_policy_encap_next_index);
+
   return 0;
 }
 
index f6d21a6..03139c0 100644 (file)
@@ -91,6 +91,7 @@ int main (int argc, char * argv[])
 #if __SSE3__
       _("sse3", "SSE3")
 #endif
+#undef _
 #endif
 
     /*