diff --git a/README.md b/README.md
index 48f4f6d..8ae54ec 100644
--- a/README.md
+++ b/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
replacement for Slirp.
+![overview diagram](/builds/passt_overview.png)
+
- [General idea](#general-idea)
- [Non-functional Targets](#non-functional-targets)
- [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
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,
-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
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
+* 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:
+
+
+
+
+
+
+
+
* and that's it, you should now have TCP connections, UDP, and ICMP/ICMPv6
echo working from/to the guest for IPv4 and IPv6
diff --git a/libvirt/0001-conf-Introduce-support-for-UNIX-domain-socket-as-qem.patch b/libvirt/0001-conf-Introduce-support-for-UNIX-domain-socket-as-qem.patch
new file mode 100644
index 0000000..c0e3337
--- /dev/null
+++ b/libvirt/0001-conf-Introduce-support-for-UNIX-domain-socket-as-qem.patch
@@ -0,0 +1,423 @@
+From 62e95cb4b5708eca7860139dffef22e65b29514c Mon Sep 17 00:00:00 2001
+From: Stefano Brivio
+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
+---
+ 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.
+
+ ...
+
+-:anchor:``
++:anchor:``
+
+-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.
+
+ ...
+
++Named UNIX domain sockets can be specified as follows:
++:since:`Since 7.2.0, qemu`
++
++::
++
++ ...
++
++
++
++
++
++ ...
++
++
++
++
++
++ ...
++
+ :anchor:``
+
+ 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 @@
+
+
+
+-
+- mcast
+- client
+-
++ mcast
+
+
+
+@@ -3143,6 +3140,30 @@
+
+
+
++
++
++ client
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+ udp
+@@ -3174,14 +3195,21 @@
+
+
+
+-
+-
+-
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+-
+-
+-
+-
++
+
+
+
+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,
+ " "), 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",
++ _("