aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2020-08-31 18:59:34 +0200
committerDamjan Marion <dmarion@me.com>2020-09-01 12:03:27 +0000
commit6e334e3e77bb156a9317a37500077a218a04f7a3 (patch)
treefa2caf364ba7d99ca7e3895c37bb1047c6be8c0f /src/vnet/ip
parent1d104c5ecdce37301fdfea0e62a533a2e5342ee0 (diff)
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>
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/ip4_format.c7
-rw-r--r--src/vnet/ip/ip4_forward.c4
-rw-r--r--src/vnet/ip/ip4_pg.c6
3 files changed, 9 insertions, 8 deletions
diff --git a/src/vnet/ip/ip4_format.c b/src/vnet/ip/ip4_format.c
index 786a01d396b..c6639b20716 100644
--- a/src/vnet/ip/ip4_format.c
+++ b/src/vnet/ip/ip4_format.c
@@ -150,9 +150,10 @@ format_ip4_header (u8 * s, va_list * args)
/* 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 595a0a1913c..3bf305303d4 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2063,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.
@@ -2104,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));
}
diff --git a/src/vnet/ip/ip4_pg.c b/src/vnet/ip/ip4_pg.c
index d89424496f0..2ccd2b45a6f 100644
--- a/src/vnet/ip/ip4_pg.c
+++ b/src/vnet/ip/ip4_pg.c
@@ -90,8 +90,8 @@ compute_length_and_or_checksum (vlib_main_t * vm,
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 @@ compute_length_and_or_checksum (vlib_main_t * vm,
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));
}
}
}