diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4be751461d..c00ace7d9c 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 677ec77724..60453225d6 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 fd1aac6485..ad3f590c91 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 ea43c03d41..031c5241f0 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 dcd070d2ad..e34e6ad372 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 867a9c7661..cdc4d25700 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 1f14a964a2..819b645df7 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 d5dd8480db..db7243eef5 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 28a58ad8f8..a0705a8322 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 f5ba337fc9..78cf2c1ba4 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 0d281ec7ed..8883aa89cc 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 0000000000..9bdcb88ac6 --- /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 0000000000..bff5278600 --- /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 f784b90c69..ec679e72ee 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 0000000000..122378a8f0 --- /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 0000000000..d21a5a395b --- /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 + + + + +
+ + + +
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +