From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202504 header.b=Y1TySwB6; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id A4D615A0274 for ; Wed, 16 Apr 2025 02:38:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202504; t=1744763923; bh=G773OFlkql6ff45NRJmqLR2SDg4YjwJbh5dDa0OlzPc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=Y1TySwB6IiTyXoqlHQHtGiscIF5QuhwWhkAC4s9i0QTFF9rhQEu1ZU3p+EXWJfRNl 8ZnpxsmnOYN01X6AIYHgmB5WDQqNVlM2CcvL9fpEvculUwEi+Dfvd5a/dbVdgTGrmJ eMOLtufQ7H4jR/4ButoshL/ozGUvT5zGZlSh3mBOOw+fQ352c1uoBPwkwL0WOpzMRO 0A/tYHPgRjcNHruJGcjh+b4vEd3RefoheJRbmgDO84/SZ+z3UQdjPftlCHiTI6YeO4 hEuhJoYWgCKQdcbo/Q1Fl4Ypoq9DGJ38J6iRpHfoSobBgeEVL6Y0Nx26zNSd/MtW1x yuA1JIIVGx+3Q== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4ZchwM1htxz4xD3; Wed, 16 Apr 2025 10:38:43 +1000 (AEST) Date: Wed, 16 Apr 2025 10:38:36 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH 7/7] udp: Propagate errors on listening and brand new sockets Message-ID: References: <20250415071624.2618589-1-david@gibson.dropbear.id.au> <20250415071624.2618589-8-david@gibson.dropbear.id.au> <20250415205417.1a3b2cde@elisabeth> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="5mBn0AvPUQakk99i" Content-Disposition: inline In-Reply-To: <20250415205417.1a3b2cde@elisabeth> Message-ID-Hash: COGAB7L3WEA7S6N446ULZK3CQGXDQJG7 X-Message-ID-Hash: COGAB7L3WEA7S6N446ULZK3CQGXDQJG7 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top, Jon Maloy X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --5mBn0AvPUQakk99i Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Apr 15, 2025 at 08:54:17PM +0200, Stefano Brivio wrote: > On Tue, 15 Apr 2025 17:16:24 +1000 > David Gibson wrote: >=20 > > udp_sock_recverr() processes errors on UDP sockets and attempts to > > propagate them as ICMP packets on the tap interface. To do this it > > currently requires the flow with which the error is associated as a > > parameter. If that's missing it will clear the error condition, but not > > propagate it. > >=20 > > That means that we largely ignore errors on "listening" sockets. It al= so > > means we may discard some errors on flow specific sockets if they occur > > very shortly after the socket is created. In udp_flush_flow() we need = to > > clear any datagrams received between bind() and connect() which might n= ot > > be associated with the "final" flow for the socket. If we get errors > > before that point we'll ignore them in the same way because we don't kn= ow > > the flow they're associated with in advance. > >=20 > > This can happen in practice if we have errors which occur almost > > immediately after connect(), such as ECONNREFUSED when we connect() to a > > local address where nothing is listening. > >=20 > > Between the extended error message itself and the PKTINFO information we > > do actually have enough information to find the correct flow. So, rath= er > > than ignoring errors where we don't have a flow "hint", determine the f= low > > the hard way in udp_sock_recverr(). > >=20 > > Signed-off-by: David Gibson > > --- > > udp.c | 41 ++++++++++++++++++++++++++++++++--------- > > 1 file changed, 32 insertions(+), 9 deletions(-) > >=20 > > diff --git a/udp.c b/udp.c > > index 6db3accc..c04a091b 100644 > > --- a/udp.c > > +++ b/udp.c > > @@ -504,27 +504,34 @@ static int udp_pktinfo(struct msghdr *msg, union = inany_addr *dst) > > * @c: Execution context > > * @s: Socket to receive errors from > > * @sidx: Flow and side of @s, or FLOW_SIDX_NONE if unknown > > + * @pif: Interface on which the error occurred > > + * (only used if @sidx =3D=3D FLOW_SIDX_NONE) > > + * @port: Local port number of @s (only used if @sidx =3D=3D FLOW_SIDX= _NONE) > > * > > * Return: 1 if error received and processed, 0 if no more errors in q= ueue, < 0 > > * if there was an error reading the queue > > * > > * #syscalls recvmsg > > */ > > -static int udp_sock_recverr(const struct ctx *c, int s, flow_sidx_t si= dx) > > +static int udp_sock_recverr(const struct ctx *c, int s, flow_sidx_t si= dx, > > + uint8_t pif, in_port_t port) > > { > > struct errhdr { > > struct sock_extended_err ee; > > union sockaddr_inany saddr; > > }; > > char buf[PKTINFO_SPACE + CMSG_SPACE(sizeof(struct errhdr))]; > > + const struct errhdr *eh =3D NULL; > > char data[ICMP6_MAX_DLEN]; > > - const struct errhdr *eh; > > struct cmsghdr *hdr; > > struct iovec iov =3D { > > .iov_base =3D data, > > .iov_len =3D sizeof(data) > > }; > > + union sockaddr_inany src; > > struct msghdr mh =3D { > > + .msg_name =3D &src, > > + .msg_namelen =3D sizeof(src), > > .msg_iov =3D &iov, > > .msg_iovlen =3D 1, > > .msg_control =3D buf, > > @@ -554,7 +561,7 @@ static int udp_sock_recverr(const struct ctx *c, in= t s, flow_sidx_t sidx) > > hdr->cmsg_type =3D=3D IP_RECVERR) || > > (hdr->cmsg_level =3D=3D IPPROTO_IPV6 && > > hdr->cmsg_type =3D=3D IPV6_RECVERR)) > > - break; > > + break; > > } > > =20 > > if (!hdr) { > > @@ -568,8 +575,19 @@ static int udp_sock_recverr(const struct ctx *c, i= nt s, flow_sidx_t sidx) > > str_ee_origin(&eh->ee), s, strerror_(eh->ee.ee_errno)); > > =20 > > if (!flow_sidx_valid(sidx)) { > > - trace("Ignoring received IP_RECVERR cmsg on listener socket"); > > - return 1; > > + /* No hint from the socket, determine flow from addresses */ > > + union inany_addr dst; > > + > > + if (udp_pktinfo(&mh, &dst) < 0) { > > + warn("Missing PKTINFO on UDP error"); >=20 > ...changed this to debug(), see my comments to 5/7. Actually this one can go away entirely. As you pointed out it's redundant with the one in udp_pktinfo() itself. Oh well, the extra debug() should be harmless enough. --=20 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 --5mBn0AvPUQakk99i Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmf+/AsACgkQzQJF27ox 2GeAjxAAnJ+/xhCi+ByZM90V//wsnZVAxnyXJMUbptjgaale+3GjHutyn7lgEVL3 kRwkaXSlviG+3o1LDgTpQ0C3ImkFgr9xXxcPI1YoMx0F1s1Xh4+d0z5ki9BGmrIo gCRQ5lwv48oTJpK0FgsuAkgqjVI/GFowRYeGGnzYYkjfFNST8QgGmEVvF7wSzwUr f6dBLeDMg2/X3TdNCWdn+ne0hzhDpDpoPltDanVn+cTtbWES2pZCUQVK1Japf7z8 sUIbYkQPmEFmP1U55Gz7oSQporWX8cbuDQG4G6BxUwp9oDpS5Eki5N1jLLoLe0gz OqJlh7T4CWuBUe3aMKTxvHAUMLpeGi1vuIFjmSh4L7a2mJsSA2pUxh7Trhq52hb1 /RCxsu8c5w/KLQilmKOVXlPE7BHIfOZnRbtF1jUA2++c0le2CVnSHB9EC8gaM9mZ /RV4yPuaH2KnwgsRFSIRyfnO/X12g7/OOBqGYMvCoFI3oUSYR9LLBLlPAW6M0vK/ O4WSZ3FT/1tnHlcjb89L3UiZo0WELrtYsANaHzIt/V0kjIg+4G9BCg7gQbo4TEfx k9elbp43Vb6su3+g3B0dQJtKcnEpKQOBBUDB/rty4vWMg5UnYQE1iMH9neMI5k9Q GlbUOkkMDa0Fyuz3ZyFrq9F1SfZjKHchclmjwMfZFB0Zdaq+MG0= =JtBc -----END PGP SIGNATURE----- --5mBn0AvPUQakk99i--