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=202408 header.b=LGXrVfOX; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id D849A5A004E for ; Fri, 06 Sep 2024 07:17:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202408; t=1725599833; bh=eWL1+sDuGDb3H41VvbJq5InsKFQTvSpB2qU/V1/ywIY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LGXrVfOXAW5JeegGpzG9LeyHBq8dAHr+LHXsMBGaoZQcV4H7FJT3xK/8stlCa3HNk +O6Vm5craw4frJ2hBhaMFk3zBanSHzWqDtkzu18cF21kpBKeqnuNAC1fPUyFhpNAeB SyfuKzPFUQqbl+6XgfhLvg/SZgqYs24j1t3/hV8A7q6GCTbcdG3vW8Wp5IMApLQn0J rztjipnz/ph78olDSWPQIp4lkHPaYaL10jY0MgCIYFFwtl+aC1DQc6o4sLR0GLU8Ko nueVPaumW3CJA7+hIXby7WDy8aDM9tzeva8rea+qgvpzmR55nCXoHOrc99xncwxKOa h7Dw6326DpTxQ== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4X0Pc957Mxz4xFb; Fri, 6 Sep 2024 15:17:13 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 5/6] udp: Treat errors getting errors as unrecoverable Date: Fri, 6 Sep 2024 15:17:09 +1000 Message-ID: <20240906051710.3863211-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240906051710.3863211-1-david@gibson.dropbear.id.au> References: <20240906051710.3863211-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: RDZAHHHJHLZD5FOVRWKSTPFJY3VTBLXC X-Message-ID-Hash: RDZAHHHJHLZD5FOVRWKSTPFJY3VTBLXC 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: David Gibson 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: We can get network errors, usually transient, reported via the socket error queue. However, at least theoretically, we could get errors trying to read the queue itself. Since we have no idea how to clear an error condition in that case, treat it as unrecoverable. Signed-off-by: David Gibson --- udp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/udp.c b/udp.c index fd91b539..fe5df995 100644 --- a/udp.c +++ b/udp.c @@ -387,11 +387,12 @@ static void udp_tap_prepare(const struct mmsghdr *mmh, unsigned idx, * udp_sock_recverr() - Receive and clear an error from a socket * @s: Socket to receive from * - * Return: true if errors received and processed, false if no more errors + * Return: 1 if error received and processed, 0 if no more errors in queue, < 0 + * if there was an error reading the queue * * #syscalls recvmsg */ -static bool udp_sock_recverr(int s) +static int udp_sock_recverr(int s) { const struct sock_extended_err *ee; const struct cmsghdr *hdr; @@ -408,14 +409,16 @@ static bool udp_sock_recverr(int s) rc = recvmsg(s, &mh, MSG_ERRQUEUE); if (rc < 0) { - if (errno != EAGAIN && errno != EWOULDBLOCK) - err_perror("Failed to read error queue"); - return false; + if (errno == EAGAIN || errno == EWOULDBLOCK) + return 0; + + err_perror("UDP: Failed to read error queue"); + return -1; } if (!(mh.msg_flags & MSG_ERRQUEUE)) { err("Missing MSG_ERRQUEUE flag reading error queue"); - return false; + return -1; } hdr = CMSG_FIRSTHDR(&mh); @@ -424,7 +427,7 @@ static bool udp_sock_recverr(int s) (hdr->cmsg_level == IPPROTO_IPV6 && hdr->cmsg_type == IPV6_RECVERR))) { err("Unexpected cmsg reading error queue"); - return false; + return -1; } ee = (const struct sock_extended_err *)CMSG_DATA(hdr); @@ -433,7 +436,7 @@ static bool udp_sock_recverr(int s) debug("%s error on UDP socket %i: %s", str_ee_origin(ee), s, strerror(ee->ee_errno)); - return true; + return 1; } /** @@ -447,6 +450,7 @@ static bool udp_sock_recverr(int s) static int udp_sock_errs(const struct ctx *c, int s, uint32_t events) { unsigned n_err = 0; + int rc; ASSERT(!c->no_udp); @@ -454,8 +458,11 @@ static int udp_sock_errs(const struct ctx *c, int s, uint32_t events) return 0; /* Nothing to do */ /* Empty the error queue */ - while (udp_sock_recverr(s)) - n_err++; + while ((rc = udp_sock_recverr(s)) > 0) + n_err += rc; + + if (rc < 0) + return -1; /* error reading error, unrecoverable */ return n_err; } -- 2.46.0