Adds a new interface type using UDP sockets, this seems only applicable
to QEMU but have edited tree-wide to support the new interface type.
The interface type required the addition of a "destaddr" (destination
address), this then maps into the following xml and qemu call.
<interface type='udp'>
<mac address='52:54:00:5c:67:56'/>
<source address='127.0.0.1' port='11112'/>
<model type='virtio'/>
<dest address="127.0.0.1' port='22222'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x07' function='0x0'/>
...
QEMU call:
-netdev socket,udp=127.0.0.1:22222,localaddr=127.0.0.1:11112
Notice the xml "source" entry becomes the "localaddr" for the qemu
call.
reference:
http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg00629.html
Signed-off-by: Jonathan Toppins <jtoppins(a)cumulusnetworks.com>
---
docs/formatdomain.html.in | 17 ++++++++++++
src/conf/domain_conf.c | 56 +++++++++++++++++++++++++++++++++++++---
src/conf/domain_conf.h | 3 +++
src/conf/netdev_bandwidth_conf.h | 1 +
src/libxl/libxl_conf.c | 1 +
src/lxc/lxc_controller.c | 1 +
src/lxc/lxc_process.c | 1 +
src/qemu/qemu_command.c | 12 +++++++++
src/qemu/qemu_hotplug.c | 1 +
src/qemu/qemu_interface.c | 2 ++
src/uml/uml_conf.c | 5 ++++
src/xenconfig/xen_sxpr.c | 1 +
tools/virsh-domain.c | 1 +
13 files changed, 99 insertions(+), 3 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c0a265a..95f7f5d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4165,6 +4165,23 @@
</devices>
...</pre>
+ <h5><a name="elementsNICSUDP">UDP unicast
tunnel</a></h5>
+
+ <p>
+ A UDP unicast architecture provides a virtual network which enables
+ connections between Qemu instances using Qemu's UDP infrastructure.</p>
+
+<pre>
+ ...
+ <devices>
+ <interface type='udp'>
+ <mac address='52:54:00:22:c9:42'/>
+ <source address='127.0.0.1' port='11115'/>
+ <dest address='127.0.0.1' port='11116'/>
+ </interface>
+ </devices>
+ ...</pre>
+
<h5><a name="elementsNICSModel">Setting the NIC
model</a></h5>
<pre>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e4114f8..11961ea 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -385,7 +385,8 @@ VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
"bridge",
"internal",
"direct",
- "hostdev")
+ "hostdev",
+ "udp")
VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST,
"default",
@@ -1629,7 +1630,9 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
VIR_FREE(def->data.socket.address);
+ VIR_FREE(def->data.socket.destaddr);
break;
case VIR_DOMAIN_NET_TYPE_NETWORK:
@@ -8398,6 +8401,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
char *script = NULL;
char *address = NULL;
char *port = NULL;
+ char *destaddr = NULL;
+ char *destport = NULL;
char *model = NULL;
char *backend = NULL;
char *txmode = NULL;
@@ -8510,10 +8515,15 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
} else if (!address &&
(def->type == VIR_DOMAIN_NET_TYPE_SERVER ||
def->type == VIR_DOMAIN_NET_TYPE_CLIENT ||
- def->type == VIR_DOMAIN_NET_TYPE_MCAST) &&
+ def->type == VIR_DOMAIN_NET_TYPE_MCAST ||
+ def->type == VIR_DOMAIN_NET_TYPE_UDP) &&
xmlStrEqual(cur->name, BAD_CAST "source")) {
address = virXMLPropString(cur, "address");
port = virXMLPropString(cur, "port");
+ } else if (!destaddr && def->type == VIR_DOMAIN_NET_TYPE_UDP
&&
+ xmlStrEqual(cur->name, BAD_CAST "dest")) {
+ destaddr = virXMLPropString(cur, "address");
+ destport = virXMLPropString(cur, "port");
} else if (xmlStrEqual(cur->name, BAD_CAST "ip")) {
virDomainNetIpDefPtr ip = NULL;
@@ -8751,6 +8761,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
if (port == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No <source> 'port' attribute "
@@ -8766,7 +8777,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (address == NULL) {
if (def->type == VIR_DOMAIN_NET_TYPE_CLIENT ||
- def->type == VIR_DOMAIN_NET_TYPE_MCAST) {
+ def->type == VIR_DOMAIN_NET_TYPE_MCAST ||
+ def->type == VIR_DOMAIN_NET_TYPE_UDP) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No <source> 'address' attribute
"
"specified with socket interface"));
@@ -8776,6 +8788,32 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
def->data.socket.address = address;
address = NULL;
}
+
+ if (def->type != VIR_DOMAIN_NET_TYPE_UDP)
+ break;
+
+ if (destport == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No <dest> 'port' attribute "
+ "specified with socket interface"));
+ goto error;
+ }
+ if (virStrToLong_i(destport, NULL, 10, &def->data.socket.destport) < 0)
{
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <dest> 'port' attribute
"
+ "with socket interface"));
+ goto error;
+ }
+
+ if (destport == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No <dest> 'address' attribute "
+ "specified with socket interface"));
+ goto error;
+ } else {
+ def->data.socket.destaddr = destaddr;
+ address = NULL;
+ }
break;
case VIR_DOMAIN_NET_TYPE_INTERNAL:
@@ -19732,6 +19770,7 @@ virDomainNetDefFormat(virBufferPtr buf,
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
if (def->data.socket.address) {
virBufferAsprintf(buf, "<source address='%s'
port='%d'/>\n",
def->data.socket.address,
def->data.socket.port);
@@ -19739,6 +19778,17 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, "<source port='%d'/>\n",
def->data.socket.port);
}
+
+ if (def->type != VIR_DOMAIN_NET_TYPE_UDP)
+ break;
+
+ if (def->data.socket.destaddr) {
+ virBufferAsprintf(buf, "<dest address='%s'
port='%d'/>\n",
+ def->data.socket.destaddr,
def->data.socket.destport);
+ } else {
+ virBufferAsprintf(buf, "<dest port='%d'/>\n",
+ def->data.socket.destport);
+ }
break;
case VIR_DOMAIN_NET_TYPE_INTERNAL:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 698a4d2..e96fece 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -889,6 +889,7 @@ typedef enum {
VIR_DOMAIN_NET_TYPE_INTERNAL,
VIR_DOMAIN_NET_TYPE_DIRECT,
VIR_DOMAIN_NET_TYPE_HOSTDEV,
+ VIR_DOMAIN_NET_TYPE_UDP,
VIR_DOMAIN_NET_TYPE_LAST
} virDomainNetType;
@@ -991,6 +992,8 @@ struct _virDomainNetDef {
struct {
char *address;
int port;
+ char *destaddr;
+ int destport;
} socket; /* any of NET_CLIENT or NET_SERVER or NET_MCAST */
struct {
char *name;
diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h
index 6cbf4ae..cdeac09 100644
--- a/src/conf/netdev_bandwidth_conf.h
+++ b/src/conf/netdev_bandwidth_conf.h
@@ -53,6 +53,7 @@ static inline bool virNetDevSupportBandwidth(virDomainNetType type)
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index e845759..a76ad5a 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1177,6 +1177,7 @@ libxlMakeNic(virDomainDefPtr def,
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 110a556..03d6311 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -382,6 +382,7 @@ static int virLXCControllerGetNICIndexes(virLXCControllerPtr ctrl)
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index e99b039..04fbb0a 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -429,6 +429,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_LAST:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index eb00f0f..2dac923 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5354,6 +5354,17 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
type_sep = ',';
break;
+ case VIR_DOMAIN_NET_TYPE_UDP:
+ virBufferAsprintf(&buf, "socket%cudp=%s:%d%clocaladdr=%s:%d",
+ type_sep,
+ net->data.socket.destaddr,
+ net->data.socket.destport,
+ type_sep,
+ net->data.socket.address,
+ net->data.socket.port);
+ type_sep = ',';
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
default:
virBufferAddLit(&buf, "user");
@@ -8416,6 +8427,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1ea397f..e6c20e9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2394,6 +2394,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
case VIR_DOMAIN_NET_TYPE_SERVER:
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) {
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index 01226ac..4d55e4d 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -100,6 +100,7 @@ qemuInterfaceStartDevice(virDomainNetDefPtr net)
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
@@ -187,6 +188,7 @@ qemuInterfaceStopDevice(virDomainNetDefPtr net)
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c
index 90deb2a..afc0375 100644
--- a/src/uml/uml_conf.c
+++ b/src/uml/uml_conf.c
@@ -195,6 +195,11 @@ umlBuildCommandLineNet(virConnectPtr conn,
_("TCP client networking type not supported"));
goto error;
+ case VIR_DOMAIN_NET_TYPE_UDP:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("UDP networking type not supported"));
+ goto error;
+
case VIR_DOMAIN_NET_TYPE_MCAST:
/* ethNNN=tuntap,macaddr,ipaddr,port */
virBufferAddLit(&buf, "mcast");
diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c
index 05e938a..1d43ec1 100644
--- a/src/xenconfig/xen_sxpr.c
+++ b/src/xenconfig/xen_sxpr.c
@@ -1962,6 +1962,7 @@ xenFormatSxprNet(virConnectPtr conn,
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 4988ba2..fc23ee1 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -993,6 +993,7 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd)
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
--
1.9.1