From: Laine Stump Date: Thu, 12 Feb 2026 16:23:10 +0000 (-0500) Subject: qemu: support setting default route for passt interfaces inside the guest X-Git-Tag: v12.2.0-rc1~107 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=331d9fe3bace413bc0dcb5d3c1277d405d27cdcf;p=thirdparty%2Flibvirt.git qemu: support setting default route for passt interfaces inside the guest libvirt's element has for a long time supported adding sub-elements to specify arbitrary routes to be added to the guest OS networking, but historically this has only worked for LXC guests. If you tried to add to the interface of a QEMU guest, it would be rejected. passt networking doesn't support setting *any arbitrary* route but it does support setting a default route (using the passt commandline "--gateway" parameter). A default route is really just a "route with unspecified destination/prefix", so a default route can be specified in libvirt XML with: Attempts to give a specified destination, prefix, or metric will result in a validation error. Resolves: https://issues.redhat.com/browse/RHEL-46602 Signed-off-by: Laine Stump Reviewed-by: Ján Tomko --- diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index b4e28e99ef..9f245293e6 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -6689,11 +6689,14 @@ IPv6 the default prefix is 64. The optional ``peer`` attribute holds the IP address of the other end of a point-to-point network device :since:`(since 2.1.0)`. -:since:`Since 1.2.12` route elements can also be added to define IP routes to -add in the guest. The attributes of this element are described in the -documentation for the ``route`` element in `network -definitions `__. This is used by the LXC -driver. +:since:`Since 1.2.12` route elements can also be added to define IP +routes to add in the guest. The attributes of this element are +described in the documentation for the ``route`` element in `network +definitions `__. This is used by the +LXC driver for adding general routes within the container. :since: +'Since 12.2.0' ``route`` elements are also user by the QEMU driver only in the +case of a passt-based interface (````) and only +for default routes (done by specifying just the ``gateway``). :: @@ -6799,6 +6802,7 @@ setting guest-side IP addresses with ```` and port forwarding with + ... diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c index 746eef3a0f..a142620b37 100644 --- a/src/qemu/qemu_passt.c +++ b/src/qemu/qemu_passt.c @@ -263,6 +263,22 @@ qemuPasstBuildCommand(char **socketName, } } + /* Add default route(s) */ + for (i = 0; i < net->guestIP.nroutes; i++) { + const virNetDevIPRoute *route = net->guestIP.routes[i]; + g_autofree char *gateway = NULL; + + if (!(gateway = virSocketAddrFormat(&route->gateway))) + return NULL; + + /* validation has already guaranteed that there is at most 1 + * IPv4 and 1 IPv6 route, and that they are only default + * routes (i.e. destination 0.0.0.0/0) + */ + + virCommandAddArgList(cmd, "--gateway", gateway, NULL); + } + /* Add port forwarding info */ for (i = 0; i < net->nPortForwards; i++) { diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 5c664d549b..bb3b2fee7e 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1904,6 +1904,8 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net, { bool hasV4Addr = false; bool hasV6Addr = false; + bool hasV4Route = false; + bool hasV6Route = false; size_t i; if (net->type == VIR_DOMAIN_NET_TYPE_USER || @@ -1978,10 +1980,50 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net, } } - if (net->guestIP.nroutes) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Invalid attempt to set network interface guest-side IP route, not supported by QEMU")); - return -1; + + for (i = 0; i < net->guestIP.nroutes; i++) { + const virNetDevIPRoute *route = net->guestIP.routes[i]; + + if (net->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Invalid attempt to set network interface guest-side IP route, not supported for this interface type/backend")); + return -1; + } + + switch (VIR_SOCKET_ADDR_FAMILY(&route->gateway)) { + case AF_INET: + if (hasV4Route) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only one IPv4 default route can be specified for an interface using the passt backend")); + return -1; + } + hasV4Route = true; + break; + case AF_INET6: + if (hasV6Route) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only one IPv6 default route can be specified for an interface using the passt backend")); + return -1; + } + hasV6Route = true; + break; + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("All elements of an interface using the passt backend must be default routes, with an IPv4 or IPv6 gateway specified")); + return -1; + } + + /* the only type of route that can be specified for passt is + * the default route, so none of the parameters except gateway + * are acceptable + */ + if (VIR_SOCKET_ADDR_VALID(&route->address) || + virNetDevIPRouteGetPrefix(route) != 0 || + route->has_metric) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _(" elements of an interface using the passt backend must be default routes, with only a gateway specified")); + return -1; + } } if (net->type == VIR_DOMAIN_NET_TYPE_VDPA) { diff --git a/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.passt0.args b/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.passt0.args index b0f26d8089..73ffcfe405 100644 --- a/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.passt0.args +++ b/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.passt0.args @@ -9,6 +9,7 @@ passt \ --address 172.17.2.0 \ --netmask 24 \ --address 2001:db8:ac10:fd01::feed \ +--gateway 172.17.2.1 \ --tcp-ports '2001:db8:ac10:fd01::1:10/22:2022,1000-1050,~1020,~1030-1040' \ --udp-ports '1.2.3.4%eth0/5000-5020:6000-6020,~5010-5015' \ --tcp-ports 80 \ diff --git a/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.xml b/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.xml index 77da297936..401b1ac0a2 100644 --- a/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.xml +++ b/tests/qemuxmlconfdata/net-user-passt.x86_64-7.2.0.xml @@ -33,6 +33,7 @@ + diff --git a/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.passt0.args b/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.passt0.args index b0f26d8089..73ffcfe405 100644 --- a/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.passt0.args +++ b/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.passt0.args @@ -9,6 +9,7 @@ passt \ --address 172.17.2.0 \ --netmask 24 \ --address 2001:db8:ac10:fd01::feed \ +--gateway 172.17.2.1 \ --tcp-ports '2001:db8:ac10:fd01::1:10/22:2022,1000-1050,~1020,~1030-1040' \ --udp-ports '1.2.3.4%eth0/5000-5020:6000-6020,~5010-5015' \ --tcp-ports 80 \ diff --git a/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.xml b/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.xml index 917a9edaa0..625c656ca1 100644 --- a/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/net-user-passt.x86_64-latest.xml @@ -33,6 +33,7 @@ + diff --git a/tests/qemuxmlconfdata/net-user-passt.xml b/tests/qemuxmlconfdata/net-user-passt.xml index 80d15de2ed..8c1565e7fe 100644 --- a/tests/qemuxmlconfdata/net-user-passt.xml +++ b/tests/qemuxmlconfdata/net-user-passt.xml @@ -30,6 +30,7 @@ + diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.passt0.args b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.passt0.args index bd176fd355..71209c3cfc 100644 --- a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.passt0.args +++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.passt0.args @@ -10,6 +10,7 @@ passt \ --address 172.17.2.0 \ --netmask 24 \ --address 2001:db8:ac10:fd01::feed \ +--gateway 2001:db8:ac10:fd01::beef \ --tcp-ports '2001:db8:ac10:fd01::1:10/22:2022,1000-1050,~1020,~1030-1040' \ --udp-ports '1.2.3.4%eth0/5000-5020:6000-6020,~5010-5015' \ --tcp-ports 80 \ diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml index 5802754c4b..f14fa49317 100644 --- a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml @@ -36,6 +36,7 @@ + diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.xml index 0a37511a0f..417903b7dc 100644 --- a/tests/qemuxmlconfdata/net-vhostuser-passt.xml +++ b/tests/qemuxmlconfdata/net-vhostuser-passt.xml @@ -32,6 +32,7 @@ +