diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bf9d00094c..a541e7bca6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6022,159 +6022,6 @@ virDomainDefHasUSB(const virDomainDef *def) } - -static int -virDomainNetDefValidatePortOptions(const char *macstr, - virDomainNetType type, - const virNetDevVPortProfile *vport, - virTristateBool isolatedPort) -{ - /* - * This function can be called for either a config interface - * object (NetDef) or a runtime interface object (ActualNetDef), - * by calling it with either, e.g., the "type" (what is in the - * config) or the "actualType" (what is determined at runtime by - * acquiring a port from the network). - */ - /* - * port isolation can only be set for an interface that is - * connected to a Linux host bridge (either a libvirt-managed - * network, or plain type='bridge') - */ - if (isolatedPort == VIR_TRISTATE_BOOL_YES) { - if (!(type == VIR_DOMAIN_NET_TYPE_NETWORK || - type == VIR_DOMAIN_NET_TYPE_BRIDGE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("interface %s - is not supported for network interfaces with type='%s'"), - macstr, virDomainNetTypeToString(type)); - return -1; - } - /* - * also not allowed for anything with setting - * (openvswitch or 802.11Qb[gh]) - */ - if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("interface %s - is not supported for network interfaces with virtualport type='%s'"), - macstr, virNetDevVPortTypeToString(vport->virtPortType)); - return -1; - } - } - return 0; -} - - -int -virDomainActualNetDefValidate(const virDomainNetDef *net) -{ - /* Unlike virDomainNetDefValidate(), which is a static function - * called internally to this file, virDomainActualNetDefValidate() - * is a public function that can be called from a hypervisor after - * it has completely setup the NetDef for use by a domain, - * including possibly allocating a port from the network driver - * (which could change the effective/"actual" type of the NetDef, - * thus changing what should/shouldn't be allowed by validation). - * - * This function should contain validations not specific to a - * particular hypervisor (e.g. whether or not specifying bandwidth - * is allowed for a type of interface), but *not* - * hypervisor-specific things. - */ - char macstr[VIR_MAC_STRING_BUFLEN]; - virDomainNetType actualType = virDomainNetGetActualType(net); - const virNetDevVPortProfile *vport = virDomainNetGetActualVirtPortProfile(net); - const virNetDevBandwidth *bandwidth = virDomainNetGetActualBandwidth(net); - - virMacAddrFormat(&net->mac, macstr); - - if (virDomainNetGetActualVlan(net)) { - /* vlan configuration via libvirt is only supported for PCI - * Passthrough SR-IOV devices (hostdev or macvtap passthru - * mode) and openvswitch bridges. Otherwise log an error and - * fail - */ - if (!(actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV || - (actualType == VIR_DOMAIN_NET_TYPE_DIRECT && - virDomainNetGetActualDirectMode(net) == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) || - (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE && - vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("interface %s - vlan tag not supported for this connection type"), - macstr); - return -1; - } - } - - /* bandwidth configuration via libvirt is not supported for - * hostdev network devices - */ - if (bandwidth && actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("interface %s - bandwidth settings are not supported " - "for hostdev interfaces"), - macstr); - return -1; - } - - if (virDomainNetDefValidatePortOptions(macstr, actualType, vport, - virDomainNetGetActualPortOptionsIsolated(net)) < 0) { - return -1; - } - - return 0; -} - - -static int -virDomainNetDefValidate(const virDomainNetDef *net) -{ - char macstr[VIR_MAC_STRING_BUFLEN]; - - virMacAddrFormat(&net->mac, macstr); - - if ((net->hostIP.nroutes || net->hostIP.nips) && - net->type != VIR_DOMAIN_NET_TYPE_ETHERNET) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Invalid attempt to set network interface " - "host-side IP route and/or address info on " - "interface of type '%s'. This is only supported " - "on interfaces of type 'ethernet'"), - virDomainNetTypeToString(net->type)); - return -1; - } - if (net->managed_tap == VIR_TRISTATE_BOOL_NO && - net->type != VIR_DOMAIN_NET_TYPE_ETHERNET) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unmanaged target dev is not supported on " - "interfaces of type '%s'"), - virDomainNetTypeToString(net->type)); - return -1; - } - - if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) { - if (!net->teaming.persistent) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("teaming persistent attribute must be set if teaming type is 'transient'")); - return -1; - } - } else { - if (net->teaming.persistent) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("teaming persistent attribute not allowed if teaming type is '%s'"), - virDomainNetTeamingTypeToString(net->teaming.type)); - return -1; - } - } - - if (virDomainNetDefValidatePortOptions(macstr, net->type, net->virtPortProfile, - net->isolatedPort) < 0) { - return -1; - } - - return 0; -} - - static int virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1c1533ed2f..e35c4206df 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3024,9 +3024,6 @@ bool virDomainDefHasUSB(const virDomainDef *def); bool virDomainDeviceAliasIsUserAlias(const char *aliasStr); -int -virDomainActualNetDefValidate(const virDomainNetDef *net); - static inline bool virDomainObjIsActive(virDomainObjPtr dom) { diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index a608e84edb..e90c405a4b 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1169,3 +1169,155 @@ virDomainDefValidate(virDomainDefPtr def, return 0; } + + +static int +virDomainNetDefValidatePortOptions(const char *macstr, + virDomainNetType type, + const virNetDevVPortProfile *vport, + virTristateBool isolatedPort) +{ + /* + * This function can be called for either a config interface + * object (NetDef) or a runtime interface object (ActualNetDef), + * by calling it with either, e.g., the "type" (what is in the + * config) or the "actualType" (what is determined at runtime by + * acquiring a port from the network). + */ + /* + * port isolation can only be set for an interface that is + * connected to a Linux host bridge (either a libvirt-managed + * network, or plain type='bridge') + */ + if (isolatedPort == VIR_TRISTATE_BOOL_YES) { + if (!(type == VIR_DOMAIN_NET_TYPE_NETWORK || + type == VIR_DOMAIN_NET_TYPE_BRIDGE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("interface %s - is not supported for network interfaces with type='%s'"), + macstr, virDomainNetTypeToString(type)); + return -1; + } + /* + * also not allowed for anything with setting + * (openvswitch or 802.11Qb[gh]) + */ + if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("interface %s - is not supported for network interfaces with virtualport type='%s'"), + macstr, virNetDevVPortTypeToString(vport->virtPortType)); + return -1; + } + } + return 0; +} + + +int +virDomainActualNetDefValidate(const virDomainNetDef *net) +{ + /* Unlike virDomainNetDefValidate(), which is a static function + * called internally to this file, virDomainActualNetDefValidate() + * is a public function that can be called from a hypervisor after + * it has completely setup the NetDef for use by a domain, + * including possibly allocating a port from the network driver + * (which could change the effective/"actual" type of the NetDef, + * thus changing what should/shouldn't be allowed by validation). + * + * This function should contain validations not specific to a + * particular hypervisor (e.g. whether or not specifying bandwidth + * is allowed for a type of interface), but *not* + * hypervisor-specific things. + */ + char macstr[VIR_MAC_STRING_BUFLEN]; + virDomainNetType actualType = virDomainNetGetActualType(net); + const virNetDevVPortProfile *vport = virDomainNetGetActualVirtPortProfile(net); + const virNetDevBandwidth *bandwidth = virDomainNetGetActualBandwidth(net); + + virMacAddrFormat(&net->mac, macstr); + + if (virDomainNetGetActualVlan(net)) { + /* vlan configuration via libvirt is only supported for PCI + * Passthrough SR-IOV devices (hostdev or macvtap passthru + * mode) and openvswitch bridges. Otherwise log an error and + * fail + */ + if (!(actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV || + (actualType == VIR_DOMAIN_NET_TYPE_DIRECT && + virDomainNetGetActualDirectMode(net) == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) || + (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE && + vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("interface %s - vlan tag not supported for this connection type"), + macstr); + return -1; + } + } + + /* bandwidth configuration via libvirt is not supported for + * hostdev network devices + */ + if (bandwidth && actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("interface %s - bandwidth settings are not supported " + "for hostdev interfaces"), + macstr); + return -1; + } + + if (virDomainNetDefValidatePortOptions(macstr, actualType, vport, + virDomainNetGetActualPortOptionsIsolated(net)) < 0) { + return -1; + } + + return 0; +} + + +int +virDomainNetDefValidate(const virDomainNetDef *net) +{ + char macstr[VIR_MAC_STRING_BUFLEN]; + + virMacAddrFormat(&net->mac, macstr); + + if ((net->hostIP.nroutes || net->hostIP.nips) && + net->type != VIR_DOMAIN_NET_TYPE_ETHERNET) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid attempt to set network interface " + "host-side IP route and/or address info on " + "interface of type '%s'. This is only supported " + "on interfaces of type 'ethernet'"), + virDomainNetTypeToString(net->type)); + return -1; + } + if (net->managed_tap == VIR_TRISTATE_BOOL_NO && + net->type != VIR_DOMAIN_NET_TYPE_ETHERNET) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unmanaged target dev is not supported on " + "interfaces of type '%s'"), + virDomainNetTypeToString(net->type)); + return -1; + } + + if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) { + if (!net->teaming.persistent) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("teaming persistent attribute must be set if teaming type is 'transient'")); + return -1; + } + } else { + if (net->teaming.persistent) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("teaming persistent attribute not allowed if teaming type is '%s'"), + virDomainNetTeamingTypeToString(net->teaming.type)); + return -1; + } + } + + if (virDomainNetDefValidatePortOptions(macstr, net->type, net->virtPortProfile, + net->isolatedPort) < 0) { + return -1; + } + + return 0; +} diff --git a/src/conf/domain_validate.h b/src/conf/domain_validate.h index 530bbb1bf3..e0dfd3186f 100644 --- a/src/conf/domain_validate.h +++ b/src/conf/domain_validate.h @@ -45,3 +45,5 @@ int virDomainDefValidate(virDomainDefPtr def, unsigned int parseFlags, virDomainXMLOptionPtr xmlopt, void *parseOpaque); +int virDomainActualNetDefValidate(const virDomainNetDef *net); +int virDomainNetDefValidate(const virDomainNetDef *net); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3cbc336bad..d0e548b0a3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -226,7 +226,6 @@ virDiskNameParse; virDiskNameToBusDeviceIndex; virDiskNameToIndex; virDomainActualNetDefFree; -virDomainActualNetDefValidate; virDomainAudioTypeTypeFromString; virDomainAudioTypeTypeToString; virDomainBlockedReasonTypeFromString; @@ -743,6 +742,7 @@ virDomainConfVMNWFilterTeardown; # conf/domain_validate.h +virDomainActualNetDefValidate; virDomainDefValidate; virDomainDeviceValidateAliasForHotplug; diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 3669b358f6..ab838b317c 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -35,6 +35,7 @@ #include "locking/domain_lock.h" #include "xen_common.h" #include "driver.h" +#include "domain_validate.h" #define VIR_FROM_THIS VIR_FROM_LIBXL diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 6af274cb1b..c2563ef872 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -55,6 +55,7 @@ #include "virnetdevtap.h" #include "cpu/cpu.h" #include "virutil.h" +#include "domain_validate.h" #define VIR_FROM_THIS VIR_FROM_LIBXL diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index b1295e71da..88d3890de7 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -58,6 +58,7 @@ #include "domain_cgroup.h" #include "domain_driver.h" #include "domain_nwfilter.h" +#include "domain_validate.h" #include "virinitctl.h" #include "virnetdev.h" #include "virnetdevtap.h" diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 0f818e2ee0..937e9a3fc1 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -42,6 +42,7 @@ #include "domain_nwfilter.h" #include "viralloc.h" #include "domain_audit.h" +#include "domain_validate.h" #include "virerror.h" #include "virlog.h" #include "vircommand.h" diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 766f76020c..bfb6e23942 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -48,6 +48,7 @@ #include "domain_capabilities.h" #include "domain_driver.h" #include "domain_event.h" +#include "domain_validate.h" #include "virtime.h" #include "virnetdevopenvswitch.h" #include "virstoragefile.h"