ip: fix ip zero checksum verification
[vpp.git] / src / vnet / ip / ip4_forward.c
index acff66d..3bf3053 100644 (file)
@@ -54,6 +54,7 @@
 #include <vnet/dpo/load_balance_map.h>
 #include <vnet/dpo/classify_dpo.h>
 #include <vnet/mfib/mfib_table.h>      /* for mFIB table and entry creation */
+#include <vnet/adj/adj_dp.h>
 
 #include <vnet/ip/ip4_forward.h>
 #include <vnet/interface_output.h>
@@ -639,6 +640,8 @@ void
 ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
 {
   ip4_main_t *im = &ip4_main;
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
 
   vec_validate_init_empty (im->ip_enabled_by_sw_if_index, sw_if_index, 0);
 
@@ -663,6 +666,11 @@ ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
   vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
                               sw_if_index, !is_enable, 0, 0);
 
+  if (is_enable)
+    hi->l3_if_count++;
+  else if (hi->l3_if_count)
+    hi->l3_if_count--;
+
   {
     ip4_enable_disable_interface_callback_t *cb;
     vec_foreach (cb, im->enable_disable_interface_callbacks)
@@ -778,7 +786,10 @@ ip4_add_del_interface_address_internal (vlib_main_t * vm,
          goto done;
        }
 
-      ip_interface_address_del (lm, if_address_index, addr_fib);
+      error = ip_interface_address_del (lm, vnm, if_address_index, addr_fib,
+                                       address_length, sw_if_index);
+      if (error)
+       goto done;
     }
   else
     {
@@ -2052,7 +2063,7 @@ ip4_ttl_inc (vlib_buffer_t * b, ip4_header_t * ip)
   ttl += 1;
   ip->ttl = ttl;
 
-  ASSERT (ip->checksum == ip4_header_checksum (ip));
+  ASSERT (ip4_header_checksum_is_valid (ip));
 }
 
 /* Decrement TTL & update checksum.
@@ -2093,7 +2104,7 @@ ip4_ttl_and_checksum_check (vlib_buffer_t * b, ip4_header_t * ip, u16 * next,
     }
 
   /* Verify checksum. */
-  ASSERT ((ip->checksum == ip4_header_checksum (ip)) ||
+  ASSERT (ip4_header_checksum_is_valid (ip) ||
          (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM));
 }
 
@@ -2222,13 +2233,15 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
 
          if (PREDICT_FALSE
              (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
-           vnet_feature_arc_start (lm->output_feature_arc_index,
-                                   tx_sw_if_index0, &next_index, b[0]);
+           vnet_feature_arc_start_w_cfg_index (lm->output_feature_arc_index,
+                                               tx_sw_if_index0,
+                                               &next_index, b[0],
+                                               adj0->ia_cfg_index);
+
          next[0] = next_index;
          if (is_midchain)
            vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
-                                       0 /* is_ip6 */ ,
-                                       0 /* with gso */ );
+                                       0 /* is_ip6 */ );
        }
       else
        {
@@ -2246,13 +2259,14 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
 
          if (PREDICT_FALSE
              (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
-           vnet_feature_arc_start (lm->output_feature_arc_index,
-                                   tx_sw_if_index1, &next_index, b[1]);
+           vnet_feature_arc_start_w_cfg_index (lm->output_feature_arc_index,
+                                               tx_sw_if_index1,
+                                               &next_index, b[1],
+                                               adj1->ia_cfg_index);
          next[1] = next_index;
          if (is_midchain)
-           vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
-                                       0 /* is_ip6 */ ,
-                                       0 /* with gso */ );
+           vnet_calc_checksums_inline (vm, b[1], 1 /* is_ip4 */ ,
+                                       0 /* is_ip6 */ );
        }
       else
        {
@@ -2261,9 +2275,14 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
            ip4_ttl_inc (b[1], ip1);
        }
 
-      /* Guess we are only writing on simple Ethernet header. */
-      vnet_rewrite_two_headers (adj0[0], adj1[0],
-                               ip0, ip1, sizeof (ethernet_header_t));
+      if (is_midchain)
+       /* Guess we are only writing on ipv4 header. */
+       vnet_rewrite_two_headers (adj0[0], adj1[0],
+                                 ip0, ip1, sizeof (ip4_header_t));
+      else
+       /* Guess we are only writing on simple Ethernet header. */
+       vnet_rewrite_two_headers (adj0[0], adj1[0],
+                                 ip0, ip1, sizeof (ethernet_header_t));
 
       if (do_counters)
        {
@@ -2284,12 +2303,10 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
 
       if (is_midchain)
        {
-         if (error0 == IP4_ERROR_NONE && adj0->sub_type.midchain.fixup_func)
-           adj0->sub_type.midchain.fixup_func
-             (vm, adj0, b[0], adj0->sub_type.midchain.fixup_data);
-         if (error1 == IP4_ERROR_NONE && adj1->sub_type.midchain.fixup_func)
-           adj1->sub_type.midchain.fixup_func
-             (vm, adj1, b[1], adj1->sub_type.midchain.fixup_data);
+         if (error0 == IP4_ERROR_NONE)
+           adj_midchain_fixup (vm, adj0, b[0]);
+         if (error1 == IP4_ERROR_NONE)
+           adj_midchain_fixup (vm, adj1, b[1]);
        }
 
       if (is_mcast)
@@ -2391,17 +2408,24 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
 
          if (PREDICT_FALSE
              (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
-           vnet_feature_arc_start (lm->output_feature_arc_index,
-                                   tx_sw_if_index0, &next_index, b[0]);
+           vnet_feature_arc_start_w_cfg_index (lm->output_feature_arc_index,
+                                               tx_sw_if_index0,
+                                               &next_index, b[0],
+                                               adj0->ia_cfg_index);
          next[0] = next_index;
 
          if (is_midchain)
-           vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
-                                       0 /* is_ip6 */ ,
-                                       0 /* with gso */ );
+           {
+             vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
+                                         0 /* is_ip6 */ );
 
-         /* Guess we are only writing on simple Ethernet header. */
-         vnet_rewrite_one_header (adj0[0], ip0, sizeof (ethernet_header_t));
+             /* Guess we are only writing on ipv4 header. */
+             vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
+           }
+         else
+           /* Guess we are only writing on simple Ethernet header. */
+           vnet_rewrite_one_header (adj0[0], ip0,
+                                    sizeof (ethernet_header_t));
 
          /*
           * Bump the per-adjacency counters
@@ -2413,9 +2437,8 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
               adj_index0, 1, vlib_buffer_length_in_chain (vm,
                                                           b[0]) + rw_len0);
 
-         if (is_midchain && adj0->sub_type.midchain.fixup_func)
-           adj0->sub_type.midchain.fixup_func
-             (vm, adj0, b[0], adj0->sub_type.midchain.fixup_data);
+         if (is_midchain)
+           adj_midchain_fixup (vm, adj0, b[0]);
 
          if (is_mcast)
            /* copy bytes from the IP address into the MAC rewrite */
@@ -2491,18 +2514,25 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
 
          if (PREDICT_FALSE
              (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
-           vnet_feature_arc_start (lm->output_feature_arc_index,
-                                   tx_sw_if_index0, &next_index, b[0]);
+           vnet_feature_arc_start_w_cfg_index (lm->output_feature_arc_index,
+                                               tx_sw_if_index0,
+                                               &next_index, b[0],
+                                               adj0->ia_cfg_index);
          next[0] = next_index;
 
          if (is_midchain)
-           /* this acts on the packet that is about to be encapped */
-           vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
-                                       0 /* is_ip6 */ ,
-                                       0 /* with gso */ );
+           {
+             /* this acts on the packet that is about to be encapped */
+             vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
+                                         0 /* is_ip6 */ );
 
-         /* Guess we are only writing on simple Ethernet header. */
-         vnet_rewrite_one_header (adj0[0], ip0, sizeof (ethernet_header_t));
+             /* Guess we are only writing on ipv4 header. */
+             vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
+           }
+         else
+           /* Guess we are only writing on simple Ethernet header. */
+           vnet_rewrite_one_header (adj0[0], ip0,
+                                    sizeof (ethernet_header_t));
 
          if (do_counters)
            vlib_increment_combined_counter
@@ -3067,10 +3097,13 @@ ip4_config (vlib_main_t * vm, unformat_input_t * input)
     {
       if (unformat (input, "heap-size %U", unformat_memory_size, &heapsize))
        ;
+      else if (unformat (input, "mtrie-hugetlb %=", &im->mtrie_hugetlb, 1))
+       ;
       else
        return clib_error_return (0,
                                  "invalid heap-size parameter `%U'",
                                  format_unformat_error, input);
+
     }
 
   im->mtrie_heap_size = heapsize;