From 812cdb802c6e2b217efe1756554755b784c1d9e3 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 10 Feb 2026 17:08:21 +0100 Subject: tcp: Move tap header update out of tcp_fill_headers() tcp_fill_headers() currently calls tap_hdr_update() to set the frame length in the tap-specific header. This is backend-specific: the tap backend needs this for its frame length header, but the vhost-user backend passes NULL for the tap header and doesn't use it at all. Remove the tap_hdr parameter from tcp_fill_headers() and instead return the computed L2 frame length. The tap backend caller, tcp_l2_buf_fill_headers(), now calls tap_hdr_update() itself with the returned length. The vhost-user callers, tcp_vu_send_flag() and tcp_vu_prepare(), no longer need to pass a NULL tap header. Signed-off-by: Laurent Vivier Signed-off-by: Stefano Brivio --- tap.h | 3 +-- tcp.c | 16 +++++++++------- tcp_buf.c | 6 ++++-- tcp_internal.h | 11 ++++++----- tcp_vu.c | 4 ++-- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/tap.h b/tap.h index ee22a9d..cc780d1 100644 --- a/tap.h +++ b/tap.h @@ -65,8 +65,7 @@ static inline struct iovec tap_hdr_iov(const struct ctx *c, */ static inline void tap_hdr_update(struct tap_hdr *thdr, size_t l2len) { - if (thdr) - thdr->vnet_len = htonl(l2len); + thdr->vnet_len = htonl(l2len); } unsigned long tap_l2_max_len(const struct ctx *c); diff --git a/tcp.c b/tcp.c index 0a64892..048da2a 100644 --- a/tcp.c +++ b/tcp.c @@ -924,7 +924,6 @@ static void tcp_fill_header(struct tcphdr *th, * tcp_fill_headers() - Fill 802.3, IP, TCP headers * @c: Execution context * @conn: Connection pointer - * @taph: tap backend specific header * @eh: Pointer to Ethernet header * @ip4h: Pointer to IPv4 header, or NULL * @ip6h: Pointer to IPv6 header, or NULL @@ -933,12 +932,15 @@ static void tcp_fill_header(struct tcphdr *th, * @ip4_check: IPv4 checksum, if already known * @seq: Sequence number for this segment * @no_tcp_csum: Do not set TCP checksum + * + * Return: frame length (including L2 headers) */ -void tcp_fill_headers(const struct ctx *c, struct tcp_tap_conn *conn, - struct tap_hdr *taph, struct ethhdr *eh, - struct iphdr *ip4h, struct ipv6hdr *ip6h, - struct tcphdr *th, struct iov_tail *payload, - const uint16_t *ip4_check, uint32_t seq, bool no_tcp_csum) +size_t tcp_fill_headers(const struct ctx *c, struct tcp_tap_conn *conn, + struct ethhdr *eh, + struct iphdr *ip4h, struct ipv6hdr *ip6h, + struct tcphdr *th, struct iov_tail *payload, + const uint16_t *ip4_check, uint32_t seq, + bool no_tcp_csum) { const struct flowside *tapside = TAPFLOW(conn); size_t l4len = iov_tail_size(payload) + sizeof(*th); @@ -1004,7 +1006,7 @@ void tcp_fill_headers(const struct ctx *c, struct tcp_tap_conn *conn, else tcp_update_csum(psum, th, payload); - tap_hdr_update(taph, MAX(l3len + sizeof(struct ethhdr), ETH_ZLEN)); + return MAX(l3len + sizeof(struct ethhdr), ETH_ZLEN); } /** diff --git a/tcp_buf.c b/tcp_buf.c index d292541..675ec13 100644 --- a/tcp_buf.c +++ b/tcp_buf.c @@ -183,14 +183,16 @@ static void tcp_l2_buf_fill_headers(const struct ctx *c, struct ethhdr *eh = iov[TCP_IOV_ETH].iov_base; struct ipv6hdr *ip6h = NULL; struct iphdr *ip4h = NULL; + size_t l2len; if (a4) ip4h = iov[TCP_IOV_IP].iov_base; else ip6h = iov[TCP_IOV_IP].iov_base; - tcp_fill_headers(c, conn, taph, eh, ip4h, ip6h, th, &tail, - check, seq, no_tcp_csum); + l2len = tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &tail, check, seq, + no_tcp_csum); + tap_hdr_update(taph, l2len); } /** diff --git a/tcp_internal.h b/tcp_internal.h index 5f8fb35..518913b 100644 --- a/tcp_internal.h +++ b/tcp_internal.h @@ -176,11 +176,12 @@ void tcp_rst_do(const struct ctx *c, struct tcp_tap_conn *conn); struct tcp_info_linux; -void tcp_fill_headers(const struct ctx *c, struct tcp_tap_conn *conn, - struct tap_hdr *taph, struct ethhdr *eh, - struct iphdr *ip4h, struct ipv6hdr *ip6h, - struct tcphdr *th, struct iov_tail *payload, - const uint16_t *ip4_check, uint32_t seq, bool no_tcp_csum); +size_t tcp_fill_headers(const struct ctx *c, struct tcp_tap_conn *conn, + struct ethhdr *eh, + struct iphdr *ip4h, struct ipv6hdr *ip6h, + struct tcphdr *th, struct iov_tail *payload, + const uint16_t *ip4_check, uint32_t seq, + bool no_tcp_csum); int tcp_update_seqack_wnd(const struct ctx *c, struct tcp_tap_conn *conn, bool force_seq, struct tcp_info_linux *tinfo); diff --git a/tcp_vu.c b/tcp_vu.c index b9e9b55..f654f31 100644 --- a/tcp_vu.c +++ b/tcp_vu.c @@ -135,7 +135,7 @@ int tcp_vu_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags) flags_elem[0].in_sg[0].iov_len = hdrlen + optlen; payload = IOV_TAIL(flags_elem[0].in_sg, 1, hdrlen); - tcp_fill_headers(c, conn, NULL, eh, ip4h, ip6h, th, &payload, + tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload, NULL, seq, !*c->pcap); vu_pad(&flags_elem[0].in_sg[0], hdrlen + optlen); @@ -335,7 +335,7 @@ static void tcp_vu_prepare(const struct ctx *c, struct tcp_tap_conn *conn, th->ack = 1; th->psh = push; - tcp_fill_headers(c, conn, NULL, eh, ip4h, ip6h, th, &payload, + tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload, *check, conn->seq_to_tap, no_tcp_csum); if (ip4h) *check = &ip4h->check; -- cgit v1.2.3