VPP-19: Split the lookup.h IP_LOOKUP_NEXT enum. 50/1550/3
authorOle Troan <ot@cisco.com>
Tue, 14 Jun 2016 19:12:32 +0000 (21:12 +0200)
committerDave Barach <openvpp@barachs.net>
Thu, 16 Jun 2016 18:05:51 +0000 (18:05 +0000)
IP4 and IP6 nodes currently shares the adj->lookup_next_index. That
has some issues, e.g. that one has to add non-functional nodes like
ip4-hop-by-hop and that anyone dynamically adding nodes to any of the
IP4/IP6 lookup nodes must ensure they add themselves to all relevant
nodes to ensure next index consistency.

This patch splits the IP_LOOKUP_NEXT into separate enums for IP4 and
IP6 with a common part for next-nodes used by both. It sets up other
IP nodes as siblings to avoid inconsistencies. This allows IP4 and IP6
lookup next nodes to evolve independently. The adj->lookup_next_index is
still shared, assuming that an IP4 adjacency isn't used by an
IP6 graph node.

Change-Id: I589b8364fe54e7a10c059b7ef9d6707eb0a345cc
Signed-off-by: Ole Troan <ot@cisco.com>
vnet/Makefile.am
vnet/vnet/classify/ip_classify.c
vnet/vnet/ip/ip4_forward.c
vnet/vnet/ip/ip4_hop_by_hop.c [deleted file]
vnet/vnet/ip/ip6_forward.c
vnet/vnet/ip/ip6_hop_by_hop.c
vnet/vnet/ip/ip6_neighbor.c
vnet/vnet/ip/ip_init.c
vnet/vnet/ip/lookup.h
vnet/vnet/mpls-gre/mpls.h
vnet/vnet/mpls-gre/policy_encap.c

index 41e066f..3d9e07d 100644 (file)
@@ -251,7 +251,6 @@ libvnet_la_SOURCES +=                               \
  vnet/ip/ip46_cli.c                            \
  vnet/ip/ip4_format.c                          \
  vnet/ip/ip4_forward.c                         \
- vnet/ip/ip4_hop_by_hop.c                      \
  vnet/ip/ip4_input.c                           \
  vnet/ip/ip4_mtrie.c                           \
  vnet/ip/ip4_pg.c                              \
index 75e80ad..c44f25e 100644 (file)
@@ -68,11 +68,15 @@ ip_classify_inline (vlib_main_t * vm,
   u32 hits = 0;
   u32 misses = 0;
   u32 chain_hits = 0;
+  u32 n_next;
 
-  if (is_ip4)
+  if (is_ip4) {
     lm = &ip4_main.lookup_main;
-  else
+    n_next = IP4_LOOKUP_N_NEXT;
+  } else {
     lm = &ip6_main.lookup_main;
+    n_next = IP6_LOOKUP_N_NEXT;
+  }
 
   from = vlib_frame_vector_args (frame);
   n_left_from = frame->n_vectors;
@@ -253,8 +257,8 @@ ip_classify_inline (vlib_main_t * vm,
                                                 t0->next_table_index);
                       else
                         {
-                          next0 = (t0->miss_next_index < IP_LOOKUP_N_NEXT)?
-                                   t0->miss_next_index:next0;
+                          next0 = (t0->miss_next_index < n_next) ?
+                                   t0->miss_next_index : next0;
                           misses++;
                           break;
                         }
@@ -321,12 +325,12 @@ VLIB_REGISTER_NODE (ip4_classify_node) = {
   .function = ip4_classify,
   .name = "ip4-classify",
   .vector_size = sizeof (u32),
+  .sibling_of = "ip4-lookup",
   .format_trace = format_ip_classify_trace,
   .n_errors = ARRAY_LEN(ip_classify_error_strings),
   .error_strings = ip_classify_error_strings,
 
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP4_LOOKUP_NEXT_NODES,
+  .n_next_nodes = 0,
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (ip4_classify_node, ip4_classify)
@@ -344,12 +348,12 @@ VLIB_REGISTER_NODE (ip6_classify_node) = {
   .function = ip6_classify,
   .name = "ip6-classify",
   .vector_size = sizeof (u32),
+  .sibling_of = "ip6-lookup",
   .format_trace = format_ip_classify_trace,
   .n_errors = ARRAY_LEN(ip_classify_error_strings),
   .error_strings = ip_classify_error_strings,
 
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP6_LOOKUP_NEXT_NODES,
+  .n_next_nodes = 0,
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (ip6_classify_node, ip6_classify)
index 5327ba5..94c446b 100644 (file)
@@ -1364,7 +1364,7 @@ VLIB_REGISTER_NODE (ip4_lookup_node) = {
 
   .format_trace = format_ip4_lookup_trace,
 
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
+  .n_next_nodes = IP4_LOOKUP_N_NEXT,
   .next_nodes = IP4_LOOKUP_NEXT_NODES,
 };
 
@@ -1384,11 +1384,10 @@ VLIB_REGISTER_NODE (ip4_indirect_node) = {
   .function = ip4_indirect,
   .name = "ip4-indirect",
   .vector_size = sizeof (u32),
-
+  .sibling_of = "ip4-lookup",
   .format_trace = format_ip4_lookup_trace,
 
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP4_LOOKUP_NEXT_NODES,
+  .n_next_nodes = 0,
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (ip4_indirect_node, ip4_indirect)
@@ -3088,11 +3087,10 @@ VLIB_REGISTER_NODE (ip4_lookup_multicast_node,static) = {
   .function = ip4_lookup_multicast,
   .name = "ip4-lookup-multicast",
   .vector_size = sizeof (u32),
-
+  .sibling_of = "ip4-lookup",
   .format_trace = format_ip4_lookup_trace,
 
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP4_LOOKUP_NEXT_NODES,
+  .n_next_nodes = 0,
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (ip4_lookup_multicast_node, ip4_lookup_multicast)
diff --git a/vnet/vnet/ip/ip4_hop_by_hop.c b/vnet/vnet/ip/ip4_hop_by_hop.c
deleted file mode 100644 (file)
index 177feb7..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
-#include <vppinfra/error.h>
-
-#include <vnet/ip/ip.h>
-
-#include <vppinfra/hash.h>
-#include <vppinfra/error.h>
-#include <vppinfra/elog.h>
-
-typedef struct {
-  /* convenience */
-  vlib_main_t * vlib_main;
-  vnet_main_t * vnet_main;
-} ip4_hop_by_hop_main_t;
-
-ip4_hop_by_hop_main_t ip4_hop_by_hop_main;
-
-vlib_node_registration_t ip4_hop_by_hop_node;
-
-typedef struct {
-  u32 next_index;
-} ip4_hop_by_hop_trace_t;
-
-/* packet trace format function */
-static u8 * format_ip4_hop_by_hop_trace (u8 * s, va_list * args)
-{
-  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
-  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
-  ip4_hop_by_hop_trace_t * t = va_arg (*args, ip4_hop_by_hop_trace_t *);
-  
-  s = format (s, "IP4_HOP_BY_HOP: next index %d",
-              t->next_index);
-  return s;
-}
-
-vlib_node_registration_t ip4_hop_by_hop_node;
-
-#define foreach_ip4_hop_by_hop_error \
-_(PROCESSED, "Pkts with ip4 hop-by-hop options")
-
-typedef enum {
-#define _(sym,str) IP4_HOP_BY_HOP_ERROR_##sym,
-  foreach_ip4_hop_by_hop_error
-#undef _
-  IP4_HOP_BY_HOP_N_ERROR,
-} ip4_hop_by_hop_error_t;
-
-static char * ip4_hop_by_hop_error_strings[] = {
-#define _(sym,string) string,
-  foreach_ip4_hop_by_hop_error
-#undef _
-};
-
-static uword
-ip4_hop_by_hop_node_fn (vlib_main_t * vm,
-                 vlib_node_runtime_t * node,
-                 vlib_frame_t * frame)
-{
-  ip4_main_t * im = &ip4_main;
-  ip_lookup_main_t * lm = &im->lookup_main;
-  u32 n_left_from, * from, * to_next;
-  ip_lookup_next_t next_index;
-  u32 processed = 0;
-
-  from = vlib_frame_vector_args (frame);
-  n_left_from = frame->n_vectors;
-  next_index = node->cached_next_index;
-
-  while (n_left_from > 0)
-    {
-      u32 n_left_to_next;
-
-      vlib_get_next_frame (vm, node, next_index,
-                          to_next, n_left_to_next);
-
-#if 0
-      while (n_left_from >= 4 && n_left_to_next >= 2)
-       {
-          u32 next0 = IP4_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
-          u32 next1 = IP4_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
-          u32 sw_if_index0, sw_if_index1;
-          u8 tmp0[6], tmp1[6];
-          ethernet_header_t *en0, *en1;
-          u32 bi0, bi1;
-         vlib_buffer_t * b0, * b1;
-          
-         /* Prefetch next iteration. */
-         {
-           vlib_buffer_t * p2, * p3;
-            
-           p2 = vlib_get_buffer (vm, from[2]);
-           p3 = vlib_get_buffer (vm, from[3]);
-            
-           vlib_prefetch_buffer_header (p2, LOAD);
-           vlib_prefetch_buffer_header (p3, LOAD);
-
-           CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE);
-         }
-
-          /* speculatively enqueue b0 and b1 to the current next frame */
-         to_next[0] = bi0 = from[0];
-         to_next[1] = bi1 = from[1];
-         from += 2;
-         to_next += 2;
-         n_left_from -= 2;
-         n_left_to_next -= 2;
-
-         b0 = vlib_get_buffer (vm, bi0);
-         b1 = vlib_get_buffer (vm, bi1);
-
-          /* $$$$$ Dual loop: process 2 x packets here $$$$$ */
-          ASSERT (b0->current_data == 0);
-          ASSERT (b1->current_data == 0);
-          
-          ip0 = vlib_buffer_get_current (b0);
-          ip1 = vlib_buffer_get_current (b0);
-
-          sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
-          sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
-
-          /* $$$$$ End of processing 2 x packets $$$$$ */
-
-          if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE)))
-            {
-              if (b0->flags & VLIB_BUFFER_IS_TRACED) 
-                {
-                    ip4_hop_by_hop_trace_t *t = 
-                      vlib_add_trace (vm, node, b0, sizeof (*t));
-                    t->sw_if_index = sw_if_index0;
-                    t->next_index = next0;
-                  }
-                if (b1->flags & VLIB_BUFFER_IS_TRACED) 
-                  {
-                    ip4_hop_by_hop_trace_t *t = 
-                      vlib_add_trace (vm, node, b1, sizeof (*t));
-                    t->sw_if_index = sw_if_index1;
-                    t->next_index = next1;
-                  }
-              }
-            
-            /* verify speculative enqueues, maybe switch current next frame */
-            vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
-                                             to_next, n_left_to_next,
-                                             bi0, bi1, next0, next1);
-        }
-#endif
-
-      while (n_left_from > 0 && n_left_to_next > 0)
-       {
-          u32 bi0;
-         vlib_buffer_t * b0;
-          u32 next0;
-          u32 adj_index0;
-          ip_adjacency_t * adj0;
-          
-          /* speculatively enqueue b0 to the current next frame */
-         bi0 = from[0];
-         to_next[0] = bi0;
-         from += 1;
-         to_next += 1;
-         n_left_from -= 1;
-         n_left_to_next -= 1;
-
-         b0 = vlib_get_buffer (vm, bi0);
-
-          adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
-          adj0 = ip_get_adjacency (lm, adj_index0);
-
-          /* $$$$$$$$$$$$ process one (or more) hop-by-hop header(s) here */
-          
-          
-          /* $$$$$$$$$$$$ */
-
-          /* Send the packet e.g. to ip4_rewrite */
-          next0 = adj0->lookup_next_index;
-
-          if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) 
-                            && (b0->flags & VLIB_BUFFER_IS_TRACED))) 
-            {
-              ip4_hop_by_hop_trace_t *t = 
-                 vlib_add_trace (vm, node, b0, sizeof (*t));
-              t->next_index = next0;
-            }
-            
-          processed++;
-
-          /* $$$$$ Done processing 1 packet here $$$$$ */
-
-          /* verify speculative enqueue, maybe switch current next frame */
-         vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
-                                          to_next, n_left_to_next,
-                                          bi0, next0);
-       }
-
-      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
-    }
-
-  vlib_node_increment_counter (vm, ip4_hop_by_hop_node.index, 
-                               IP4_HOP_BY_HOP_ERROR_PROCESSED, processed);
-  return frame->n_vectors;
-}
-
-VLIB_REGISTER_NODE (ip4_hop_by_hop_node) = {
-  .function = ip4_hop_by_hop_node_fn,
-  .name = "ip4-hop-by-hop",
-  .vector_size = sizeof (u32),
-  .format_trace = format_ip4_hop_by_hop_trace,
-  .type = VLIB_NODE_TYPE_INTERNAL,
-  
-  .n_errors = ARRAY_LEN(ip4_hop_by_hop_error_strings),
-  .error_strings = ip4_hop_by_hop_error_strings,
-
-  /* See ip/lookup.h */
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP4_LOOKUP_NEXT_NODES,
-};
-
-VLIB_NODE_FUNCTION_MULTIARCH (ip4_hop_by_hop_node, ip4_hop_by_hop_node_fn)
-
-VLIB_REGISTER_NODE (ip4_add_hop_by_hop_node) = {
-  .function = ip4_hop_by_hop_node_fn,
-  .name = "ip4-add-hop-by-hop",
-  .vector_size = sizeof (u32),
-  .format_trace = format_ip4_hop_by_hop_trace,
-  .type = VLIB_NODE_TYPE_INTERNAL,
-  
-  .n_errors = ARRAY_LEN(ip4_hop_by_hop_error_strings),
-  .error_strings = ip4_hop_by_hop_error_strings,
-
-  /* See ip/lookup.h */
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP4_LOOKUP_NEXT_NODES,
-};
-
-VLIB_REGISTER_NODE (ip4_pop_hop_by_hop_node) = {
-  .function = ip4_hop_by_hop_node_fn,
-  .name = "ip4-pop-hop-by-hop",
-  .vector_size = sizeof (u32),
-  .format_trace = format_ip4_hop_by_hop_trace,
-  .type = VLIB_NODE_TYPE_INTERNAL,
-  
-  .n_errors = ARRAY_LEN(ip4_hop_by_hop_error_strings),
-  .error_strings = ip4_hop_by_hop_error_strings,
-
-  /* See ip/lookup.h */
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP4_LOOKUP_NEXT_NODES,
-};
-
-static clib_error_t *
-ip4_hop_by_hop_init (vlib_main_t * vm)
-{
-  ip4_hop_by_hop_main_t * hm = &ip4_hop_by_hop_main;
-
-  hm->vlib_main = vm;
-  hm->vnet_main = vnet_get_main();
-
-  return 0;
-}
-
-VLIB_INIT_FUNCTION (ip4_hop_by_hop_init);
index ad2d0db..e49d242 100644 (file)
@@ -762,9 +762,9 @@ ip6_lookup_inline (vlib_main_t * vm,
 
          /* Only process the HBH Option Header if explicitly configured to do so */
           next0 = (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) && im->hbh_enabled &&
-           adj_index0 ? IP_LOOKUP_NEXT_HOP_BY_HOP : adj0->lookup_next_index;
+           adj_index0 ? IP6_LOOKUP_NEXT_HOP_BY_HOP : adj0->lookup_next_index;
           next1 = (ip1->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) && im->hbh_enabled &&
-           adj_index1 ? IP_LOOKUP_NEXT_HOP_BY_HOP : adj1->lookup_next_index;
+           adj_index1 ? IP6_LOOKUP_NEXT_HOP_BY_HOP : adj1->lookup_next_index;
 
           vnet_buffer (p0)->ip.flow_hash = 
             vnet_buffer(p1)->ip.flow_hash = 0;
@@ -893,7 +893,7 @@ ip6_lookup_inline (vlib_main_t * vm,
 
          /* Only process the HBH Option Header if explicitly configured to do so */
           next0 = (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) && im->hbh_enabled &&
-           adj_index0 ? IP_LOOKUP_NEXT_HOP_BY_HOP : adj0->lookup_next_index;
+           adj_index0 ? IP6_LOOKUP_NEXT_HOP_BY_HOP : adj0->lookup_next_index;
 
           vnet_buffer (p0)->ip.flow_hash = 0;
 
@@ -1271,7 +1271,7 @@ VLIB_REGISTER_NODE (ip6_lookup_node) = {
 
   .format_trace = format_ip6_lookup_trace,
 
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
+  .n_next_nodes = IP6_LOOKUP_N_NEXT,
   .next_nodes = IP6_LOOKUP_NEXT_NODES,
 };
 
@@ -1290,11 +1290,9 @@ VLIB_REGISTER_NODE (ip6_indirect_node) = {
   .function = ip6_indirect,
   .name = "ip6-indirect",
   .vector_size = sizeof (u32),
-
+  .sibling_of = "ip6-lookup",
   .format_trace = format_ip6_lookup_trace,
-
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP6_LOOKUP_NEXT_NODES,
+  .n_next_nodes = 0,
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (ip6_indirect_node, ip6_indirect)
@@ -2685,7 +2683,7 @@ ip6_hop_by_hop (vlib_main_t * vm,
     out0:
       /* Has the classifier flagged this buffer for special treatment? */
       if ((error0 == 0) && (vnet_buffer(b0)->l2_classify.opaque_index == OI_DECAP))
-       next0 = IP_LOOKUP_NEXT_POP_HOP_BY_HOP;
+       next0 = IP6_LOOKUP_NEXT_POP_HOP_BY_HOP;
 
       if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) {
        ip6_hop_by_hop_trace_t *t = vlib_add_trace(vm, node, b0, sizeof (*t));
index 1cc6b9f..df0dae5 100644 (file)
@@ -798,13 +798,12 @@ VLIB_REGISTER_NODE (ip6_pop_hop_by_hop_node) = {
   .vector_size = sizeof (u32),
   .format_trace = format_ip6_pop_hop_by_hop_trace,
   .type = VLIB_NODE_TYPE_INTERNAL,
-  
+  .sibling_of = "ip6-lookup",
   .n_errors = ARRAY_LEN(ip6_pop_hop_by_hop_error_strings),
   .error_strings = ip6_pop_hop_by_hop_error_strings,
 
   /* See ip/lookup.h */
-  .n_next_nodes = IP_LOOKUP_N_NEXT,
-  .next_nodes = IP6_LOOKUP_NEXT_NODES,
+  .n_next_nodes = 0,
 };
 
 VLIB_NODE_FUNCTION_MULTIARCH (ip6_pop_hop_by_hop_node,
@@ -1148,10 +1147,10 @@ int ip6_ioam_set_destination (ip6_address_t *addr, u32 mask_width, u32 vrf_id,
     adj->saved_lookup_next_index = adj->lookup_next_index;
 
   if (is_add)
-    adj->lookup_next_index = IP_LOOKUP_NEXT_ADD_HOP_BY_HOP;
+    adj->lookup_next_index = IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP;
 
   if (is_pop)
-    adj->lookup_next_index = IP_LOOKUP_NEXT_POP_HOP_BY_HOP;
+    adj->lookup_next_index = IP6_LOOKUP_NEXT_POP_HOP_BY_HOP;
 
   hm->adj = *addr;
   hm->ioam_flag = (is_add ? IOAM_HBYH_ADD :
index 0dad232..f161036 100644 (file)
@@ -751,7 +751,7 @@ icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
               /* Allow all realistic-looking rewrite adjacencies to pass */
               ni0 = adj0->lookup_next_index;
               is_rewrite0 = (ni0 >= IP_LOOKUP_NEXT_ARP) &&
-                (ni0 < IP_LOOKUP_N_NEXT);
+                (ni0 < IP6_LOOKUP_N_NEXT);
 
              error0 = ((adj0->rewrite_header.sw_if_index != sw_if_index0
                          || ! is_rewrite0)
index b6b2ea1..8b6659d 100644 (file)
@@ -121,9 +121,6 @@ do {                                                \
   if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_init)))
     return error;
 
-  if ((error = vlib_call_init_function (vm, ip4_hop_by_hop_init)))
-    return error;
-
   if ((error = vlib_call_init_function (vm, udp_local_init)))
     return error;
 
index 30c1291..a7aef9f 100644 (file)
@@ -45,7 +45,7 @@
 #include <vnet/ip/ip4_packet.h>
 #include <vnet/ip/ip6_packet.h>
 
-/* Next index stored in adjacency. */
+/* Common (IP4/IP6) next index stored in adjacency. */
 typedef enum {
   /* Packet does not match any route in table. */
   IP_LOOKUP_NEXT_MISS,
@@ -82,16 +82,23 @@ typedef enum {
   /* This packets needs to go to indirect next hop */
   IP_LOOKUP_NEXT_INDIRECT,
 
-  /* Hop-by-hop header handling */
-  IP_LOOKUP_NEXT_HOP_BY_HOP,
-  IP_LOOKUP_NEXT_ADD_HOP_BY_HOP,
-  IP_LOOKUP_NEXT_POP_HOP_BY_HOP,
-
   IP_LOOKUP_NEXT_ICMP_ERROR,
 
   IP_LOOKUP_N_NEXT,
 } ip_lookup_next_t;
 
+typedef enum {
+  IP4_LOOKUP_N_NEXT = IP_LOOKUP_N_NEXT,
+} ip4_lookup_next_t;
+
+typedef enum {
+  /* Hop-by-hop header handling */
+  IP6_LOOKUP_NEXT_HOP_BY_HOP = IP_LOOKUP_N_NEXT,
+  IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP,
+  IP6_LOOKUP_NEXT_POP_HOP_BY_HOP,
+  IP6_LOOKUP_N_NEXT,
+} ip6_lookup_next_t;
+
 #define IP4_LOOKUP_NEXT_NODES {                                        \
     [IP_LOOKUP_NEXT_MISS] = "ip4-miss",                                \
     [IP_LOOKUP_NEXT_DROP] = "ip4-drop",                                \
@@ -103,9 +110,6 @@ typedef enum {
     [IP_LOOKUP_NEXT_MAP] = "ip4-map",                          \
     [IP_LOOKUP_NEXT_MAP_T] = "ip4-map-t",                      \
     [IP_LOOKUP_NEXT_SIXRD] = "ip4-sixrd",                      \
-    [IP_LOOKUP_NEXT_HOP_BY_HOP] = "ip4-hop-by-hop",            \
-    [IP_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip4-add-hop-by-hop",    \
-    [IP_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip4-pop-hop-by-hop",    \
     [IP_LOOKUP_NEXT_INDIRECT] = "ip4-indirect",                        \
     [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error",            \
 }
@@ -121,11 +125,11 @@ typedef enum {
     [IP_LOOKUP_NEXT_MAP] = "ip6-map",                          \
     [IP_LOOKUP_NEXT_MAP_T] = "ip6-map-t",                      \
     [IP_LOOKUP_NEXT_SIXRD] = "ip6-sixrd",                      \
-    [IP_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",            \
-    [IP_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",    \
-    [IP_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",    \
     [IP_LOOKUP_NEXT_INDIRECT] = "ip6-indirect",                        \
     [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip6-icmp-error",            \
+    [IP6_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",           \
+    [IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",   \
+    [IP6_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",   \
 }
 
 /* Flow hash configuration */
index e2fe42e..cd487b2 100644 (file)
@@ -95,8 +95,9 @@ typedef struct {
   mpls_decap_t * decaps;
   uword * mpls_decap_by_rx_fib_and_label;
 
-  /* mpls-o-e policy tunnel next index for ip4-classify */
-  u32 ip_classify_mpls_policy_encap_next_index;
+  /* mpls-o-e policy tunnel next index for ip4/ip6-classify */
+  u32 ip4_classify_mpls_policy_encap_next_index;
+  u32 ip6_classify_mpls_policy_encap_next_index;
 
   /* convenience */
   vlib_main_t * vlib_main;
index e3f4beb..0ea051f 100644 (file)
@@ -160,30 +160,20 @@ 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;
   
-  mm->ip_classify_mpls_policy_encap_next_index = 
+  mm->ip4_classify_mpls_policy_encap_next_index =
     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 = 
+  mm->ip6_classify_mpls_policy_encap_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;
 }