span: fix wrong next1 feature index in dual loop
[vpp.git] / vnet / vnet / vxlan-gpe / decap.c
index 34bcccd..f6d1402 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/**
+ *  @file
+ *  @brief Functions for decapsulating VXLAN GPE tunnels
+ *
+*/
 
 #include <vlib/vlib.h>
 #include <vnet/pg/pg.h>
 
 vlib_node_registration_t vxlan_gpe_input_node;
 
+/**
+ * @brief Struct for VXLAN GPE decap packet tracing
+ *
+ */
 typedef struct {
   u32 next_index;
   u32 tunnel_index;
   u32 error;
 } vxlan_gpe_rx_trace_t;
 
+/**
+ * @brief Tracing function for VXLAN GPE packet decapsulation
+ *
+ * @param *s
+ * @param *args
+ *
+ * @return *s
+ *
+ */
 static u8 * format_vxlan_gpe_rx_trace (u8 * s, va_list * args)
 {
   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
@@ -46,7 +64,15 @@ static u8 * format_vxlan_gpe_rx_trace (u8 * s, va_list * args)
   return s;
 }
 
-
+/**
+ * @brief Tracing function for VXLAN GPE packet decapsulation including length
+ *
+ * @param *s
+ * @param *args
+ *
+ * @return *s
+ *
+ */
 static u8 * format_vxlan_gpe_with_length (u8 * s, va_list * args)
 {
   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
@@ -56,6 +82,25 @@ static u8 * format_vxlan_gpe_with_length (u8 * s, va_list * args)
   return s;
 }
 
+/**
+ * @brief Common processing for IPv4 and IPv6 VXLAN GPE decap dispatch functions
+ *
+ * It is worth noting that other than trivial UDP forwarding (transit), VXLAN GPE
+ * tunnels are "terminate local". This means that there is no "TX" interface for this
+ * decap case, so that field in the buffer_metadata can be "used for something else".
+ * The something else in this case is, for the IPv4/IPv6 inner-packet type case, the
+ * FIB index used to look up the inner-packet's adjacency.
+ *
+ *      vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->decap_fib_index;
+ *
+ * @param *vm
+ * @param *node
+ * @param *from_frame
+ * @param is_ip4
+ *
+ * @return from_frame->n_vectors
+ *
+ */
 always_inline uword
 vxlan_gpe_input (vlib_main_t * vm,
                      vlib_node_runtime_t * node,
@@ -73,7 +118,10 @@ vxlan_gpe_input (vlib_main_t * vm,
   u32 cpu_index = os_get_cpu_number ();
   u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
 
-  memset (&last_key4, 0xff, sizeof(last_key4));
+  if (is_ip4)
+      memset (&last_key4, 0xff, sizeof(last_key4));
+  else
+      memset (&last_key6, 0xff, sizeof(last_key6));
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
@@ -179,7 +227,31 @@ vxlan_gpe_input (vlib_main_t * vm,
 
         key4_0.pad = 0;
         key4_1.pad = 0;
+      }
+      else /* is_ip6 */
+      {
+        next0 = (iuvn6_0->vxlan.protocol < node->n_next_nodes) ?
+                iuvn6_0->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP;
+        next1 = (iuvn6_1->vxlan.protocol < node->n_next_nodes) ?
+                iuvn6_1->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP;
+
+        key6_0.local.as_u64[0] = iuvn6_0->ip6.dst_address.as_u64[0];
+        key6_0.local.as_u64[1] = iuvn6_0->ip6.dst_address.as_u64[1];
+        key6_1.local.as_u64[0] = iuvn6_1->ip6.dst_address.as_u64[0];
+        key6_1.local.as_u64[1] = iuvn6_1->ip6.dst_address.as_u64[1];
+
+        key6_0.remote.as_u64[0] = iuvn6_0->ip6.src_address.as_u64[0];
+        key6_0.remote.as_u64[1] = iuvn6_0->ip6.src_address.as_u64[1];
+        key6_1.remote.as_u64[0] = iuvn6_1->ip6.src_address.as_u64[0];
+        key6_1.remote.as_u64[1] = iuvn6_1->ip6.src_address.as_u64[1];
+
+        key6_0.vni = iuvn6_0->vxlan.vni_res;
+        key6_1.vni = iuvn6_1->vxlan.vni_res;
+      }
 
+      /* Processing packet 0*/
+      if (is_ip4)
+      {
         /* Processing for key4_0 */
         if (PREDICT_FALSE((key4_0.as_u64[0] != last_key4.as_u64[0])
                 || (key4_0.as_u64[1] != last_key4.as_u64[1])))
@@ -201,24 +273,6 @@ vxlan_gpe_input (vlib_main_t * vm,
       }
       else /* is_ip6 */
       {
-        next0 = (iuvn6_0->vxlan.protocol < node->n_next_nodes) ?
-                iuvn6_0->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP;
-        next1 = (iuvn6_1->vxlan.protocol < node->n_next_nodes) ?
-                iuvn6_1->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP;
-
-        key6_0.local.as_u64[0] = iuvn6_0->ip6.dst_address.as_u64[0];
-        key6_0.local.as_u64[1] = iuvn6_0->ip6.dst_address.as_u64[1];
-        key6_1.local.as_u64[0] = iuvn6_1->ip6.dst_address.as_u64[0];
-        key6_1.local.as_u64[1] = iuvn6_1->ip6.dst_address.as_u64[1];
-
-        key6_0.remote.as_u64[0] = iuvn6_0->ip6.src_address.as_u64[0];
-        key6_0.remote.as_u64[1] = iuvn6_0->ip6.src_address.as_u64[1];
-        key6_1.remote.as_u64[0] = iuvn6_1->ip6.src_address.as_u64[0];
-        key6_1.remote.as_u64[1] = iuvn6_1->ip6.src_address.as_u64[1];
-
-        key6_0.vni = iuvn6_0->vxlan.vni_res;
-        key6_1.vni = iuvn6_1->vxlan.vni_res;
-
         /* Processing for key6_0 */
         if (PREDICT_FALSE(memcmp (&key6_0, &last_key6, sizeof(last_key6)) != 0))
         {
@@ -247,7 +301,7 @@ vxlan_gpe_input (vlib_main_t * vm,
       /* Required to make the l2 tag push / pop code work on l2 subifs */
       vnet_update_l2_len (b0);
 
-      /*
+      /**
        * ip[46] lookup in the configured FIB
        */
       vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->decap_fib_index;
@@ -542,6 +596,17 @@ vxlan_gpe_input (vlib_main_t * vm,
   return from_frame->n_vectors;
 }
 
+/**
+ * @brief Graph processing dispatch function for IPv4 VXLAN GPE
+ *
+ * @node vxlan4-gpe-input
+ * @param *vm
+ * @param *node
+ * @param *from_frame
+ *
+ * @return from_frame->n_vectors
+ *
+ */
 static uword
 vxlan4_gpe_input (vlib_main_t * vm, vlib_node_runtime_t * node,
                   vlib_frame_t * from_frame)
@@ -549,6 +614,17 @@ vxlan4_gpe_input (vlib_main_t * vm, vlib_node_runtime_t * node,
   return vxlan_gpe_input (vm, node, from_frame, /* is_ip4 */1);
 }
 
+/**
+ * @brief Graph processing dispatch function for IPv6 VXLAN GPE
+ *
+ * @node vxlan6-gpe-input
+ * @param *vm
+ * @param *node
+ * @param *from_frame
+ *
+ * @return from_frame->n_vectors - uword
+ *
+ */
 static uword
 vxlan6_gpe_input (vlib_main_t * vm, vlib_node_runtime_t * node,
                   vlib_frame_t * from_frame)
@@ -556,6 +632,9 @@ vxlan6_gpe_input (vlib_main_t * vm, vlib_node_runtime_t * node,
   return vxlan_gpe_input (vm, node, from_frame, /* is_ip4 */0);
 }
 
+/**
+ * @brief VXLAN GPE error strings
+ */
 static char * vxlan_gpe_error_strings[] = {
 #define vxlan_gpe_error(n,s) s,
 #include <vnet/vxlan-gpe/vxlan_gpe_error.def>
@@ -584,7 +663,7 @@ VLIB_REGISTER_NODE (vxlan4_gpe_input_node) = {
   // $$$$ .unformat_buffer = unformat_vxlan_gpe_header,
 };
 
-VLIB_NODE_FUNCTION_MULTIARCH (vxlan4_gpe_input_node, vxlan4_gpe_input)
+VLIB_NODE_FUNCTION_MULTIARCH (vxlan4_gpe_input_node, vxlan4_gpe_input);
 
 VLIB_REGISTER_NODE (vxlan6_gpe_input_node) = {
   .function = vxlan6_gpe_input,
@@ -607,4 +686,4 @@ VLIB_REGISTER_NODE (vxlan6_gpe_input_node) = {
   // $$$$ .unformat_buffer = unformat_vxlan_gpe_header,
 };
 
-VLIB_NODE_FUNCTION_MULTIARCH (vxlan6_gpe_input_node, vxlan6_gpe_input)
+VLIB_NODE_FUNCTION_MULTIARCH (vxlan6_gpe_input_node, vxlan6_gpe_input);