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=poOXzF+Q; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 808845A0275 for ; Fri, 06 Sep 2024 13:49:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202408; t=1725623381; bh=HcjQQHgvZlvTzlmWejT/kdgKtfTnbSIQe7e5FdyUOJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=poOXzF+QVW5ulvd/Qd8OetfEwYtgELi8bTRVenGDCl/qklj2Im2A4qLUgNKju9dor RwLjq9C6CkNgxE/PlXg+gz1cE5PYxmLdRKgSg+CbypGLs0C9lwNEXDLDo/rgeS5kum gmoDWnLHFrxblCchzoylDBf4k4GsLpp+7FxTyoMYWQtf87LEM1iarXoLfhvXWos7zA EjCkQ42m/+/X2TgwSSxyWl0lhzyWU79rxEp87GOIYYxqLTZ2y1MlEiZiAx3J6bSjgX 7i0lz5voYCL04nRtK/WQwIiLOVU4/zS2CjGyUnn8x1+OYO4WrY7WD/TYVOJpAQ1ORH MJPhrNjOmwM8w== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4X0ZK11KC2z4x3q; Fri, 6 Sep 2024 21:49:41 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 3/4] tap: Restructure in tap_pasta_input() Date: Fri, 6 Sep 2024 21:49:38 +1000 Message-ID: <20240906114939.261097-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240906114939.261097-1-david@gibson.dropbear.id.au> References: <20240906114939.261097-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: HSVFE3ZX3XKDZSGEZ2H5IHQIOZOGRAYX X-Message-ID-Hash: HSVFE3ZX3XKDZSGEZ2H5IHQIOZOGRAYX 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: tap_pasta_input() has a rather confusing structure, using two gotos. Remove these by restructuring the function to have the main loop condition based on filling our buffer space, with errors or running out of data treated as the exception, rather than the other way around. This allows us to handle the EINTR which triggered the 'restart' goto with a continue. The outer 'redo' was triggered if we completely filled our buffer, to flush it and do another pass. This one is unnecessary since we don't (yet) use EPOLLET on the tap device: if there's still more data we'll get another event and re-enter the loop. Along the way handle a couple of extra edge cases: - Check for EWOULDBLOCK as well as EAGAIN for the benefit of any future ports where those might not have the same value - Detect EOF on the tap device and exit in that case Signed-off-by: David Gibson --- tap.c | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/tap.c b/tap.c index 8977b3f2..145587fc 100644 --- a/tap.c +++ b/tap.c @@ -1073,42 +1073,35 @@ void tap_handler_passt(struct ctx *c, uint32_t events, static void tap_pasta_input(struct ctx *c, const struct timespec *now) { ssize_t n, len; - int ret; - -redo: - n = 0; tap_flush_pools(); -restart: - while ((len = read(c->fd_tap, pkt_buf + n, TAP_BUF_BYTES - n)) > 0) { - if (len < (ssize_t)sizeof(struct ethhdr) || - len > (ssize_t)ETH_MAX_MTU) { - n += len; - continue; - } + for (n = 0; n < (ssize_t)TAP_BUF_BYTES; n += len) { + len = read(c->fd_tap, pkt_buf + n, TAP_BUF_BYTES - n); + if (len == 0) { + die("EOF on tap device, exiting"); + } else if (len < 0) { + if (errno == EINTR) { + len = 0; + continue; + } - tap_add_packet(c, len, pkt_buf + n); + if (errno == EAGAIN && errno == EWOULDBLOCK) + break; /* all done for now */ - if ((n += len) == TAP_BUF_BYTES) - break; - } + die("Error on tap device, exiting"); + } - if (len < 0 && errno == EINTR) - goto restart; + /* Ignore frames of bad length */ + if (len < (ssize_t)sizeof(struct ethhdr) || + len > (ssize_t)ETH_MAX_MTU) + continue; - ret = errno; + tap_add_packet(c, len, pkt_buf + n); + } tap_handler(c, now); - - if (len > 0 || ret == EAGAIN) - return; - - if (n == TAP_BUF_BYTES) - goto redo; - - die("Error on tap device, exiting"); } /** -- 2.46.0