Add support for transparent ethernet bridging to GRE
[vpp.git] / vnet / vnet / gre / node.c
index 97f9dac..d5ea4b6 100644 (file)
@@ -23,6 +23,7 @@
 #define foreach_gre_input_next                 \
 _(PUNT, "error-punt")                           \
 _(DROP, "error-drop")                           \
+_(ETHERNET_INPUT, "ethernet-input")             \
 _(IP4_INPUT, "ip4-input")                       \
 _(IP6_INPUT, "ip6-input")                      
 
@@ -160,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);
@@ -207,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);
@@ -256,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)) 
@@ -326,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);
@@ -375,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:
@@ -476,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; 
@@ -494,6 +503,8 @@ static clib_error_t * gre_input_init (vlib_main_t * vm)
      /* bits in index */ BITS (((gre_header_t *) 0)->protocol));
 
   /* 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");
@@ -501,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);