diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 7edeca8a61..6a6bdbc4f2 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2341,6 +2341,15 @@
<char>/dev/input/event3</char>
</source>
</hostdev>
+...
+
+
+...
+<hostdev mode='capabilities' type='net'>
+ <source>
+ <interface>eth0</interface>
+ </source>
+</hostdev>
...
@@ -2349,13 +2358,15 @@
The hostdev
element is the main container for describing
host devices. For block/character device passthrough mode
is
always "capabilities" and type
is "block" for a block
- device and "char" for a character device.
+ device, "char" for a character device and "net" for a host network
+ interface.
source
The source element describes the device as seen from the host.
For block devices, the path to the block device in the host
OS is provided in the nested "block" element, while for character
- devices the "char" element is used
+ devices the "char" element is used. For network interfaces, the
+ name of the interface is provided in the "interface" element.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 32abd4f90f..7b3d6376af 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3002,6 +3002,9 @@
+
+
+
@@ -3062,6 +3065,17 @@
+
+
+ net
+
+
+
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 79e3b2ef64..03e5740935 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -582,7 +582,8 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST,
VIR_ENUM_IMPL(virDomainHostdevCaps, VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST,
"storage",
- "misc")
+ "misc",
+ "net")
VIR_ENUM_IMPL(virDomainPciRombarMode,
VIR_DOMAIN_PCI_ROMBAR_LAST,
@@ -1611,6 +1612,9 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
VIR_FREE(def->source.caps.u.misc.chardev);
break;
+ case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
+ VIR_FREE(def->source.caps.u.net.iface);
+ break;
}
}
}
@@ -3675,6 +3679,14 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
goto error;
}
break;
+ case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
+ if (!(def->source.caps.u.net.iface =
+ virXPathString("string(./source/interface[1])", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Missing element in hostdev net device"));
+ goto error;
+ }
+ break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("address type='%s' not supported in hostdev interfaces"),
@@ -8881,6 +8893,14 @@ virDomainHostdevMatchCapsMisc(virDomainHostdevDefPtr a,
b->source.caps.u.misc.chardev);
}
+static int
+virDomainHostdevMatchCapsNet(virDomainHostdevDefPtr a,
+ virDomainHostdevDefPtr b)
+{
+ return STREQ_NULLABLE(a->source.caps.u.net.iface,
+ b->source.caps.u.net.iface);
+}
+
static int
virDomainHostdevMatchCaps(virDomainHostdevDefPtr a,
@@ -8894,6 +8914,8 @@ virDomainHostdevMatchCaps(virDomainHostdevDefPtr a,
return virDomainHostdevMatchCapsStorage(a, b);
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
return virDomainHostdevMatchCapsMisc(a, b);
+ case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
+ return virDomainHostdevMatchCapsNet(a, b);
}
return 0;
}
@@ -13530,6 +13552,10 @@ virDomainHostdevDefFormatCaps(virBufferPtr buf,
virBufferEscapeString(buf, "%s\n",
def->source.caps.u.misc.chardev);
break;
+ case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
+ virBufferEscapeString(buf, "%s\n",
+ def->source.caps.u.net.iface);
+ break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected hostdev type %d"),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a24ebc7096..ec823e2d72 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -407,6 +407,7 @@ struct _virDomainHostdevSubsys {
enum virDomainHostdevCapsType {
VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE,
VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC,
+ VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET,
VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST
};
@@ -422,6 +423,9 @@ struct _virDomainHostdevCaps {
struct {
char *chardev;
} misc;
+ struct {
+ char *iface;
+ } net;
} u;
};