On Mon, Sep 16, 2024 at 02:16:01PM +0200, Laurent Vivier wrote: > We can need not to set TCP checksum. Add a parameter to > tcp_fill_headers4() and tcp_fill_headers6() to disable it. > > Signed-off-by: Laurent Vivier Reviewed-by: David Gibson > --- > tcp.c | 24 +++++++++++++++++------- > tcp_buf.c | 8 +++++--- > tcp_internal.h | 3 ++- > 3 files changed, 24 insertions(+), 11 deletions(-) > > diff --git a/tcp.c b/tcp.c > index f9fe1b9a1330..a44d7b977214 100644 > --- a/tcp.c > +++ b/tcp.c > @@ -903,6 +903,7 @@ static void tcp_fill_header(struct tcphdr *th, > * @dlen: TCP payload length > * @check: Checksum, if already known > * @seq: Sequence number for this segment > + * @no_tcp_csum: Do not set TCP checksum > * > * Return: The IPv4 payload length, host order > */ > @@ -910,7 +911,7 @@ static size_t tcp_fill_headers4(const struct tcp_tap_conn *conn, > struct tap_hdr *taph, > struct iphdr *iph, struct tcphdr *th, > size_t dlen, const uint16_t *check, > - uint32_t seq) > + uint32_t seq, bool no_tcp_csum) > { > const struct flowside *tapside = TAPFLOW(conn); > const struct in_addr *src4 = inany_v4(&tapside->oaddr); > @@ -929,7 +930,10 @@ static size_t tcp_fill_headers4(const struct tcp_tap_conn *conn, > > tcp_fill_header(th, conn, seq); > > - tcp_update_check_tcp4(iph, th); > + if (no_tcp_csum) > + th->check = 0; > + else > + tcp_update_check_tcp4(iph, th); > > tap_hdr_update(taph, l3len + sizeof(struct ethhdr)); > > @@ -945,13 +949,14 @@ static size_t tcp_fill_headers4(const struct tcp_tap_conn *conn, > * @dlen: TCP payload length > * @check: Checksum, if already known > * @seq: Sequence number for this segment > + * @no_tcp_csum: Do not set TCP checksum > * > * Return: The IPv6 payload length, host order > */ > static size_t tcp_fill_headers6(const struct tcp_tap_conn *conn, > struct tap_hdr *taph, > struct ipv6hdr *ip6h, struct tcphdr *th, > - size_t dlen, uint32_t seq) > + size_t dlen, uint32_t seq, bool no_tcp_csum) > { > const struct flowside *tapside = TAPFLOW(conn); > size_t l4len = dlen + sizeof(*th); > @@ -970,7 +975,10 @@ static size_t tcp_fill_headers6(const struct tcp_tap_conn *conn, > > tcp_fill_header(th, conn, seq); > > - tcp_update_check_tcp6(ip6h, th); > + if (no_tcp_csum) > + th->check = 0; > + else > + tcp_update_check_tcp6(ip6h, th); > > tap_hdr_update(taph, l4len + sizeof(*ip6h) + sizeof(struct ethhdr)); > > @@ -984,12 +992,14 @@ static size_t tcp_fill_headers6(const struct tcp_tap_conn *conn, > * @dlen: TCP payload length > * @check: Checksum, if already known > * @seq: Sequence number for this segment > + * @no_tcp_csum: Do not set TCP checksum > * > * Return: IP payload length, host order > */ > size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, > struct iovec *iov, size_t dlen, > - const uint16_t *check, uint32_t seq) > + const uint16_t *check, uint32_t seq, > + bool no_tcp_csum) > { > const struct flowside *tapside = TAPFLOW(conn); > const struct in_addr *a4 = inany_v4(&tapside->oaddr); > @@ -998,13 +1008,13 @@ size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, > return tcp_fill_headers4(conn, iov[TCP_IOV_TAP].iov_base, > iov[TCP_IOV_IP].iov_base, > iov[TCP_IOV_PAYLOAD].iov_base, dlen, > - check, seq); > + check, seq, no_tcp_csum); > } > > return tcp_fill_headers6(conn, iov[TCP_IOV_TAP].iov_base, > iov[TCP_IOV_IP].iov_base, > iov[TCP_IOV_PAYLOAD].iov_base, dlen, > - seq); > + seq, no_tcp_csum); > } > > /** > diff --git a/tcp_buf.c b/tcp_buf.c > index 1a398461a34b..10a663bdfc26 100644 > --- a/tcp_buf.c > +++ b/tcp_buf.c > @@ -320,7 +320,7 @@ int tcp_buf_send_flag(struct ctx *c, struct tcp_tap_conn *conn, int flags) > return ret; > } > > - l4len = tcp_l2_buf_fill_headers(conn, iov, optlen, NULL, seq); > + l4len = tcp_l2_buf_fill_headers(conn, iov, optlen, NULL, seq, false); > iov[TCP_IOV_PAYLOAD].iov_len = l4len; > > if (flags & DUP_ACK) { > @@ -381,7 +381,8 @@ static void tcp_data_to_tap(struct ctx *c, struct tcp_tap_conn *conn, > tcp4_frame_conns[tcp4_payload_used] = conn; > > iov = tcp4_l2_iov[tcp4_payload_used++]; > - l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, check, seq); > + l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, check, seq, > + false); > iov[TCP_IOV_PAYLOAD].iov_len = l4len; > if (tcp4_payload_used > TCP_FRAMES_MEM - 1) > tcp_payload_flush(c); > @@ -389,7 +390,8 @@ static void tcp_data_to_tap(struct ctx *c, struct tcp_tap_conn *conn, > tcp6_frame_conns[tcp6_payload_used] = conn; > > iov = tcp6_l2_iov[tcp6_payload_used++]; > - l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, NULL, seq); > + l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, NULL, seq, > + false); > iov[TCP_IOV_PAYLOAD].iov_len = l4len; > if (tcp6_payload_used > TCP_FRAMES_MEM - 1) > tcp_payload_flush(c); > diff --git a/tcp_internal.h b/tcp_internal.h > index aa8bb64f1f33..e7fe735bfcb4 100644 > --- a/tcp_internal.h > +++ b/tcp_internal.h > @@ -91,7 +91,8 @@ void tcp_rst_do(struct ctx *c, struct tcp_tap_conn *conn); > > size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, > struct iovec *iov, size_t dlen, > - const uint16_t *check, uint32_t seq); > + const uint16_t *check, uint32_t seq, > + bool no_tcp_csum); > 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, -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson