Per RFC768:
If the computed checksum is zero, it is transmitted as all ones.
An all zero transmitted checksum value means that the transmitter
generated no checksum.
RFC793 for TCP has no such special treatment for the checksum of zero.
Fixes:
6006818cfb26 ("net: new checksum functions")
Cc: stable@dpdk.org
Signed-off-by: Hongzhi Guo <guohongzhi1@huawei.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
* @param l4_hdr
* The pointer to the beginning of the L4 header.
* @return
* @param l4_hdr
* The pointer to the beginning of the L4 header.
* @return
- * The complemented checksum to set in the IP packet
- * or 0 on error
+ * The complemented checksum to set in the IP packet.
*/
static inline uint16_t
rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
*/
static inline uint16_t
rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
+ /*
+ * Per RFC 768:If the computed checksum is zero for UDP,
+ * it is transmitted as all ones
+ * (the equivalent in one's complement arithmetic).
+ */
+ if (cksum == 0 && ipv4_hdr->next_proto_id == IPPROTO_UDP)
cksum = 0xffff;
return (uint16_t)cksum;
cksum = 0xffff;
return (uint16_t)cksum;
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
+ /*
+ * Per RFC 768: If the computed checksum is zero for UDP,
+ * it is transmitted as all ones
+ * (the equivalent in one's complement arithmetic).
+ */
+ if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
cksum = 0xffff;
return (uint16_t)cksum;
cksum = 0xffff;
return (uint16_t)cksum;