ip: fix ip zero checksum verification

In one's complement, there are two representations of zero: the all
zero and the all one bit values, often referred to as +0 and -0. See
RFC 1624 section 3 for more details.
This used to be taken care of in ip4_header_checksum(), but it is no
longer the case. The check ip->checksum == ip4_header_checksum (ip) is
no longer correct in the -0 case.
Always use ip4_header_checksum_is_valid() instead (which behaves
correctly since 9a79a1ab931c3b5a7ae07d6f0fcfef7c4368a2c4).

Type: fix
Fixes: e5f0050c7a5d411f96af6401797529d58825e2af

Change-Id: Iacc6b60645a834287b085aecb9e3fdb4554cf0cf
Signed-off-by: Benoît Ganne <bganne@cisco.com>
diff --git a/src/vnet/ip/ip4_format.c b/src/vnet/ip/ip4_format.c
index 786a01d..c6639b2 100644
--- a/src/vnet/ip/ip4_format.c
+++ b/src/vnet/ip/ip4_format.c
@@ -150,9 +150,10 @@
 
   /* Check and report invalid checksums. */
   {
-    u16 c = ip4_header_checksum (ip);
-    if (c != ip->checksum)
-      s = format (s, " (should be 0x%04x)", clib_net_to_host_u16 (c));
+    if (!ip4_header_checksum_is_valid (ip))
+      s =
+	format (s, " (should be 0x%04x)",
+		clib_net_to_host_u16 (ip4_header_checksum (ip)));
   }
 
   s = format (s, " dscp %U ecn %U",
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 595a0a1..3bf3053 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2063,7 +2063,7 @@
   ttl += 1;
   ip->ttl = ttl;
 
-  ASSERT (ip->checksum == ip4_header_checksum (ip));
+  ASSERT (ip4_header_checksum_is_valid (ip));
 }
 
 /* Decrement TTL & update checksum.
@@ -2104,7 +2104,7 @@
     }
 
   /* Verify checksum. */
-  ASSERT ((ip->checksum == ip4_header_checksum (ip)) ||
+  ASSERT (ip4_header_checksum_is_valid (ip) ||
 	  (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM));
 }
 
diff --git a/src/vnet/ip/ip4_pg.c b/src/vnet/ip/ip4_pg.c
index d894244..2ccd2b4 100644
--- a/src/vnet/ip/ip4_pg.c
+++ b/src/vnet/ip/ip4_pg.c
@@ -90,8 +90,8 @@
 	  ip0->checksum = ~ip_csum_fold (sum0);
 	  ip1->checksum = ~ip_csum_fold (sum1);
 
-	  ASSERT (ip0->checksum == ip4_header_checksum (ip0));
-	  ASSERT (ip1->checksum == ip4_header_checksum (ip1));
+	  ASSERT (ip4_header_checksum_is_valid (ip0));
+	  ASSERT (ip4_header_checksum_is_valid (ip1));
 	}
     }
 
@@ -123,7 +123,7 @@
 	  ip4_partial_header_checksum_x1 (ip0, sum0);
 	  ip0->checksum = ~ip_csum_fold (sum0);
 
-	  ASSERT (ip0->checksum == ip4_header_checksum (ip0));
+	  ASSERT (ip4_header_checksum_is_valid (ip0));
 	}
     }
 }