diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2024-09-18 11:53:05 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2024-09-18 17:14:47 +0200 |
commit | 4aff6f93923327cb875ceacf12ef0ffc2e613174 (patch) | |
tree | 9142414b32751a7d2027a2a2efe1fe0e02009006 /tcp_internal.h | |
parent | 7d8804beb8ecbd07b51dbbeaf14289d37f4f8107 (diff) | |
download | passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.tar passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.tar.gz passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.tar.bz2 passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.tar.lz passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.tar.xz passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.tar.zst passt-4aff6f93923327cb875ceacf12ef0ffc2e613174.zip |
tcp: Clean up tcpi_snd_wnd probing
When available, we want to retrieve our socket peer's advertised window and
forward that to the guest. That information has been available from the
kernel via the TCP_INFO getsockopt() since kernel commit 8f7baad7f035.
Currently our probing for this is a bit odd. The HAS_SND_WND define
determines if our headers include the tcp_snd_wnd field, but that doesn't
necessarily mean the running kernel supports it. Currently we start by
assuming it's _not_ available, but mark it as available if we ever see
a non-zero value in the field. This is a bit hit and miss in two ways:
* Zero is perfectly possible window the peer could report, so we can
get false negatives
* We're reading TCP_INFO into a local variable, which might not be zero
initialised, so if the kernel _doesn't_ write it it could have non-zero
garbage, giving us false positives.
We can use a more direct way of probing for this: getsockopt() reports the
length of the information retreived. So, check whether that's long enough
to include the field. This lets us probe the availability of the field
once and for all during initialisation. That in turn allows ctx to become
a const pointer to tcp_prepare_flags() which cascades through many other
functions.
We also move the flag for the probe result from the ctx structure to a
global, to match peek_offset_cap.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'tcp_internal.h')
-rw-r--r-- | tcp_internal.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/tcp_internal.h b/tcp_internal.h index aa8bb64..bd634be 100644 --- a/tcp_internal.h +++ b/tcp_internal.h @@ -82,7 +82,7 @@ void conn_event_do(const struct ctx *c, struct tcp_tap_conn *conn, conn_event_do(c, conn, event); \ } while (0) -void tcp_rst_do(struct ctx *c, struct tcp_tap_conn *conn); +void tcp_rst_do(const struct ctx *c, struct tcp_tap_conn *conn); #define tcp_rst(c, conn) \ do { \ flow_dbg((conn), "TCP reset at %s:%i", __func__, __LINE__); \ @@ -94,7 +94,7 @@ size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, const uint16_t *check, uint32_t seq); int tcp_update_seqack_wnd(const struct ctx *c, struct tcp_tap_conn *conn, int force_seq, struct tcp_info *tinfo); -int tcp_prepare_flags(struct ctx *c, struct tcp_tap_conn *conn, int flags, +int tcp_prepare_flags(const struct ctx *c, struct tcp_tap_conn *conn, int flags, struct tcphdr *th, char *data, size_t *optlen); #endif /* TCP_INTERNAL_H */ |