import UBI passt-0^20251210.gd04c480-5.el9_8
This commit is contained in:
parent
b396701ee3
commit
3671914cf9
@ -0,0 +1,106 @@
|
||||
From 116e08082c23c8f00e608bd7c7825aa068401e46 Mon Sep 17 00:00:00 2001
|
||||
From: Laurent Vivier <lvivier@redhat.com>
|
||||
Date: Wed, 7 Jan 2026 09:08:09 +0100
|
||||
Subject: [PATCH 19/20] udp_vu: Discard datagrams when RX virtqueue is not
|
||||
usable
|
||||
|
||||
During vhost-user device initialization, UDP datagrams may arrive on
|
||||
listening sockets before the guest has enabled the RX virtqueue.
|
||||
|
||||
When this happens, udp_vu_sock_recv() returns 0 without consuming
|
||||
the datagram from the socket. The caller, udp_sock_fwd(), uses a
|
||||
while loop with udp_peek_addr() to process pending datagrams. Since
|
||||
the datagram remains in the socket buffer, udp_peek_addr() keeps
|
||||
returning data available, causing a busy loop with 100% CPU usage.
|
||||
|
||||
To avoid that, we need to discard the data when the virtqueue is not
|
||||
ready. udp_buf_sock_to_tap() actually does the same as it reads data
|
||||
with udp_sock_recv() and if fd_tap is not initialized tap_send_frames()
|
||||
drops them.
|
||||
|
||||
Fixes: 28997fcb29b5 ("vhost-user: add vhost-user")
|
||||
Link: https://bugs.passt.top/show_bug.cgi?id=185
|
||||
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
|
||||
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
(cherry picked from commit edac476e268e4a0c5759a32fea9c720056de6315)
|
||||
---
|
||||
udp_vu.c | 32 ++++++++++++++++++++++----------
|
||||
1 file changed, 22 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/udp_vu.c b/udp_vu.c
|
||||
index c30dcf9..3774d53 100644
|
||||
--- a/udp_vu.c
|
||||
+++ b/udp_vu.c
|
||||
@@ -65,7 +65,8 @@ static size_t udp_vu_hdrlen(bool v6)
|
||||
* @v6: Set for IPv6 connections
|
||||
* @dlen: Size of received data (output)
|
||||
*
|
||||
- * Return: number of iov entries used to store the datagram
|
||||
+ * Return: number of iov entries used to store the datagram, 0 if the datagram
|
||||
+ * was discarded because the virtqueue is not ready, -1 on error
|
||||
*/
|
||||
static int udp_vu_sock_recv(const struct ctx *c, struct vu_virtq *vq, int s,
|
||||
bool v6, ssize_t *dlen)
|
||||
@@ -77,6 +78,15 @@ static int udp_vu_sock_recv(const struct ctx *c, struct vu_virtq *vq, int s,
|
||||
|
||||
ASSERT(!c->no_udp);
|
||||
|
||||
+ if (!vu_queue_enabled(vq) || !vu_queue_started(vq)) {
|
||||
+ debug("Got UDP packet, but RX virtqueue not usable yet");
|
||||
+
|
||||
+ if (recvmsg(s, &msg, MSG_DONTWAIT) < 0)
|
||||
+ debug_perror("Failed to discard datagram");
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
/* compute L2 header length */
|
||||
hdrlen = udp_vu_hdrlen(v6);
|
||||
|
||||
@@ -87,7 +97,7 @@ static int udp_vu_sock_recv(const struct ctx *c, struct vu_virtq *vq, int s,
|
||||
sizeof(struct virtio_net_hdr_mrg_rxbuf),
|
||||
NULL);
|
||||
if (iov_cnt == 0)
|
||||
- return 0;
|
||||
+ return -1;
|
||||
|
||||
/* reserve space for the headers */
|
||||
ASSERT(iov_vu[0].iov_len >= MAX(hdrlen, ETH_ZLEN));
|
||||
@@ -101,7 +111,7 @@ static int udp_vu_sock_recv(const struct ctx *c, struct vu_virtq *vq, int s,
|
||||
*dlen = recvmsg(s, &msg, 0);
|
||||
if (*dlen < 0) {
|
||||
vu_queue_rewind(vq, iov_cnt);
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
/* restore the pointer to the headers address */
|
||||
@@ -216,15 +226,17 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s, int n, flow_sidx_t tosidx)
|
||||
int iov_used;
|
||||
|
||||
iov_used = udp_vu_sock_recv(c, vq, s, v6, &dlen);
|
||||
- if (iov_used <= 0)
|
||||
+ if (iov_used < 0)
|
||||
break;
|
||||
|
||||
- udp_vu_prepare(c, toside, dlen);
|
||||
- if (*c->pcap) {
|
||||
- udp_vu_csum(toside, iov_used);
|
||||
- pcap_iov(iov_vu, iov_used,
|
||||
- sizeof(struct virtio_net_hdr_mrg_rxbuf));
|
||||
+ if (iov_used > 0) {
|
||||
+ udp_vu_prepare(c, toside, dlen);
|
||||
+ if (*c->pcap) {
|
||||
+ udp_vu_csum(toside, iov_used);
|
||||
+ pcap_iov(iov_vu, iov_used,
|
||||
+ sizeof(struct virtio_net_hdr_mrg_rxbuf));
|
||||
+ }
|
||||
+ vu_flush(vdev, vq, elem, iov_used);
|
||||
}
|
||||
- vu_flush(vdev, vq, elem, iov_used);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,116 @@
|
||||
From e361a399f88c8cef26bd74df8259d45001d9aa44 Mon Sep 17 00:00:00 2001
|
||||
From: Stefano Brivio <sbrivio@redhat.com>
|
||||
Date: Mon, 8 Jun 2026 21:06:17 +0200
|
||||
Subject: [PATCH 20/20] conf, util: Disable IPv6 if explicit IPv6 socket probe
|
||||
fails
|
||||
|
||||
In https://bugs.passt.top/show_bug.cgi?id=188, I originally reported
|
||||
that if IPv6 is disabled in the kernel (for example via command line
|
||||
parameter ipv6.disable=1, or disabled in build configuration), and we
|
||||
attempt to forward any port, we'll exit right away after failing to
|
||||
set up dual-stack listening sockets.
|
||||
|
||||
The original instance of that issue is now fixed for pasta by commit
|
||||
75dcbc300bf0 ("pasta: Warn, disable matching IP version if not
|
||||
supported, in local mode") together with the new implementation of
|
||||
the rule forwarding table, starting from commit b223bec48213 ("fwd,
|
||||
tcp, udp: Set up listening sockets based on forward table"), because
|
||||
we first parse forwarding options, then probe for IPv6 support in the
|
||||
target namespace (and disable IPv6 as a result), and finally bind
|
||||
sockets once we already know that IPv6 support is disabled.
|
||||
|
||||
But we don't do that when invoked as passt, because we have no target
|
||||
namespace and hence no probing for IPv6 support whatsoever.
|
||||
|
||||
Add IPv6 to the socket features we test in sock_probe_features(), and,
|
||||
if we fail to create an IPv6 socket for whatever reason (which might
|
||||
include security policies as well), disable IPv6 support altogether,
|
||||
so that we won't attempt to use dual-stack sockets for port forwarding
|
||||
either.
|
||||
|
||||
Note that the probe comes without any sort of debug message, because
|
||||
at this point we haven't parsed the configuration yet, and we would
|
||||
therefore print that regardless of the selected logging level and
|
||||
other options, including --ipv4-only, which would be rather confusing.
|
||||
I doubt we'll miss this kind of message though, IPv6 support being
|
||||
disabled is anyway obvious from the initial configuration dump.
|
||||
|
||||
Reported-by: Chi Cuong HA <ChiCuong.HA@amadeus.com>
|
||||
Reported-by: Romain Geissler <romain.geissler@amadeus.com>
|
||||
Link: https://bugs.passt.top/show_bug.cgi?id=188
|
||||
Fixes: 4ddd59bc6085 ("conf: Separate local mode for each IP version, don't enable disabled IP version")
|
||||
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
(cherry picked from commit e1a6d9ef626aa6dbcfeef97dbbab3bd69c35b4b1)
|
||||
---
|
||||
conf.c | 6 ++++++
|
||||
passt.h | 2 ++
|
||||
util.c | 8 ++++++++
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/conf.c b/conf.c
|
||||
index fdc19e8..1af7753 100644
|
||||
--- a/conf.c
|
||||
+++ b/conf.c
|
||||
@@ -1515,6 +1515,9 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
||||
+ if (c->no_ipv6)
|
||||
+ v4_only = true;
|
||||
+
|
||||
if (c->mode == MODE_PASTA) {
|
||||
c->no_dhcp_dns = c->no_dhcp_dns_search = 1;
|
||||
fwd_default = FWD_AUTO;
|
||||
@@ -1919,6 +1922,9 @@ void conf(struct ctx *c, int argc, char **argv)
|
||||
v6_only = false;
|
||||
break;
|
||||
case '6':
|
||||
+ if (c->no_ipv6)
|
||||
+ die("IPv6 not available but --ipv6-only given");
|
||||
+
|
||||
v6_only = true;
|
||||
v4_only = false;
|
||||
break;
|
||||
diff --git a/passt.h b/passt.h
|
||||
index 79d01dd..266563e 100644
|
||||
--- a/passt.h
|
||||
+++ b/passt.h
|
||||
@@ -205,6 +205,7 @@ struct ip6_ctx {
|
||||
* @low_wmem: Low probed net.core.wmem_max
|
||||
* @low_rmem: Low probed net.core.rmem_max
|
||||
* @no_bindtodevice: Unprivileged SO_BINDTODEVICE not available
|
||||
+ * @no_ipv6: IPv6 sockets not available
|
||||
* @vdev: vhost-user device
|
||||
* @device_state_fd: Device state migration channel
|
||||
* @device_state_result: Device state migration result
|
||||
@@ -283,6 +284,7 @@ struct ctx {
|
||||
int low_wmem;
|
||||
int low_rmem;
|
||||
int no_bindtodevice;
|
||||
+ bool no_ipv6;
|
||||
|
||||
struct vu_dev *vdev;
|
||||
|
||||
diff --git a/util.c b/util.c
|
||||
index bfeb619..f4f8f85 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -331,6 +331,14 @@ void sock_probe_features(struct ctx *c)
|
||||
c->no_bindtodevice = 1;
|
||||
}
|
||||
|
||||
+ /* Check if IPv6 sockets are usable */
|
||||
+ close(s);
|
||||
+ s = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
|
||||
+ if (s < 0) {
|
||||
+ c->no_ipv6 = true;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
close(s);
|
||||
}
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
Name: passt
|
||||
Version: 0^20251210.gd04c480
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
Summary: User-mode networking daemons for virtual machines and namespaces
|
||||
License: GPL-2.0-or-later AND BSD-3-Clause
|
||||
Group: System Environment/Daemons
|
||||
@ -38,6 +38,8 @@ Patch15: 0015-tcp-Re-introduce-inactivity-timeouts-based-on-a-cloc.patch
|
||||
Patch16: 0016-tcp-Extend-tcp_send_flag-to-send-TCP-keepalive-segme.patch
|
||||
Patch17: 0017-tcp-Send-TCP-keepalive-segments-after-a-period-of-ta.patch
|
||||
Patch18: 0018-tcp-Replace-send-buffer-boost-with-EPOLLOUT-monitori.patch
|
||||
Patch19: 0019-udp_vu-Discard-datagrams-when-RX-virtqueue-is-not-us.patch
|
||||
Patch20: 0020-conf-util-Disable-IPv6-if-explicit-IPv6-socket-probe.patch
|
||||
|
||||
BuildRequires: gcc, make, git, checkpolicy, selinux-policy-devel
|
||||
Requires: (%{name}-selinux = %{version}-%{release} if selinux-policy-%{selinuxtype})
|
||||
@ -152,6 +154,9 @@ fi
|
||||
%{_datadir}/selinux/packages/%{selinuxtype}/passt-repair.pp
|
||||
|
||||
%changelog
|
||||
* Thu Jun 11 2026 Stefano Brivio <sbrivio@redhat.com> - 0^20251210.gd04c480-5
|
||||
- Resolves: RHEL-184106 RHEL-183990
|
||||
|
||||
* Tue Apr 21 2026 Stefano Brivio <sbrivio@redhat.com> - 0^20251210.gd04c480-4
|
||||
- Resolves: RHEL-169637 RHEL-169639 RHEL-169648
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user