VPP-189: fix coverity issue in api_format.c
[vpp.git] / vnet / vnet / gre / node.c
index 7d07223..d5ea4b6 100644 (file)
@@ -23,8 +23,9 @@
 #define foreach_gre_input_next                 \
 _(PUNT, "error-punt")                           \
 _(DROP, "error-drop")                           \
+_(ETHERNET_INPUT, "ethernet-input")             \
 _(IP4_INPUT, "ip4-input")                       \
-_(IP6_INPUT, "ip6-input")
+_(IP6_INPUT, "ip6-input")                      
 
 typedef enum {
 #define _(s,n) GRE_INPUT_NEXT_##s,
@@ -57,8 +58,6 @@ typedef struct {
   /* Sparse vector mapping gre protocol in network byte order
      to next index. */
   u16 * next_by_protocol;
-
-  u32 * sparse_index_by_next_index;
 } gre_input_runtime_t;
 
 static uword
@@ -68,7 +67,7 @@ gre_input (vlib_main_t * vm,
 {
   gre_main_t * gm = &gre_main;
   gre_input_runtime_t * rt = (void *) node->runtime_data;
-  __attribute__((unused)) u32 n_left_from, next_index, i_next, * from, * to_next;
+  __attribute__((unused)) u32 n_left_from, next_index, * from, * to_next;
   u64 cached_tunnel_key = (u64) ~0;
   u32 cached_tunnel_sw_if_index = 0, tunnel_sw_if_index;
   u32 cached_tunnel_fib_index = 0, tunnel_fib_index;
@@ -79,7 +78,6 @@ gre_input (vlib_main_t * vm,
   n_left_from = from_frame->n_vectors;
 
   next_index = node->cached_next_index;
-  i_next = vec_elt (rt->sparse_index_by_next_index, next_index);
 
   while (n_left_from > 0)
     {
@@ -148,8 +146,8 @@ gre_input (vlib_main_t * vm,
           next0 = vec_elt(rt->next_by_protocol, i0);
           next1 = vec_elt(rt->next_by_protocol, i1);
 
-         b0->error = node->errors[next0 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
-         b1->error = node->errors[next1 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
+         b0->error = node->errors[i0 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
+         b1->error = node->errors[i1 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
           
           version0 = clib_net_to_host_u16 (h0->flags_and_version);
           verr0 =  version0 & GRE_VERSION_MASK;
@@ -163,9 +161,11 @@ gre_input (vlib_main_t * vm,
               : b1->error;
           next1 = verr1 ? GRE_INPUT_NEXT_DROP : next1;
 
+
           /* RPF check for ip4/ip6 input */
-          if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT 
-                            || next0 == GRE_INPUT_NEXT_IP6_INPUT))
+          if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
+                            || next0 == GRE_INPUT_NEXT_IP6_INPUT
+                            || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT))
             {
               u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
                          (u64)(vnet_buffer(b0)->gre.src);
@@ -210,11 +210,13 @@ gre_input (vlib_main_t * vm,
                                                len /* bytes */);
 
               vnet_buffer(b0)->sw_if_index[VLIB_TX] = tunnel_fib_index;
+              vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
             }
 
 drop0:
-          if (PREDICT_FALSE(next1 == GRE_INPUT_NEXT_IP4_INPUT 
-                            || next1 == GRE_INPUT_NEXT_IP6_INPUT))
+          if (PREDICT_FALSE(next1 == GRE_INPUT_NEXT_IP4_INPUT
+                            || next1 == GRE_INPUT_NEXT_IP6_INPUT
+                            || next1 == GRE_INPUT_NEXT_ETHERNET_INPUT))
             {
               u64 key = ((u64)(vnet_buffer(b1)->gre.dst) << 32) |
                          (u64)(vnet_buffer(b1)->gre.src);
@@ -259,6 +261,7 @@ drop0:
                                                len /* bytes */);
 
               vnet_buffer(b1)->sw_if_index[VLIB_TX] = tunnel_fib_index;
+              vnet_buffer(b1)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
             }
 drop1:
           if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
@@ -320,7 +323,7 @@ drop1:
           next0 = vec_elt(rt->next_by_protocol, i0);
 
          b0->error = 
-              node->errors[next0 == SPARSE_VEC_INVALID_INDEX 
+              node->errors[i0 == SPARSE_VEC_INVALID_INDEX 
                            ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
          
           version0 = clib_net_to_host_u16 (h0->flags_and_version);
@@ -329,11 +332,13 @@ drop1:
               : b0->error;
           next0 = verr0 ? GRE_INPUT_NEXT_DROP : next0;
 
+
           /* For IP payload we need to find source interface
              so we can increase counters and help forward node to
              pick right FIB */
-          if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT 
-                            || next0 == GRE_INPUT_NEXT_IP6_INPUT))
+          if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
+                            || next0 == GRE_INPUT_NEXT_IP6_INPUT
+                            || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT))
             {
               u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
                          (u64)(vnet_buffer(b0)->gre.src);
@@ -378,6 +383,7 @@ drop1:
                                                len /* bytes */);
 
               vnet_buffer(b0)->sw_if_index[VLIB_TX] = tunnel_fib_index;
+              vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
             }
 
 drop:
@@ -434,6 +440,8 @@ VLIB_REGISTER_NODE (gre_input_node) = {
   .unformat_buffer = unformat_gre_header,
 };
 
+VLIB_NODE_FUNCTION_MULTIARCH (gre_input_node, gre_input)
+
 void
 gre_register_input_protocol (vlib_main_t * vm,
                             gre_protocol_t protocol,
@@ -443,7 +451,6 @@ gre_register_input_protocol (vlib_main_t * vm,
   gre_protocol_info_t * pi;
   gre_input_runtime_t * rt;
   u16 * n;
-  u32 i;
 
   {
     clib_error_t * error = vlib_call_init_function (vm, gre_input_init);
@@ -462,12 +469,6 @@ gre_register_input_protocol (vlib_main_t * vm,
   n = sparse_vec_validate (rt->next_by_protocol, 
                            clib_host_to_net_u16 (protocol));
   n[0] = pi->next_index;
-
-  /* Rebuild next index -> sparse index inverse mapping when sparse vector
-     is updated. */
-  vec_validate (rt->sparse_index_by_next_index, pi->next_index);
-  for (i = 1; i < vec_len (rt->next_by_protocol); i++)
-    rt->sparse_index_by_next_index[rt->next_by_protocol[i]] = i;
 }
 
 static void
@@ -484,7 +485,7 @@ gre_setup_node (vlib_main_t * vm, u32 node_index)
 static clib_error_t * gre_input_init (vlib_main_t * vm)
 {
   gre_input_runtime_t * rt;
-  vlib_node_t *ip4_input, *ip6_input, *mpls_unicast_input;
+  vlib_node_t *ethernet_input, *ip4_input, *ip6_input, *mpls_unicast_input;
 
   {
     clib_error_t * error; 
@@ -501,14 +502,9 @@ static clib_error_t * gre_input_init (vlib_main_t * vm)
     (/* elt bytes */ sizeof (rt->next_by_protocol[0]),
      /* bits in index */ BITS (((gre_header_t *) 0)->protocol));
 
-  vec_validate (rt->sparse_index_by_next_index, GRE_INPUT_NEXT_DROP);
-  vec_validate (rt->sparse_index_by_next_index, GRE_INPUT_NEXT_PUNT);
-  rt->sparse_index_by_next_index[GRE_INPUT_NEXT_DROP]
-    = SPARSE_VEC_INVALID_INDEX;
-  rt->sparse_index_by_next_index[GRE_INPUT_NEXT_PUNT]
-    = SPARSE_VEC_INVALID_INDEX;
-
   /* These could be moved to the supported protocol input node defn's */
+  ethernet_input = vlib_get_node_by_name (vm, (u8 *)"ethernet-input");
+  ASSERT(ethernet_input);
   ip4_input = vlib_get_node_by_name (vm, (u8 *)"ip4-input");
   ASSERT(ip4_input);
   ip6_input = vlib_get_node_by_name (vm, (u8 *)"ip6-input");
@@ -516,6 +512,9 @@ static clib_error_t * gre_input_init (vlib_main_t * vm)
   mpls_unicast_input = vlib_get_node_by_name (vm, (u8 *)"mpls-gre-input");
   ASSERT(mpls_unicast_input);
 
+  gre_register_input_protocol (vm, GRE_PROTOCOL_teb,
+                               ethernet_input->index);
+
   gre_register_input_protocol (vm, GRE_PROTOCOL_ip4, 
                                ip4_input->index);