IPv4/6 reassembly
[vpp.git] / src / vnet / ip / ip4_forward.c
index c7cf362..2a21135 100755 (executable)
@@ -883,11 +883,11 @@ ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
       if (0 != --im->ip_enabled_by_sw_if_index[sw_if_index])
        return;
     }
-  vnet_feature_enable_disable ("ip4-unicast", "ip4-drop", sw_if_index,
+  vnet_feature_enable_disable ("ip4-unicast", "ip4-not-enabled", sw_if_index,
                               !is_enable, 0, 0);
 
 
-  vnet_feature_enable_disable ("ip4-multicast", "ip4-drop",
+  vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
                               sw_if_index, !is_enable, 0, 0);
 }
 
@@ -1066,10 +1066,10 @@ VNET_FEATURE_INIT (ip4_vxlan_bypass, static) =
   .runs_before = VNET_FEATURES ("ip4-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_drop, static) =
+VNET_FEATURE_INIT (ip4_not_enabled, static) =
 {
   .arc_name = "ip4-unicast",
-  .node_name = "ip4-drop",
+  .node_name = "ip4-not-enabled",
   .runs_before = VNET_FEATURES ("ip4-lookup"),
 };
 
@@ -1095,10 +1095,10 @@ VNET_FEATURE_INIT (ip4_vpath_mc, static) =
   .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_mc_drop, static) =
+VNET_FEATURE_INIT (ip4_mc_not_enabled, static) =
 {
   .arc_name = "ip4-multicast",
-  .node_name = "ip4-drop",
+  .node_name = "ip4-not-enabled",
   .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
 };
 
@@ -1113,7 +1113,7 @@ VNET_FEATURE_INIT (ip4_lookup_mc, static) =
 VNET_FEATURE_ARC_INIT (ip4_output, static) =
 {
   .arc_name = "ip4-output",
-  .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain"),
+  .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain", "ip4-dvr-dpo"),
   .arc_index_ptr = &ip4_main.lookup_main.output_feature_arc_index,
 };
 
@@ -1166,11 +1166,11 @@ ip4_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
       /* *INDENT-ON* */
     }
 
-  vnet_feature_enable_disable ("ip4-unicast", "ip4-drop", sw_if_index,
+  vnet_feature_enable_disable ("ip4-unicast", "ip4-not-enabled", sw_if_index,
                               is_add, 0, 0);
 
-  vnet_feature_enable_disable ("ip4-multicast", "ip4-drop", sw_if_index,
-                              is_add, 0, 0);
+  vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
+                              sw_if_index, is_add, 0, 0);
 
   return /* no error */ 0;
 }
@@ -1582,8 +1582,12 @@ ip4_local_inline (vlib_main_t * vm,
 
          /* Treat IP frag packets as "experimental" protocol for now
             until support of IP frag reassembly is implemented */
-         proto0 = ip4_is_fragment (ip0) ? 0xfe : ip0->protocol;
-         proto1 = ip4_is_fragment (ip1) ? 0xfe : ip1->protocol;
+         proto0 =
+           ip4_is_fragment (ip0) ? IP_PROTOCOL_VPP_FRAGMENTATION :
+           ip0->protocol;
+         proto1 =
+           ip4_is_fragment (ip1) ? IP_PROTOCOL_VPP_FRAGMENTATION :
+           ip1->protocol;
 
          if (head_of_feature_arc == 0)
            goto skip_checks;
@@ -1748,7 +1752,9 @@ ip4_local_inline (vlib_main_t * vm,
 
          /* Treat IP frag packets as "experimental" protocol for now
             until support of IP frag reassembly is implemented */
-         proto0 = ip4_is_fragment (ip0) ? 0xfe : ip0->protocol;
+         proto0 =
+           ip4_is_fragment (ip0) ? IP_PROTOCOL_VPP_FRAGMENTATION :
+           ip0->protocol;
 
          if (head_of_feature_arc == 0 || p0->flags & VNET_BUFFER_F_IS_NATED)
            goto skip_check;
@@ -1839,6 +1845,7 @@ VLIB_REGISTER_NODE (ip4_local_node) =
     [IP_LOCAL_NEXT_PUNT] = "ip4-punt",
     [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip4-udp-lookup",
     [IP_LOCAL_NEXT_ICMP] = "ip4-icmp-input",
+    [IP_LOCAL_NEXT_REASSEMBLY] = "ip4-reassembly",
   },
 };
 /* *INDENT-ON* */
@@ -2477,6 +2484,16 @@ ip4_rewrite_inline (vlib_main_t * vm,
             rewrite_header.max_l3_packet_bytes ? IP4_ERROR_MTU_EXCEEDED :
             error1);
 
+         if (is_mcast)
+           {
+             error0 = ((adj0[0].rewrite_header.sw_if_index ==
+                        vnet_buffer (p0)->sw_if_index[VLIB_RX]) ?
+                       IP4_ERROR_SAME_INTERFACE : error0);
+             error1 = ((adj1[0].rewrite_header.sw_if_index ==
+                        vnet_buffer (p1)->sw_if_index[VLIB_RX]) ?
+                       IP4_ERROR_SAME_INTERFACE : error1);
+           }
+
          /* Don't adjust the buffer for ttl issue; icmp-error node wants
           * to see the IP headerr */
          if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
@@ -2531,8 +2548,10 @@ ip4_rewrite_inline (vlib_main_t * vm,
 
          if (is_midchain)
            {
-             adj0->sub_type.midchain.fixup_func (vm, adj0, p0);
-             adj1->sub_type.midchain.fixup_func (vm, adj1, p1);
+             adj0->sub_type.midchain.fixup_func
+               (vm, adj0, p0, adj0->sub_type.midchain.fixup_data);
+             adj1->sub_type.midchain.fixup_func
+               (vm, adj1, p1, adj0->sub_type.midchain.fixup_data);
            }
          if (is_mcast)
            {
@@ -2636,7 +2655,12 @@ ip4_rewrite_inline (vlib_main_t * vm,
          error0 = (vlib_buffer_length_in_chain (vm, p0)
                    > adj0[0].rewrite_header.max_l3_packet_bytes
                    ? IP4_ERROR_MTU_EXCEEDED : error0);
-
+         if (is_mcast)
+           {
+             error0 = ((adj0[0].rewrite_header.sw_if_index ==
+                        vnet_buffer (p0)->sw_if_index[VLIB_RX]) ?
+                       IP4_ERROR_SAME_INTERFACE : error0);
+           }
          p0->error = error_node->errors[error0];
 
          /* Don't adjust the buffer for ttl issue; icmp-error node wants
@@ -2652,7 +2676,8 @@ ip4_rewrite_inline (vlib_main_t * vm,
 
              if (is_midchain)
                {
-                 adj0->sub_type.midchain.fixup_func (vm, adj0, p0);
+                 adj0->sub_type.midchain.fixup_func
+                   (vm, adj0, p0, adj0->sub_type.midchain.fixup_data);
                }
 
              if (PREDICT_FALSE
@@ -2712,7 +2737,7 @@ ip4_rewrite_inline (vlib_main_t * vm,
 
     <em>Next Indices:</em>
     - <code> adj->rewrite_header.next_index </code>
-      or @c error-drop
+      or @c ip4-drop
 */
 static uword
 ip4_rewrite (vlib_main_t * vm,
@@ -2764,7 +2789,7 @@ VLIB_REGISTER_NODE (ip4_rewrite_node) = {
 
   .n_next_nodes = 2,
   .next_nodes = {
-    [IP4_REWRITE_NEXT_DROP] = "error-drop",
+    [IP4_REWRITE_NEXT_DROP] = "ip4-drop",
     [IP4_REWRITE_NEXT_ICMP_ERROR] = "ip4-icmp-error",
   },
 };