diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4be751461df9ed6f65f3d6ef2bbf5a0aeeb3f9ac..c00ace7d9c327209911661a68d3172a5c0bf54a4 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3178,6 +3178,9 @@
+
+
+
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 677ec77724475b04c96cbbb744c4fe1aa2845410..60453225d62c79068c653bd5809c3e26e8015762 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -332,6 +332,9 @@
+
+
+
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index fd1aac6485a52cd37e1cb444d7bdb5ed29507dc3..ad3f590c9131ff99bf8b9cdf7813f502d78e565a 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -280,4 +280,15 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/schemas/networkport.rng b/docs/schemas/networkport.rng
index ea43c03d4111a31e3bb3e440a1bf33346369095d..031c5241f0da118234bbadbbde9bd7b14fcdcf6c 100644
--- a/docs/schemas/networkport.rng
+++ b/docs/schemas/networkport.rng
@@ -32,6 +32,9 @@
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index dcd070d2adfaf3666be8874c852bfa9a965b480e..e34e6ad3726430cce9fa15a67a19e87116d8bb20 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11534,6 +11534,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &actual->vlan) < 0)
goto error;
+ if (virNetworkPortOptionsParseXML(ctxt, &actual->isolatedPort) < 0)
+ goto error;
+
*def = g_steal_pointer(&actual);
ret = 0;
error:
@@ -12430,6 +12433,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
goto error;
}
+ if (virNetworkPortOptionsParseXML(ctxt, &def->isolatedPort) < 0)
+ goto error;
+
cleanup:
virDomainActualNetDefFree(actual);
virHashFree(filterparams);
@@ -25539,6 +25545,7 @@ virDomainActualNetDefContentsFormat(virBufferPtr buf,
return -1;
if (virNetDevBandwidthFormat(virDomainNetGetActualBandwidth(def), 0, buf) < 0)
return -1;
+ virNetworkPortOptionsFormat(virDomainNetGetActualPortOptionsIsolated(def), buf);
return 0;
}
@@ -25915,6 +25922,7 @@ virDomainNetDefFormat(virBufferPtr buf,
return -1;
if (virNetDevBandwidthFormat(def->bandwidth, 0, buf) < 0)
return -1;
+ virNetworkPortOptionsFormat(def->isolatedPort, buf);
/* ONLY for internal status storage - format the ActualNetDef
* as a subelement of so that no persistent config
@@ -29992,6 +30000,17 @@ virDomainNetGetActualVlan(const virDomainNetDef *iface)
}
+virTristateBool
+virDomainNetGetActualPortOptionsIsolated(const virDomainNetDef *iface)
+{
+ if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
+ iface->data.network.actual) {
+ return iface->data.network.actual->isolatedPort;
+ }
+ return iface->isolatedPort;
+}
+
+
bool
virDomainNetGetActualTrustGuestRxFilters(const virDomainNetDef *iface)
{
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 867a9c76617bd1ad765714a94e9695e1e7b4f167..cdc4d2570025640c7cfcd174566f473eeb41c63a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -928,6 +928,7 @@ struct _virDomainActualNetDef {
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
int trustGuestRxFilters; /* enum virTristateBool */
+ virTristateBool isolatedPort;
unsigned int class_id; /* class ID for bandwidth 'floor' */
};
@@ -1032,6 +1033,7 @@ struct _virDomainNetDef {
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
int trustGuestRxFilters; /* enum virTristateBool */
+ virTristateBool isolatedPort;
int linkstate;
unsigned int mtu;
virNetDevCoalescePtr coalesce;
@@ -3239,6 +3241,8 @@ const virNetDevBandwidth *
virDomainNetGetActualBandwidth(const virDomainNetDef *iface);
const virNetDevVlan *virDomainNetGetActualVlan(const virDomainNetDef *iface);
bool virDomainNetGetActualTrustGuestRxFilters(const virDomainNetDef *iface);
+virTristateBool
+virDomainNetGetActualPortOptionsIsolated(const virDomainNetDef *iface);
const char *virDomainNetGetModelString(const virDomainNetDef *net);
int virDomainNetSetModelString(virDomainNetDefPtr et,
const char *model);
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 1f14a964a27d9be95b9cafe33f238c144070a2e9..819b645df7c85724e22d389de28058024ac598a2 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1172,6 +1172,26 @@ virNetworkIPDefParseXML(const char *networkName,
}
+int
+virNetworkPortOptionsParseXML(xmlXPathContextPtr ctxt,
+ virTristateBool *isolatedPort)
+{
+ g_autofree char *str = NULL;
+ int tmp = VIR_TRISTATE_BOOL_ABSENT;
+
+ if ((str = virXPathString("string(./port/@isolated)", ctxt))) {
+ if ((tmp = virTristateBoolTypeFromString(str)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unknown port isolated value '%s'"), str);
+ return -1;
+ }
+ }
+
+ *isolatedPort = tmp;
+ return 0;
+}
+
+
static int
virNetworkPortGroupParseXML(virPortGroupDefPtr def,
xmlNodePtr node,
@@ -1725,6 +1745,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
goto error;
+ if (virNetworkPortOptionsParseXML(ctxt, &def->isolatedPort) < 0)
+ goto error;
+
/* Parse bridge information */
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
def->bridgeZone = virXPathString("string(./bridge[1]/@zone)", ctxt);
@@ -2331,6 +2354,14 @@ virNetworkIPDefFormat(virBufferPtr buf,
return 0;
}
+void
+virNetworkPortOptionsFormat(virTristateBool isolatedPort,
+ virBufferPtr buf)
+{
+ if (isolatedPort != VIR_TRISTATE_BOOL_ABSENT)
+ virBufferAsprintf(buf, "\n",
+ virTristateBoolTypeToString(isolatedPort));
+}
static int
virPortGroupDefFormat(virBufferPtr buf,
@@ -2608,6 +2639,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
return -1;
if (virNetDevBandwidthFormat(def->bandwidth, 0, buf) < 0)
return -1;
+ virNetworkPortOptionsFormat(def->isolatedPort, buf);
for (i = 0; i < def->nips; i++) {
if (virNetworkIPDefFormat(buf, &def->ips[i]) < 0)
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index d5dd8480db36d1da02473efb64c0fbe816ce6614..db7243eef52e59933ce12c5688cd39052339a8bf 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -272,6 +272,7 @@ struct _virNetworkDef {
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
int trustGuestRxFilters; /* enum virTristateBool */
+ virTristateBool isolatedPort;
/* Application-specific custom metadata */
xmlNodePtr metadata;
@@ -377,6 +378,14 @@ virNetworkConfigFile(const char *dir,
void
virNetworkSetBridgeMacAddr(virNetworkDefPtr def);
+int
+virNetworkPortOptionsParseXML(xmlXPathContextPtr ctxt,
+ virTristateBool *isolatedPort);
+
+void
+virNetworkPortOptionsFormat(virTristateBool isolatedPort,
+ virBufferPtr buf);
+
VIR_ENUM_DECL(virNetworkForward);
#define VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE \
diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c
index 28a58ad8f84b553d25e7055eba915a1ebddd2511..a0705a83226b34e4336cebd80c88b261247b5c64 100644
--- a/src/conf/virnetworkportdef.c
+++ b/src/conf/virnetworkportdef.c
@@ -161,6 +161,8 @@ virNetworkPortDefParseXML(xmlXPathContextPtr ctxt)
if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
return NULL;
+ if (virNetworkPortOptionsParseXML(ctxt, &def->isolatedPort) < 0)
+ return NULL;
trustGuestRxFilters
= virXPathString("string(./rxfilters/@trustGuest)", ctxt);
@@ -360,6 +362,7 @@ virNetworkPortDefFormatBuf(virBufferPtr buf,
virNetDevBandwidthFormat(def->bandwidth, def->class_id, buf);
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
return -1;
+ virNetworkPortOptionsFormat(def->isolatedPort, buf);
if (def->trustGuestRxFilters)
virBufferAsprintf(buf, "\n",
virTristateBoolTypeToString(def->trustGuestRxFilters));
diff --git a/src/conf/virnetworkportdef.h b/src/conf/virnetworkportdef.h
index f5ba337fc9d801d8136b31cdd11a5e0d1141ab02..78cf2c1ba4bc9bd391c71f94d11a49816b54729a 100644
--- a/src/conf/virnetworkportdef.h
+++ b/src/conf/virnetworkportdef.h
@@ -60,6 +60,7 @@ struct _virNetworkPortDef {
unsigned int class_id; /* class ID for bandwidth 'floor' */
virNetDevVlan vlan;
int trustGuestRxFilters; /* enum virTristateBool */
+ virTristateBool isolatedPort;
int plugtype; /* virNetworkPortPlugType */
union {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0d281ec7ed192fb2759ee4c6beb0a95a1530f358..8883aa89cc1f671af80a3c06c076a2ac689144e9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -513,6 +513,7 @@ virDomainNetGetActualBridgeName;
virDomainNetGetActualDirectDev;
virDomainNetGetActualDirectMode;
virDomainNetGetActualHostdev;
+virDomainNetGetActualPortOptionsIsolated;
virDomainNetGetActualTrustGuestRxFilters;
virDomainNetGetActualType;
virDomainNetGetActualVirtPortProfile;
diff --git a/tests/networkxml2xmlin/isolated-ports.xml b/tests/networkxml2xmlin/isolated-ports.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9bdcb88ac617a4139f23227e0a0e428c19952eea
--- /dev/null
+++ b/tests/networkxml2xmlin/isolated-ports.xml
@@ -0,0 +1,7 @@
+
+ port-isolation-test
+ 81ff0d90-c91e-6742-64da-4a736edb9a9b
+
+
+
+
diff --git a/tests/networkxml2xmlout/isolated-ports.xml b/tests/networkxml2xmlout/isolated-ports.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bff52786008c4a9fe7dd43fbe9bf7f23f1e79ae1
--- /dev/null
+++ b/tests/networkxml2xmlout/isolated-ports.xml
@@ -0,0 +1,7 @@
+
+ port-isolation-test
+ 81ff0d90-c91e-6742-64da-4a736edb9a9b
+
+
+
+
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index f784b90c69096b92281d10c39a4224db6075f516..ec679e72ee552ca15788b369e82874d9d87d6c36 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -160,6 +160,7 @@ mymain(void)
DO_TEST("metadata");
DO_TEST("set-mtu");
DO_TEST("dnsmasq-options");
+ DO_TEST("isolated-ports");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/tests/qemuxml2argvdata/net-isolated-port.xml b/tests/qemuxml2argvdata/net-isolated-port.xml
new file mode 100644
index 0000000000000000000000000000000000000000..122378a8f0054106ab89733f5f87eaa067d7f805
--- /dev/null
+++ b/tests/qemuxml2argvdata/net-isolated-port.xml
@@ -0,0 +1,34 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/net-isolated-port.x86_64-latest.xml b/tests/qemuxml2xmloutdata/net-isolated-port.x86_64-latest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d21a5a395b59c17d244968162bf1757deebab32e
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/net-isolated-port.x86_64-latest.xml
@@ -0,0 +1,63 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ qemu64
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index daf9b53ce8626239ee0b38a8964f3f1e90638027..c29dd5053d55a0c7b8b94e6ae309e5695d1f0676 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -463,6 +463,7 @@ mymain(void)
DO_TEST("net-virtio-teaming-network",
QEMU_CAPS_VIRTIO_NET_FAILOVER,
QEMU_CAPS_DEVICE_VFIO_PCI);
+ DO_TEST_CAPS_LATEST("net-isolated-port");
DO_TEST("net-hostdev", NONE);
DO_TEST("net-hostdev-bootorder", NONE);
DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI);