aboutgitcodebugslistschat
path: root/udp.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-05-01 18:31:07 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-05-02 16:13:44 +0200
commit2d16946bac152e251156258ac314a74f1984d421 (patch)
tree851b1d998216cfa91a984b878b3fc8ee63717494 /udp.c
parent6c4d26a3645b8cf58a62972f9e1b4e4af89971e0 (diff)
downloadpasst-2d16946bac152e251156258ac314a74f1984d421.tar
passt-2d16946bac152e251156258ac314a74f1984d421.tar.gz
passt-2d16946bac152e251156258ac314a74f1984d421.tar.bz2
passt-2d16946bac152e251156258ac314a74f1984d421.tar.lz
passt-2d16946bac152e251156258ac314a74f1984d421.tar.xz
passt-2d16946bac152e251156258ac314a74f1984d421.tar.zst
passt-2d16946bac152e251156258ac314a74f1984d421.zip
udp: Explicitly set checksum in guest-bound UDP headers
For IPv4, UDP checksums are optional and can just be set to 0. udp_update_hdr4() ignores the checksum field entirely. Since these are set to 0 during startup, this works as intended for now. However, we'd like to share payload and UDP header buffers betweem IPv4 and IPv6, which does calculate UDP checksums. Therefore, for robustness, we should explicitly set the checksum field to 0 for guest-bound UDP packets. In the tap_udp4_send() slow path, however, we do allow IPv4 UDP checksums to be calculated as a compile time option. For consistency, use the same thing in the udp_update_hdr4() path, which will typically initialize to 0, but calculate a real checksum if configured to do so. 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.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/udp.c b/udp.c
index bb7d161..cc938bb 100644
--- a/udp.c
+++ b/udp.c
@@ -592,6 +592,7 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *b,
in_port_t dstport, size_t dlen,
const struct timespec *now)
{
+ const struct in_addr dst = c->ip4.addr_seen;
size_t l4len = dlen + sizeof(b->uh);
size_t l3len = l4len + sizeof(b->iph);
in_port_t srcport = ntohs(b->s_in.sin_port);
@@ -617,14 +618,14 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *b,
}
b->iph.tot_len = htons(l3len);
- b->iph.daddr = c->ip4.addr_seen.s_addr;
+ b->iph.daddr = dst.s_addr;
b->iph.saddr = src.s_addr;
- b->iph.check = csum_ip4_header(l3len, IPPROTO_UDP,
- src, c->ip4.addr_seen);
+ b->iph.check = csum_ip4_header(l3len, IPPROTO_UDP, src, dst);
b->uh.source = b->s_in.sin_port;
b->uh.dest = htons(dstport);
b->uh.len = htons(l4len);
+ csum_udp4(&b->uh, src, dst, b->data, dlen);
tap_hdr_update(&b->taph, l3len + sizeof(b->eh));
return l4len;