checksum: introduce functions to compute the header part checksum for TCP/UDP

The TCP and UDP checksums are computed using the data in the TCP/UDP
payload but also some informations in the IP header (protocol,
length, source and destination addresses).

We add two functions, proto_ipv4_header_psum() and
proto_ipv6_header_psum(), to compute the checksum of the IP
header part.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Message-ID: <20240303135114.1023026-8-lvivier@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Laurent Vivier
2024-03-06 16:58:36 +11:00
committed by Stefano Brivio
parent feb4900c25
commit 7df624e79a
4 changed files with 90 additions and 50 deletions

18
udp.c
View File

@@ -625,6 +625,7 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport,
{
struct udp6_l2_buf_t *b = &udp6_l2_buf[n];
const struct in6_addr *src, *dst;
uint16_t payload_len;
in_port_t src_port;
size_t ip_len;
@@ -634,7 +635,8 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport,
ip_len = udp6_l2_mh_sock[n].msg_len + sizeof(b->ip6h) + sizeof(b->uh);
b->ip6h.payload_len = htons(udp6_l2_mh_sock[n].msg_len + sizeof(b->uh));
payload_len = udp6_l2_mh_sock[n].msg_len + sizeof(b->uh);
b->ip6h.payload_len = htons(payload_len);
if (IN6_IS_ADDR_LINKLOCAL(src)) {
dst = &c->ip6.addr_ll_seen;
@@ -670,17 +672,17 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport,
}
b->ip6h.daddr = *dst;
b->ip6h.saddr = *src;
b->ip6h.version = 6;
b->ip6h.nexthdr = IPPROTO_UDP;
b->ip6h.hop_limit = 255;
b->uh.source = b->s_in6.sin6_port;
b->uh.dest = htons(dstport);
b->uh.len = b->ip6h.payload_len;
b->ip6h.hop_limit = IPPROTO_UDP;
b->ip6h.version = b->ip6h.nexthdr = b->uh.check = 0;
b->uh.check = csum(&b->ip6h, ip_len, 0);
b->ip6h.version = 6;
b->ip6h.nexthdr = IPPROTO_UDP;
b->ip6h.hop_limit = 255;
b->uh.check = 0;
b->uh.check = csum(&b->uh, payload_len,
proto_ipv6_header_psum(payload_len, IPPROTO_UDP,
src, dst));
return tap_iov_len(c, &b->taph, ip_len);
}