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>
udp->checksum = 0xffff;
}
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
/* Find or allocate a frame */
f = fm->context[which].frames_per_worker[my_cpu_number];
if (udp->checksum == 0)
udp->checksum = 0xffff;
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
to_next[0] = bi0;
f->n_vectors++;
if (udp->checksum == 0)
udp->checksum = 0xffff;
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
to_next[0] = bi0;
f->n_vectors++;
*error = ttl <= 0 ? IP4_ERROR_TIME_EXPIRED : *error;
/* Verify checksum. */
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
}
static u32
udp->checksum = 0xffff;
}
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
}
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));
p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
p1->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
ip0->checksum = ip_csum_fold (sum0);
- ASSERT (ip0->checksum == ip4_header_checksum (ip0));
+ ASSERT (ip4_header_checksum_is_valid (ip0));
p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
}
/* 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",
ttl += 1;
ip->ttl = ttl;
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
}
/* Decrement TTL & update checksum.
}
/* Verify checksum. */
- ASSERT ((ip->checksum == ip4_header_checksum (ip)) ||
+ ASSERT (ip4_header_checksum_is_valid (ip) ||
(b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM));
}
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));
}
}
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));
}
}
}
udp->checksum = 0xffff;
}
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
to_next[0] = bi0;
f->n_vectors++;
udp->checksum = 0xffff;
}
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
to_next[0] = bi0;
f->n_vectors++;
udp->checksum = 0xffff;
}
- ASSERT (ip->checksum == ip4_header_checksum (ip));
+ ASSERT (ip4_header_checksum_is_valid (ip));
vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
}