public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Laurent Vivier <lvivier@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH v2 09/20] icmp: Convert to iov_tail
Date: Mon, 14 Apr 2025 13:14:24 +1000	[thread overview]
Message-ID: <Z_x9kCFEGXZh9l-V@zatzit> (raw)
In-Reply-To: <20250411131031.1398006-10-lvivier@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 4656 bytes --]

On Fri, Apr 11, 2025 at 03:10:19PM +0200, Laurent Vivier wrote:
> Use packet_base() and extract headers using IOV_PEEK_HEADER()
> rather than packet_get().
> 
> Introduce iov_tail_msghdr() to convert iov_tail to msghdr
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  icmp.c | 32 +++++++++++++++++---------------
>  iov.c  | 21 +++++++++++++++++++++
>  iov.h  |  2 ++
>  3 files changed, 40 insertions(+), 15 deletions(-)
> 
> diff --git a/icmp.c b/icmp.c
> index 7e2b3423a8d1..64ad738b6809 100644
> --- a/icmp.c
> +++ b/icmp.c
> @@ -241,24 +241,25 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
>  	struct icmp_ping_flow *pingf;
>  	const struct flowside *tgt;
>  	union sockaddr_inany sa;
> -	size_t dlen, l4len;
> +	struct iov_tail data;
> +	struct msghdr msh;
>  	uint16_t id, seq;
>  	union flow *flow;
>  	uint8_t proto;
> -	socklen_t sl;
> -	void *pkt;
>  
>  	(void)saddr;
>  	ASSERT(pif == PIF_TAP);
>  
> +	if (!packet_base(p, 0, &data))
> +		return -1;
> +
>  	if (af == AF_INET) {
>  		const struct icmphdr *ih;
> +		struct icmphdr ihc;
>  
> -		if (!(pkt = packet_get(p, 0, 0, sizeof(*ih), &dlen)))
> -			return 1;
> -
> -		ih =  (struct icmphdr *)pkt;
> -		l4len = dlen + sizeof(*ih);
> +		ih = IOV_PEEK_HEADER(&data, ihc);
> +		if (!ih)
> +			return -1;

You've replaced a 'return 1' with a 'return -1' which doesn't seem correct.

>  
>  		if (ih->type != ICMP_ECHO)
>  			return 1;
> @@ -268,12 +269,11 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
>  		seq = ntohs(ih->un.echo.sequence);
>  	} else if (af == AF_INET6) {
>  		const struct icmp6hdr *ih;
> +		struct icmp6hdr ihc;
>  
> -		if (!(pkt = packet_get(p, 0, 0, sizeof(*ih), &dlen)))
> -			return 1;
> -
> -		ih = (struct icmp6hdr *)pkt;
> -		l4len = dlen + sizeof(*ih);
> +		ih = IOV_PEEK_HEADER(&data, ihc);
> +		if (!ih)
> +			return -1;

Same here.

>  
>  		if (ih->icmp6_type != ICMPV6_ECHO_REQUEST)
>  			return 1;
> @@ -298,8 +298,10 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
>  	ASSERT(flow_proto[pingf->f.type] == proto);
>  	pingf->ts = now->tv_sec;
>  
> -	pif_sockaddr(c, &sa, &sl, PIF_HOST, &tgt->eaddr, 0);
> -	if (sendto(pingf->sock, pkt, l4len, MSG_NOSIGNAL, &sa.sa, sl) < 0) {
> +	iov_tail_msghdr(&msh, &data, &sa);
> +
> +	pif_sockaddr(c, &sa, &msh.msg_namelen, PIF_HOST, &tgt->eaddr, 0);

> +	if (sendmsg(pingf->sock, &msh, MSG_NOSIGNAL) < 0) {
>  		flow_dbg_perror(pingf, "failed to relay request to socket");
>  	} else {
>  		flow_dbg(pingf,
> diff --git a/iov.c b/iov.c
> index 98d5fecbdc8f..9e3786e6efe8 100644
> --- a/iov.c
> +++ b/iov.c
> @@ -210,6 +210,27 @@ int iov_slice(struct iovec *dst_iov, size_t dst_iov_cnt,
>  	return j;
>  }
>  
> +/**
> + * iov_tail_msghdr - Initialize a msghdr from an IOV tail structure
> + * @msh:	msghdr to initialize
> + * @tail:	iov_tail to use to set msg_iov and msg_iovlen
> + * @msg_name:	Pointer to set to msg_name
> + */
> +void iov_tail_msghdr(struct msghdr *msh, struct iov_tail *tail,
> +		     void *msg_name)
> +{
> +	iov_tail_prune(tail);
> +
> +	ASSERT(tail->off == 0);
> +
> +	msh->msg_name = msg_name;

This doesn't initialise msg_namelen.  I see that you do it outside
from pif_sockaddr(), but that makes it extremely easy to misuse this
function.

Not immediately sure how to make an interface that's both safe and
convenient here.  If it helps, it's probably reasonable to assume here
that you'll always use a union sockaddr_inany for the address.

> +	msh->msg_iov = (struct iovec *)tail->iov;
> +	msh->msg_iovlen = tail->cnt;
> +	msh->msg_control = NULL;
> +	msh->msg_controllen = 0;
> +	msh->msg_flags = 0;
> +}
> +
>  /**
>   * iov_tail_prune() - Remove any unneeded buffers from an IOV tail
>   * @tail:	IO vector tail (modified)
> diff --git a/iov.h b/iov.h
> index b412a96b1090..acba2ea4240b 100644
> --- a/iov.h
> +++ b/iov.h
> @@ -83,6 +83,8 @@ struct iov_tail {
>  #define IOV_TAIL_FROM_BUF(buf_, len_, off_) \
>  	IOV_TAIL((&(const struct iovec){ .iov_base = (buf_), .iov_len = (len_) }), 1, (off_))
>  
> +void iov_tail_msghdr(struct msghdr *msh, struct iov_tail *tail,
> +		     void *msg_name);
>  bool iov_tail_prune(struct iov_tail *tail);
>  size_t iov_tail_size(struct iov_tail *tail);
>  bool iov_tail_drop(struct iov_tail *tail, size_t len);

-- 
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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2025-04-14  3:22 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-11 13:10 [PATCH v2 00/20] Introduce discontiguous frames management Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 01/20] arp: Don't mix incoming and outgoing buffers Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 02/20] iov: Introduce iov_tail_drop() and iov_slice() Laurent Vivier
2025-04-14  2:14   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 03/20] iov: Update IOV_REMOVE_HEADER() and IOV_PEEK_HEADER() Laurent Vivier
2025-04-14  2:19   ` David Gibson
2025-04-14  7:31     ` Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 04/20] tap: Use iov_tail with tap_add_packet() Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 05/20] packet: Use iov_tail with packet_add() Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 06/20] packet: Add packet_base() Laurent Vivier
2025-04-14  2:29   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 07/20] arp: Convert to iov_tail Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 08/20] ndp: " Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 09/20] icmp: " Laurent Vivier
2025-04-14  3:14   ` David Gibson [this message]
2025-04-11 13:10 ` [PATCH v2 10/20] udp: " Laurent Vivier
2025-04-14  3:21   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 11/20] tcp: Convert tcp_tap_handler() to use iov_tail Laurent Vivier
2025-04-14  3:26   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 12/20] tcp: Convert tcp_data_from_tap() " Laurent Vivier
2025-04-14  3:28   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 13/20] dhcpv6: move offset initialization out of dhcpv6_opt() Laurent Vivier
2025-04-14  4:07   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 14/20] dhcpv6: Extract sending of NotOnLink status Laurent Vivier
2025-04-14  4:10   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 15/20] dhcpv6: Convert to iov_tail Laurent Vivier
2025-04-14  4:12   ` David Gibson
2025-04-11 13:10 ` [PATCH v2 16/20] dhcpv6: Use iov_tail in dhcpv6_opt() Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 17/20] dhcp: Convert to iov_tail Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 18/20] ip: Use iov_tail in ipv6_l4hdr() Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 19/20] tap: Convert tap4_handler() to iov_tail Laurent Vivier
2025-04-11 13:10 ` [PATCH v2 20/20] tap: Convert tap6_handler() " 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=Z_x9kCFEGXZh9l-V@zatzit \
    --to=david@gibson.dropbear.id.au \
    --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).