passt: Add libvirt patch for qemu UNIX socket domain back-end
...and mention it in the README. While at it, remove useless escaping in the README, and fix indentation in the syslog message with the qemu command line example. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
35015ce72e
commit
e653f9b3ed
3 changed files with 438 additions and 2 deletions
15
README.md
15
README.md
|
@ -5,6 +5,8 @@ and native Layer-4 sockets (TCP, UDP, ICMP/ICMPv6 echo) on a host. It doesn't
|
||||||
require any capabilities or privileges, and it can be used as a simple
|
require any capabilities or privileges, and it can be used as a simple
|
||||||
replacement for Slirp.
|
replacement for Slirp.
|
||||||
|
|
||||||
|
![overview diagram](/builds/passt_overview.png)
|
||||||
|
|
||||||
- [General idea](#general-idea)
|
- [General idea](#general-idea)
|
||||||
- [Non-functional Targets](#non-functional-targets)
|
- [Non-functional Targets](#non-functional-targets)
|
||||||
- [Interfaces and Environment](#interfaces-and-environment)
|
- [Interfaces and Environment](#interfaces-and-environment)
|
||||||
|
@ -50,7 +52,7 @@ solution comes with a number of downsides:
|
||||||
_passt_ implements a thinner layer between guest and host, that only implements
|
_passt_ implements a thinner layer between guest and host, that only implements
|
||||||
what's strictly needed to pretend processes are running locally. A further, full
|
what's strictly needed to pretend processes are running locally. A further, full
|
||||||
TCP/IP stack is not necessarily needed. Some sort of TCP adaptation is needed,
|
TCP/IP stack is not necessarily needed. Some sort of TCP adaptation is needed,
|
||||||
however, as this layer runs without the `CAP\_NET\_RAW` capability: we can't
|
however, as this layer runs without the `CAP_NET_RAW` capability: we can't
|
||||||
create raw IP sockets on the pod, and therefore need to map packets at Layer-2
|
create raw IP sockets on the pod, and therefore need to map packets at Layer-2
|
||||||
to Layer-4 sockets offered by the host kernel.
|
to Layer-4 sockets offered by the host kernel.
|
||||||
|
|
||||||
|
@ -163,6 +165,17 @@ before _passt_ starts.
|
||||||
|
|
||||||
qemu-system-x86_64 ... -net socket,connect=/tmp/passt.socket -net nic,model=virtio
|
qemu-system-x86_64 ... -net socket,connect=/tmp/passt.socket -net nic,model=virtio
|
||||||
|
|
||||||
|
* alternatively, you can use libvirt, with [this patch](https://passt.top/passt/tree/libvirt/0001-conf-Introduce-support-for-UNIX-domain-socket-as-qem.patch),
|
||||||
|
to start qemu (with the patch mentioned above), with this kind of network
|
||||||
|
interface configuration:
|
||||||
|
|
||||||
|
<interface type='client'>
|
||||||
|
<mac address='52:54:00:02:6b:60'/>
|
||||||
|
<source path='/tmp/passt.socket'/>
|
||||||
|
<model type='virtio'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||||
|
</interface>
|
||||||
|
|
||||||
* and that's it, you should now have TCP connections, UDP, and ICMP/ICMPv6
|
* and that's it, you should now have TCP connections, UDP, and ICMP/ICMPv6
|
||||||
echo working from/to the guest for IPv4 and IPv6
|
echo working from/to the guest for IPv4 and IPv6
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
From 62e95cb4b5708eca7860139dffef22e65b29514c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefano Brivio <sbrivio@redhat.com>
|
||||||
|
Date: Sat, 20 Mar 2021 07:16:15 +0100
|
||||||
|
Subject: [PATCH] conf: Introduce support for UNIX domain socket as qemu netdev
|
||||||
|
back-end
|
||||||
|
|
||||||
|
Since qemu [TODO], named UNIX domain sockets can be used instead of
|
||||||
|
TCP to establish a virtual network between VMs.
|
||||||
|
|
||||||
|
The obvious difference compared with TCP is that we need pass a path
|
||||||
|
instead of address and port.
|
||||||
|
|
||||||
|
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
||||||
|
---
|
||||||
|
docs/formatdomain.rst | 41 +++++++++++++++++++------
|
||||||
|
docs/schemas/domaincommon.rng | 50 +++++++++++++++++++++++-------
|
||||||
|
src/conf/domain_conf.c | 58 +++++++++++++++++++++++++++--------
|
||||||
|
src/conf/domain_conf.h | 13 +++++---
|
||||||
|
src/qemu/qemu_command.c | 46 ++++++++++++++++++---------
|
||||||
|
src/qemu/qemu_hotplug.c | 8 +++--
|
||||||
|
6 files changed, 160 insertions(+), 56 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
|
||||||
|
index 9392c80113..b5b642e91a 100644
|
||||||
|
--- a/docs/formatdomain.rst
|
||||||
|
+++ b/docs/formatdomain.rst
|
||||||
|
@@ -4995,18 +4995,20 @@ must be from the multicast address block.
|
||||||
|
</devices>
|
||||||
|
...
|
||||||
|
|
||||||
|
-:anchor:`<a id="elementsNICSTCP"/>`
|
||||||
|
+:anchor:`<a id="elementsNICSStream"/>`
|
||||||
|
|
||||||
|
-TCP tunnel
|
||||||
|
-^^^^^^^^^^
|
||||||
|
+TCP or UNIX domain socket tunnel
|
||||||
|
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
+
|
||||||
|
+A stream-oriented client/server architecture provides a virtual network. One VM
|
||||||
|
+provides the server end of the network, all other VMS are configured as clients.
|
||||||
|
+All network traffic is routed between the VMs via the server. This mode is also
|
||||||
|
+available to unprivileged users. There is no default DNS or DHCP support and no
|
||||||
|
+outgoing network access. To provide outgoing network access, one of the VMs
|
||||||
|
+should have a 2nd NIC which is connected to one of the first 4 network types and
|
||||||
|
+do the appropriate routing.
|
||||||
|
|
||||||
|
-A TCP client/server architecture provides a virtual network. One VM provides the
|
||||||
|
-server end of the network, all other VMS are configured as clients. All network
|
||||||
|
-traffic is routed between the VMs via the server. This mode is also available to
|
||||||
|
-unprivileged users. There is no default DNS or DHCP support and no outgoing
|
||||||
|
-network access. To provide outgoing network access, one of the VMs should have a
|
||||||
|
-2nd NIC which is connected to one of the first 4 network types and do the
|
||||||
|
-appropriate routing.
|
||||||
|
+TCP endpoints can be specified as follows:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
@@ -5024,6 +5026,25 @@ appropriate routing.
|
||||||
|
</devices>
|
||||||
|
...
|
||||||
|
|
||||||
|
+Named UNIX domain sockets can be specified as follows:
|
||||||
|
+:since:`Since 7.2.0, qemu`
|
||||||
|
+
|
||||||
|
+::
|
||||||
|
+
|
||||||
|
+ ...
|
||||||
|
+ <devices>
|
||||||
|
+ <interface type='server'>
|
||||||
|
+ <mac address='52:54:00:22:c9:42'/>
|
||||||
|
+ <source path='/tmp/qemu.socket'/>
|
||||||
|
+ </interface>
|
||||||
|
+ ...
|
||||||
|
+ <interface type='client'>
|
||||||
|
+ <mac address='52:54:00:8b:c9:51'/>
|
||||||
|
+ <source path='/tmp/qemu.socket'/>
|
||||||
|
+ </interface>
|
||||||
|
+ </devices>
|
||||||
|
+ ...
|
||||||
|
+
|
||||||
|
:anchor:`<a id="elementsNICSUDP"/>`
|
||||||
|
|
||||||
|
UDP unicast tunnel
|
||||||
|
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
|
||||||
|
index 1dbfc68f18..350d6969c0 100644
|
||||||
|
--- a/docs/schemas/domaincommon.rng
|
||||||
|
+++ b/docs/schemas/domaincommon.rng
|
||||||
|
@@ -3125,10 +3125,7 @@
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<attribute name="type">
|
||||||
|
- <choice>
|
||||||
|
- <value>mcast</value>
|
||||||
|
- <value>client</value>
|
||||||
|
- </choice>
|
||||||
|
+ <value>mcast</value>
|
||||||
|
</attribute>
|
||||||
|
<interleave>
|
||||||
|
<element name="source">
|
||||||
|
@@ -3143,6 +3140,30 @@
|
||||||
|
<ref name="interface-options"/>
|
||||||
|
</interleave>
|
||||||
|
</group>
|
||||||
|
+ <group>
|
||||||
|
+ <attribute name="type">
|
||||||
|
+ <value>client</value>
|
||||||
|
+ </attribute>
|
||||||
|
+ <interleave>
|
||||||
|
+ <element name="source">
|
||||||
|
+ <choice>
|
||||||
|
+ <group>
|
||||||
|
+ <attribute name="address">
|
||||||
|
+ <ref name="ipv4Addr"/>
|
||||||
|
+ </attribute>
|
||||||
|
+ <attribute name="port">
|
||||||
|
+ <ref name="PortNumber"/>
|
||||||
|
+ </attribute>
|
||||||
|
+ </group>
|
||||||
|
+ <attribute name="path">
|
||||||
|
+ <ref name="absFilePath"/>
|
||||||
|
+ </attribute>
|
||||||
|
+ </choice>
|
||||||
|
+ <empty/>
|
||||||
|
+ </element>
|
||||||
|
+ <ref name="interface-options"/>
|
||||||
|
+ </interleave>
|
||||||
|
+ </group>
|
||||||
|
<group>
|
||||||
|
<attribute name="type">
|
||||||
|
<value>udp</value>
|
||||||
|
@@ -3174,14 +3195,21 @@
|
||||||
|
</attribute>
|
||||||
|
<interleave>
|
||||||
|
<element name="source">
|
||||||
|
- <optional>
|
||||||
|
- <attribute name="address">
|
||||||
|
- <ref name="ipv4Addr"/>
|
||||||
|
+ <choice>
|
||||||
|
+ <group>
|
||||||
|
+ <optional>
|
||||||
|
+ <attribute name="address">
|
||||||
|
+ <ref name="ipv4Addr"/>
|
||||||
|
+ </attribute>
|
||||||
|
+ </optional>
|
||||||
|
+ <attribute name="port">
|
||||||
|
+ <ref name="PortNumber"/>
|
||||||
|
+ </attribute>
|
||||||
|
+ </group>
|
||||||
|
+ <attribute name="path">
|
||||||
|
+ <ref name="absFilePath"/>
|
||||||
|
</attribute>
|
||||||
|
- </optional>
|
||||||
|
- <attribute name="port">
|
||||||
|
- <ref name="PortNumber"/>
|
||||||
|
- </attribute>
|
||||||
|
+ </choice>
|
||||||
|
<empty/>
|
||||||
|
</element>
|
||||||
|
<ref name="interface-options"/>
|
||||||
|
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
||||||
|
index 7671050134..55543c47ce 100644
|
||||||
|
--- a/src/conf/domain_conf.c
|
||||||
|
+++ b/src/conf/domain_conf.c
|
||||||
|
@@ -2569,8 +2569,9 @@ virDomainNetDefFree(virDomainNetDefPtr def)
|
||||||
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_UDP:
|
||||||
|
- g_free(def->data.socket.address);
|
||||||
|
- g_free(def->data.socket.localaddr);
|
||||||
|
+ g_free(def->data.socket.net.address);
|
||||||
|
+ g_free(def->data.socket.net.localaddr);
|
||||||
|
+ g_free(def->data.socket.path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
||||||
|
@@ -10792,6 +10793,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
g_autofree char *downscript = NULL;
|
||||||
|
g_autofree char *address = NULL;
|
||||||
|
g_autofree char *port = NULL;
|
||||||
|
+ g_autofree char *path = NULL;
|
||||||
|
g_autofree char *localaddr = NULL;
|
||||||
|
g_autofree char *localport = NULL;
|
||||||
|
g_autofree char *model = NULL;
|
||||||
|
@@ -10935,7 +10937,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
" <interface type='%s'>"), type);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
- } else if (!address &&
|
||||||
|
+ } else if (!address && !path &&
|
||||||
|
(def->type == VIR_DOMAIN_NET_TYPE_SERVER ||
|
||||||
|
def->type == VIR_DOMAIN_NET_TYPE_CLIENT ||
|
||||||
|
def->type == VIR_DOMAIN_NET_TYPE_MCAST ||
|
||||||
|
@@ -10943,6 +10945,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
virXMLNodeNameEqual(cur, "source")) {
|
||||||
|
address = virXMLPropString(cur, "address");
|
||||||
|
port = virXMLPropString(cur, "port");
|
||||||
|
+ path = virXMLPropString(cur, "path");
|
||||||
|
if (!localaddr && def->type == VIR_DOMAIN_NET_TYPE_UDP) {
|
||||||
|
xmlNodePtr tmpnode = ctxt->node;
|
||||||
|
ctxt->node = cur;
|
||||||
|
@@ -11186,6 +11189,27 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_SERVER:
|
||||||
|
+ if (path != NULL) {
|
||||||
|
+ if (port != NULL || address != NULL ||
|
||||||
|
+ localport != NULL || localaddr != NULL) {
|
||||||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
+ _("<source> 'path' attribute "
|
||||||
|
+ "for socket interface cannot be specified "
|
||||||
|
+ "together with other attributes"));
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+ def->data.socket.path = g_steal_pointer(&path);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (port == NULL) {
|
||||||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
+ _("Neither <source> 'port' nor 'path' attribute "
|
||||||
|
+ "specified with socket interface"));
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ G_GNUC_FALLTHROUGH;
|
||||||
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_UDP:
|
||||||
|
if (port == NULL) {
|
||||||
|
@@ -11194,7 +11218,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
"specified with socket interface"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
- if (virStrToLong_i(port, NULL, 10, &def->data.socket.port) < 0) {
|
||||||
|
+ if (virStrToLong_i(port, NULL, 10, &def->data.socket.net.port) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Cannot parse <source> 'port' attribute "
|
||||||
|
"with socket interface"));
|
||||||
|
@@ -11211,7 +11235,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- def->data.socket.address = g_steal_pointer(&address);
|
||||||
|
+ def->data.socket.net.address = g_steal_pointer(&address);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def->type != VIR_DOMAIN_NET_TYPE_UDP)
|
||||||
|
@@ -11223,7 +11247,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
"specified with socket interface"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
- if (virStrToLong_i(localport, NULL, 10, &def->data.socket.localport) < 0) {
|
||||||
|
+ if (virStrToLong_i(localport, NULL, 10,
|
||||||
|
+ &def->data.socket.net.localport) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Cannot parse <local> 'port' attribute "
|
||||||
|
"with socket interface"));
|
||||||
|
@@ -11236,7 +11261,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
|
"specified with socket interface"));
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
- def->data.socket.localaddr = g_steal_pointer(&localaddr);
|
||||||
|
+ def->data.socket.net.localaddr = g_steal_pointer(&localaddr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -26219,15 +26244,22 @@ virDomainNetDefFormat(virBufferPtr buf,
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_SERVER:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
||||||
|
+ if (def->data.socket.path) {
|
||||||
|
+ virBufferAsprintf(buf, "<source path='%s'",
|
||||||
|
+ def->data.socket.path);
|
||||||
|
+ sourceLines++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ G_GNUC_FALLTHROUGH;
|
||||||
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_UDP:
|
||||||
|
- if (def->data.socket.address) {
|
||||||
|
+ if (def->data.socket.net.address) {
|
||||||
|
virBufferAsprintf(buf, "<source address='%s' port='%d'",
|
||||||
|
- def->data.socket.address,
|
||||||
|
- def->data.socket.port);
|
||||||
|
+ def->data.socket.net.address,
|
||||||
|
+ def->data.socket.net.port);
|
||||||
|
} else {
|
||||||
|
virBufferAsprintf(buf, "<source port='%d'",
|
||||||
|
- def->data.socket.port);
|
||||||
|
+ def->data.socket.net.port);
|
||||||
|
}
|
||||||
|
sourceLines++;
|
||||||
|
|
||||||
|
@@ -26239,8 +26271,8 @@ virDomainNetDefFormat(virBufferPtr buf,
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<local address='%s' port='%d'/>\n",
|
||||||
|
- def->data.socket.localaddr,
|
||||||
|
- def->data.socket.localport);
|
||||||
|
+ def->data.socket.net.localaddr,
|
||||||
|
+ def->data.socket.net.localport);
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
||||||
|
index 87bc7e8625..3cc0842eed 100644
|
||||||
|
--- a/src/conf/domain_conf.h
|
||||||
|
+++ b/src/conf/domain_conf.h
|
||||||
|
@@ -1042,11 +1042,14 @@ struct _virDomainNetDef {
|
||||||
|
virDomainNetTeamingInfoPtr teaming;
|
||||||
|
union {
|
||||||
|
virDomainChrSourceDefPtr vhostuser;
|
||||||
|
- struct {
|
||||||
|
- char *address;
|
||||||
|
- int port;
|
||||||
|
- char *localaddr;
|
||||||
|
- int localport;
|
||||||
|
+ union {
|
||||||
|
+ struct {
|
||||||
|
+ char *address;
|
||||||
|
+ int port;
|
||||||
|
+ char *localaddr;
|
||||||
|
+ int localport;
|
||||||
|
+ } net;
|
||||||
|
+ char *path;
|
||||||
|
} socket; /* any of NET_CLIENT or NET_SERVER or NET_MCAST */
|
||||||
|
struct {
|
||||||
|
char *name;
|
||||||
|
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
||||||
|
index 5717f7b98d..c1687e582e 100644
|
||||||
|
--- a/src/qemu/qemu_command.c
|
||||||
|
+++ b/src/qemu/qemu_command.c
|
||||||
|
@@ -3639,37 +3639,55 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
||||||
|
- if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
|
||||||
|
- virJSONValueObjectAppendStringPrintf(netprops, "connect", "%s:%d",
|
||||||
|
- net->data.socket.address,
|
||||||
|
- net->data.socket.port) < 0)
|
||||||
|
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (net->data.socket.path != NULL) {
|
||||||
|
+ if (virJSONValueObjectAppendStringPrintf(netprops, "connect", "%s",
|
||||||
|
+ net->data.socket.path) < 0)
|
||||||
|
+ return NULL;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (virJSONValueObjectAppendStringPrintf(netprops, "connect", "%s:%d",
|
||||||
|
+ net->data.socket.net.address,
|
||||||
|
+ net->data.socket.net.port) < 0)
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_SERVER:
|
||||||
|
- if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
|
||||||
|
- virJSONValueObjectAppendStringPrintf(netprops, "listen", "%s:%d",
|
||||||
|
- NULLSTR_EMPTY(net->data.socket.address),
|
||||||
|
- net->data.socket.port) < 0)
|
||||||
|
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (net->data.socket.path != NULL) {
|
||||||
|
+ if (virJSONValueObjectAppendStringPrintf(netprops, "listen", "%s",
|
||||||
|
+ net->data.socket.path) < 0)
|
||||||
|
+ return NULL;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (virJSONValueObjectAppendStringPrintf(netprops, "listen", "%s:%d",
|
||||||
|
+ NULLSTR_EMPTY(net->data.socket.net.address),
|
||||||
|
+ net->data.socket.net.port) < 0)
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
||||||
|
if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
|
||||||
|
virJSONValueObjectAppendStringPrintf(netprops, "mcast", "%s:%d",
|
||||||
|
- net->data.socket.address,
|
||||||
|
- net->data.socket.port) < 0)
|
||||||
|
+ net->data.socket.net.address,
|
||||||
|
+ net->data.socket.net.port) < 0)
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_UDP:
|
||||||
|
if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
|
||||||
|
virJSONValueObjectAppendStringPrintf(netprops, "udp", "%s:%d",
|
||||||
|
- net->data.socket.address,
|
||||||
|
- net->data.socket.port) < 0 ||
|
||||||
|
+ net->data.socket.net.address,
|
||||||
|
+ net->data.socket.net.port) < 0 ||
|
||||||
|
virJSONValueObjectAppendStringPrintf(netprops, "localaddr", "%s:%d",
|
||||||
|
- net->data.socket.localaddr,
|
||||||
|
- net->data.socket.localport) < 0)
|
||||||
|
+ net->data.socket.net.localaddr,
|
||||||
|
+ net->data.socket.net.localport) < 0)
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
||||||
|
index a66354426d..8ca86f9c53 100644
|
||||||
|
--- a/src/qemu/qemu_hotplug.c
|
||||||
|
+++ b/src/qemu/qemu_hotplug.c
|
||||||
|
@@ -3752,9 +3752,11 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
|
||||||
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
||||||
|
case VIR_DOMAIN_NET_TYPE_UDP:
|
||||||
|
- if (STRNEQ_NULLABLE(olddev->data.socket.address,
|
||||||
|
- newdev->data.socket.address) ||
|
||||||
|
- olddev->data.socket.port != newdev->data.socket.port) {
|
||||||
|
+ if (STRNEQ_NULLABLE(olddev->data.socket.path,
|
||||||
|
+ newdev->data.socket.path) ||
|
||||||
|
+ STRNEQ_NULLABLE(olddev->data.socket.net.address,
|
||||||
|
+ newdev->data.socket.net.address) ||
|
||||||
|
+ olddev->data.socket.net.port != newdev->data.socket.net.port) {
|
||||||
|
needReconnect = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
2
passt.c
2
passt.c
|
@ -591,7 +591,7 @@ listen:
|
||||||
info("or directly qemu, patched with:");
|
info("or directly qemu, patched with:");
|
||||||
info(" qemu/0001-net-Allow-also-UNIX-domain-sockets-to-be-used-as-net.patch");
|
info(" qemu/0001-net-Allow-also-UNIX-domain-sockets-to-be-used-as-net.patch");
|
||||||
info("as follows:");
|
info("as follows:");
|
||||||
info("kvm ... -net socket,connect="
|
info(" kvm ... -net socket,connect="
|
||||||
UNIX_SOCK_PATH " -net nic,model=virtio");
|
UNIX_SOCK_PATH " -net nic,model=virtio");
|
||||||
|
|
||||||
c.fd_unix = accept(fd_unix, NULL, NULL);
|
c.fd_unix = accept(fd_unix, NULL, NULL);
|
||||||
|
|
Loading…
Reference in a new issue