aboutgitcodebugslistschat
path: root/udp.c
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2024-03-06 16:58:36 +1100
committerStefano Brivio <sbrivio@redhat.com>2024-03-06 08:03:47 +0100
commit7df624e79a450ba6b737b972040d9007ecc61672 (patch)
treeb5b04fd7ad258104870e5dcf2d123578458fa247 /udp.c
parentfeb4900c25deabaf9b54760e40aea5e65499e987 (diff)
downloadpasst-7df624e79a450ba6b737b972040d9007ecc61672.tar
passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.gz
passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.bz2
passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.lz
passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.xz
passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.zst
passt-7df624e79a450ba6b737b972040d9007ecc61672.zip
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>
Diffstat (limited to 'udp.c')
-rw-r--r--udp.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/udp.c b/udp.c
index fb8373b..2fd6792 100644
--- a/udp.c
+++ b/udp.c
@@ -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);
}