public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Stefano Brivio <sbrivio@redhat.com>
To: Laurent Vivier <lvivier@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH v5 1/8] tcp: extract buffer management from tcp_send_flag()
Date: Wed, 12 Jun 2024 00:09:04 +0200	[thread overview]
Message-ID: <20240612000904.59b438c5@elisabeth> (raw)
In-Reply-To: <20240605152129.1641658-2-lvivier@redhat.com>

On Wed,  5 Jun 2024 17:21:22 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> This commit isolates the internal data structure management used for storing
> data (e.g., tcp4_l2_flags_iov[], tcp6_l2_flags_iov[], tcp4_flags_ip[],
> tcp4_flags[], ...) from the tcp_send_flag() function. The extracted
> functionality is relocated to a new function named tcp_fill_flag_header().
> 
> tcp_fill_flag_header() is now a generic function that accepts parameters such
> as struct tcphdr and a data pointer. tcp_send_flag() utilizes this parameter to
> pass memory pointers from tcp4_l2_flags_iov[] and tcp6_l2_flags_iov[].
> 
> This separation sets the stage for utilizing tcp_fill_flag_header() to
> set the memory provided by the guest via vhost-user in future developments.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  tcp.c | 63 ++++++++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 39 insertions(+), 24 deletions(-)
> 
> diff --git a/tcp.c b/tcp.c
> index 06acb41e4d90..68d4afa05a36 100644
> --- a/tcp.c
> +++ b/tcp.c
> @@ -1549,24 +1549,25 @@ static void tcp_update_seqack_from_tap(const struct ctx *c,
>  }
>  
>  /**
> - * tcp_send_flag() - Send segment with flags to tap (no payload)
> + * tcp_fill_flag_header() - Prepare header for flags-only segment (no payload)
>   * @c:		Execution context
>   * @conn:	Connection pointer
>   * @flags:	TCP flags: if not set, send segment only if ACK is due
> + * @th:		TCP header to update
> + * @data:	buffer to store TCP option
> + * @optlen:	size of the TCP option buffer

Now, this becomes an output parameter if SYN is set in flags, but it's
otherwise an input parameter (and it must be zero, otherwise the data
offset field we send will be wrong).

I think having it always as output parameter (that is, setting it to
zero on non-SYN in this function, not in the caller) would be less
fragile and easier to describe in the comment, too.

Or, even simpler, pass it as input parameter, and calculate it in the
caller. The caller sets 'flags' anyway.

>   *
> - * Return: negative error code on connection reset, 0 otherwise
> + * Return: < 0 error code on connection reset,
> + *           0 if there is no flag to send

As you use one tab to indent "1 otherwise" below, you could use one
here as well.

> + *	     1 otherwise
>   */
> -static int tcp_send_flag(struct ctx *c, struct tcp_tap_conn *conn, int flags)
> +static int tcp_fill_flag_header(struct ctx *c, struct tcp_tap_conn *conn,
> +				int flags, struct tcphdr *th, char *data,
> +				size_t *optlen)
>  {
> -	struct tcp_flags_t *payload;
>  	struct tcp_info tinfo = { 0 };
>  	socklen_t sl = sizeof(tinfo);
>  	int s = conn->sock;
> -	size_t optlen = 0;
> -	struct tcphdr *th;
> -	struct iovec *iov;
> -	size_t l4len;
> -	char *data;
>  
>  	if (SEQ_GE(conn->seq_ack_to_tap, conn->seq_from_tap) &&
>  	    !flags && conn->wnd_to_tap)
> @@ -1588,20 +1589,11 @@ static int tcp_send_flag(struct ctx *c, struct tcp_tap_conn *conn, int flags)
>  	if (!tcp_update_seqack_wnd(c, conn, flags, &tinfo) && !flags)
>  		return 0;
>  
> -	if (CONN_V4(conn))
> -		iov = tcp4_l2_flags_iov[tcp4_flags_used++];
> -	else
> -		iov = tcp6_l2_flags_iov[tcp6_flags_used++];
> -
> -	payload = iov[TCP_IOV_PAYLOAD].iov_base;
> -	th = &payload->th;
> -	data = payload->opts;
> -
>  	if (flags & SYN) {
>  		int mss;
>  
>  		/* Options: MSS, NOP and window scale (8 bytes) */
> -		optlen = OPT_MSS_LEN + 1 + OPT_WS_LEN;
> +		*optlen = OPT_MSS_LEN + 1 + OPT_WS_LEN;
>  
>  		*data++ = OPT_MSS;
>  		*data++ = OPT_MSS_LEN;
> @@ -1635,17 +1627,13 @@ static int tcp_send_flag(struct ctx *c, struct tcp_tap_conn *conn, int flags)
>  		flags |= ACK;
>  	}
>  
> -	th->doff = (sizeof(*th) + optlen) / 4;
> +	th->doff = (sizeof(*th) + *optlen) / 4;
>  
>  	th->ack = !!(flags & ACK);
>  	th->rst = !!(flags & RST);
>  	th->syn = !!(flags & SYN);
>  	th->fin = !!(flags & FIN);
>  
> -	l4len = tcp_l2_buf_fill_headers(c, conn, iov, optlen, NULL,
> -					conn->seq_to_tap);
> -	iov[TCP_IOV_PAYLOAD].iov_len = l4len;
> -
>  	if (th->ack) {
>  		if (SEQ_GE(conn->seq_ack_to_tap, conn->seq_from_tap))
>  			conn_flag(c, conn, ~ACK_TO_TAP_DUE);
> @@ -1660,6 +1648,33 @@ static int tcp_send_flag(struct ctx *c, struct tcp_tap_conn *conn, int flags)
>  	if (th->fin || th->syn)
>  		conn->seq_to_tap++;
>  
> +	return 1;
> +}
> +
> +static int tcp_send_flag(struct ctx *c, struct tcp_tap_conn *conn, int flags)
> +{
> +	struct tcp_flags_t *payload;
> +	size_t optlen = 0;
> +	struct iovec *iov;
> +	size_t l4len;
> +	int ret;
> +
> +	if (CONN_V4(conn))
> +		iov = tcp4_l2_flags_iov[tcp4_flags_used++];
> +	else
> +		iov = tcp6_l2_flags_iov[tcp6_flags_used++];
> +
> +	payload = iov[TCP_IOV_PAYLOAD].iov_base;
> +
> +	ret = tcp_fill_flag_header(c, conn, flags, &payload->th,
> +				   payload->opts, &optlen);
> +	if (ret <= 0)
> +		return ret;
> +
> +	l4len = tcp_l2_buf_fill_headers(c, conn, iov, optlen, NULL,
> +					conn->seq_to_tap);
> +	iov[TCP_IOV_PAYLOAD].iov_len = l4len;
> +
>  	if (flags & DUP_ACK) {
>  		struct iovec *dup_iov;
>  		int i;

-- 
Stefano


  parent reply	other threads:[~2024-06-11 22:09 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-05 15:21 [PATCH v5 0/8] Add vhost-user support to passt (part 2) Laurent Vivier
2024-06-05 15:21 ` [PATCH v5 1/8] tcp: extract buffer management from tcp_send_flag() Laurent Vivier
2024-06-11  5:31   ` David Gibson
2024-06-11 11:42     ` Laurent Vivier
2024-06-12  6:31       ` David Gibson
2024-06-11 22:09   ` Stefano Brivio [this message]
2024-06-12  6:32     ` David Gibson
2024-06-05 15:21 ` [PATCH v5 2/8] tcp: move buffers management functions to their own file Laurent Vivier
2024-06-11 22:09   ` Stefano Brivio
2024-06-12  6:14   ` David Gibson
2024-06-12 12:03     ` Stefano Brivio
2024-06-05 15:21 ` [PATCH v5 3/8] tap: refactor packets handling functions Laurent Vivier
2024-06-11 22:09   ` Stefano Brivio
2024-06-12  6:18     ` David Gibson
2024-06-12  6:34       ` Stefano Brivio
2024-06-12  6:37         ` David Gibson
2024-06-12  6:21   ` David Gibson
2024-06-05 15:21 ` [PATCH v5 4/8] udp: refactor UDP header update functions Laurent Vivier
2024-06-11 22:10   ` Stefano Brivio
2024-06-12  6:27   ` David Gibson
2024-06-05 15:21 ` [PATCH v5 5/8] udp: rename udp_sock_handler() to udp_buf_sock_handler() Laurent Vivier
2024-06-12  6:28   ` David Gibson
2024-06-05 15:21 ` [PATCH v5 6/8] vhost-user: compare mode MODE_PASTA and not MODE_PASST Laurent Vivier
2024-06-11 22:10   ` Stefano Brivio
2024-06-05 15:21 ` [PATCH v5 7/8] iov: remove iov_copy() Laurent Vivier
2024-06-05 15:21 ` [PATCH v5 8/8] tap: use in->buf_size rather than sizeof(pkt_buf) Laurent Vivier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240612000904.59b438c5@elisabeth \
    --to=sbrivio@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=passt-dev@passt.top \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).