aboutgitcodebugslistschat
path: root/tcp.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-10-15 17:09:37 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-10-15 17:09:37 +0200
commit54e6513d17802200538e30d54845b18abbe2ec0f (patch)
tree415b2e7e0b166c20462148222357c504e73f1e5b /tcp.c
parentbf63832207f0e13e5bda564d2be993f10b0fb458 (diff)
downloadpasst-54e6513d17802200538e30d54845b18abbe2ec0f.tar
passt-54e6513d17802200538e30d54845b18abbe2ec0f.tar.gz
passt-54e6513d17802200538e30d54845b18abbe2ec0f.tar.bz2
passt-54e6513d17802200538e30d54845b18abbe2ec0f.tar.lz
passt-54e6513d17802200538e30d54845b18abbe2ec0f.tar.xz
passt-54e6513d17802200538e30d54845b18abbe2ec0f.tar.zst
passt-54e6513d17802200538e30d54845b18abbe2ec0f.zip
tcp: Clamp MSS depending on IP version, properly derive buffer sizes
It makes no sense to include an IPv6 header in the calculation for clamping MSS on IPv4. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/tcp.c b/tcp.c
index ed26c49..c682072 100644
--- a/tcp.c
+++ b/tcp.c
@@ -352,6 +352,11 @@
#define MAX_WS 10
#define MAX_WINDOW (1 << (16 + (MAX_WS)))
#define MSS_DEFAULT 536
+#define MSS4 (USHRT_MAX - sizeof(uint32_t) - sizeof(struct ethhdr) - \
+ sizeof(struct iphdr) - sizeof(struct tcphdr))
+#define MSS6 (USHRT_MAX - sizeof(uint32_t) - sizeof(struct ethhdr) - \
+ sizeof(struct ipv6hdr) - sizeof(struct tcphdr))
+
#define WINDOW_DEFAULT 14600 /* RFC 6928 */
#define SYN_TIMEOUT 240000 /* ms */
@@ -590,7 +595,8 @@ static struct tcp4_l2_buf_t {
struct ethhdr eh; /* 30 14 */
struct iphdr iph; /* 44 28 */
struct tcphdr th; /* 64 48 */
- uint8_t data[USHRT_MAX - sizeof(struct tcphdr)];
+ uint8_t data[MSS4]; /* 84 68 */
+ /* 65541 65525 */
#ifdef __AVX2__
} __attribute__ ((packed, aligned(32)))
#else
@@ -622,8 +628,8 @@ struct tcp6_l2_buf_t {
struct ethhdr eh; /* 18 6 */
struct ipv6hdr ip6h; /* 32 20 */
struct tcphdr th; /* 72 60 */
- uint8_t data[USHRT_MAX -
- (sizeof(struct ipv6hdr) + sizeof(struct tcphdr))];
+ uint8_t data[MSS6]; /* 92 80 */
+ /* 65639 65627 */
#ifdef __AVX2__
} __attribute__ ((packed, aligned(32)))
#else
@@ -1868,14 +1874,12 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr,
if (conn->mss_guest < 0)
conn->mss_guest = MSS_DEFAULT;
+ /* Don't upset qemu */
if (c->mode == MODE_PASST) {
- /* Don't upset qemu */
- conn->mss_guest = MIN(USHRT_MAX -
- sizeof(uint32_t) -
- sizeof(struct ethhdr) -
- sizeof(struct ipv6hdr) -
- sizeof(struct tcphdr),
- conn->mss_guest);
+ if (af == AF_INET)
+ conn->mss_guest = MIN(MSS4, conn->mss_guest);
+ else
+ conn->mss_guest = MIN(MSS6, conn->mss_guest);
}
sl = sizeof(conn->mss_guest);
@@ -2563,14 +2567,12 @@ int tcp_tap_handler(struct ctx *c, int af, void *addr,
if (conn->mss_guest < 0)
conn->mss_guest = MSS_DEFAULT;
+ /* Don't upset qemu */
if (c->mode == MODE_PASST) {
- /* Don't upset qemu */
- conn->mss_guest = MIN(USHRT_MAX -
- sizeof(uint32_t) -
- sizeof(struct ethhdr) -
- sizeof(struct ipv6hdr) -
- sizeof(struct tcphdr),
- conn->mss_guest);
+ if (af == AF_INET)
+ conn->mss_guest = MIN(MSS4, conn->mss_guest);
+ else
+ conn->mss_guest = MIN(MSS6, conn->mss_guest);
}
/* info.tcpi_bytes_acked already includes one byte for SYN, but