Convert the virDomainNetDef object into a virNetworkPortDef object at the start of networkAllocateActualDevice. This largely decouples the method impl from the domain object type. Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- src/network/bridge_driver.c | 222 +++++++++++++++--------------------- 1 file changed, 91 insertions(+), 131 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 8d1a1b95d2..594574db8c 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -68,6 +68,7 @@ #include "network_event.h" #include "virhook.h" #include "virjson.h" +#include "conf/virnetworkportdef.h" #define VIR_FROM_THIS VIR_FROM_NETWORK #define MAX_BRIDGE_ID 256 @@ -4447,17 +4448,16 @@ networkAllocateActualDevice(virNetworkPtr net, virDomainNetDefPtr iface) { virNetworkDriverStatePtr driver = networkGetDriver(); - virDomainNetType actualType = iface->type; virNetworkObjPtr obj = NULL; virNetworkDefPtr netdef = NULL; - virNetDevBandwidthPtr bandwidth = NULL; virPortGroupDefPtr portgroup = NULL; - virNetDevVPortProfilePtr virtport = iface->virtPortProfile; - virNetDevVlanPtr vlan = NULL; virNetworkForwardIfDefPtr dev = NULL; size_t i; int ret = -1; + virNetDevVPortProfilePtr portprofile = NULL; + virNetworkPortDefPtr port = NULL; + VIR_DEBUG("Allocating port from net %s", net->name); obj = virNetworkObjFindByName(driver->networks, net->name); if (!obj) { virReportError(VIR_ERR_NO_NETWORK, @@ -4472,9 +4472,6 @@ networkAllocateActualDevice(virNetworkPtr net, goto error; } - virDomainActualNetDefFree(iface->data.network.actual); - iface->data.network.actual = NULL; - netdef = virNetworkObjGetDef(obj); if (!virNetworkObjIsActive(obj)) { @@ -4484,99 +4481,84 @@ networkAllocateActualDevice(virNetworkPtr net, goto error; } - if (VIR_ALLOC(iface->data.network.actual) < 0) + if (!(port = virDomainNetDefToNetworkPort(dom, iface))) goto error; + VIR_DEBUG("Interface port group %s", port->group); /* portgroup can be present for any type of network, in particular * for bandwidth information, so we need to check for that and * fill it in appropriately for all forward types. */ - portgroup = virPortGroupFindByName(netdef, iface->data.network.portgroup); - - /* If there is already interface-specific bandwidth, just use that - * (already in NetDef). Otherwise, if there is bandwidth info in - * the portgroup, fill that into the ActualDef. - */ - - if (iface->bandwidth) - bandwidth = iface->bandwidth; - else if (portgroup && portgroup->bandwidth) - bandwidth = portgroup->bandwidth; + portgroup = virPortGroupFindByName(netdef, port->group); - if (bandwidth && virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth, - bandwidth) < 0) - goto error; + if (!port->bandwidth) { + if (portgroup && portgroup->bandwidth && + virNetDevBandwidthCopy(&port->bandwidth, + portgroup->bandwidth) < 0) + goto error; + } - /* copy appropriate vlan info to actualNet */ - if (iface->vlan.nTags > 0) - vlan = &iface->vlan; - else if (portgroup && portgroup->vlan.nTags > 0) - vlan = &portgroup->vlan; - else if (netdef->vlan.nTags > 0) - vlan = &netdef->vlan; + if (port->vlan.nTags == 0) { + virNetDevVlanPtr vlan = NULL; + if (portgroup && portgroup->vlan.nTags > 0) + vlan = &portgroup->vlan; + else if (netdef->vlan.nTags > 0) + vlan = &netdef->vlan; - if (vlan && virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0) - goto error; + if (vlan && virNetDevVlanCopy(&port->vlan, vlan) < 0) + goto error; + } - if (iface->trustGuestRxFilters) - iface->data.network.actual->trustGuestRxFilters - = iface->trustGuestRxFilters; - else if (portgroup && portgroup->trustGuestRxFilters) - iface->data.network.actual->trustGuestRxFilters - = portgroup->trustGuestRxFilters; - else if (netdef->trustGuestRxFilters) - iface->data.network.actual->trustGuestRxFilters - = netdef->trustGuestRxFilters; + if (!port->trustGuestRxFilters) { + if (portgroup && portgroup->trustGuestRxFilters) + port->trustGuestRxFilters = portgroup->trustGuestRxFilters; + else if (netdef->trustGuestRxFilters) + port->trustGuestRxFilters = netdef->trustGuestRxFilters; + } /* merge virtualports from interface, network, and portgroup to * arrive at actual virtualport to use */ - if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile, - iface->virtPortProfile, + if (virNetDevVPortProfileMerge3(&portprofile, + port->virtPortProfile, netdef->virtPortProfile, portgroup ? portgroup->virtPortProfile : NULL) < 0) { - goto error; + goto error; + } + if (portprofile) { + VIR_FREE(port->virtPortProfile); + port->virtPortProfile = portprofile; } - virtport = iface->data.network.actual->virtPortProfile; + VIR_DEBUG("Processing forward type %d", netdef->forward.type); switch ((virNetworkForwardType) netdef->forward.type) { case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: - iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE; + port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE; - /* we also store the bridge device and macTableManager settings - * in iface->data.network.actual->data.bridge for later use - * after the domain's tap device is created (to attach to the - * bridge and set flood/learning mode on the tap device) - */ - if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname, - netdef->bridge) < 0) + if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0) goto error; - iface->data.network.actual->data.bridge.macTableManager - = netdef->macTableManager; + port->plug.bridge.macTableManager = netdef->macTableManager; - if (virtport) { + if (port->virtPortProfile) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("<virtualport type='%s'> not supported for network " "'%s' which uses IP forwarding"), - virNetDevVPortTypeToString(virtport->virtPortType), + virNetDevVPortTypeToString(port->virtPortProfile->virtPortType), netdef->name); goto error; } - if (networkPlugBandwidth(obj, &iface->mac, iface->bandwidth, - iface->data.network.actual ? - &iface->data.network.actual->class_id : NULL) < 0) + if (networkPlugBandwidth(obj, &port->mac, port->bandwidth, &port->class_id) < 0) goto error; break; case VIR_NETWORK_FORWARD_HOSTDEV: { - virDomainHostdevSubsysPCIBackendType backend; + port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI; - iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_HOSTDEV; if (networkCreateInterfacePool(netdef) < 0) goto error; @@ -4594,42 +4576,19 @@ networkAllocateActualDevice(virNetworkPtr net, netdef->name); goto error; } - iface->data.network.actual->data.hostdev.def.parent = iface; - iface->data.network.actual->data.hostdev.def.info = &iface->info; - iface->data.network.actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; - iface->data.network.actual->data.hostdev.def.managed = netdef->forward.managed ? 1 : 0; - iface->data.network.actual->data.hostdev.def.source.subsys.type = dev->type; - iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.addr = dev->device.pci; - - switch (netdef->forward.driverName) { - case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT: - backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT; - break; - case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM: - backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM; - break; - case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO: - backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO; - break; - default: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unrecognized driver name value %d " - " in network '%s'"), - netdef->forward.driverName, netdef->name); - goto error; - } - iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend - = backend; + port->plug.hostdevpci.addr = dev->device.pci; + port->plug.hostdevpci.driver = netdef->forward.driverName; + port->plug.hostdevpci.managed = netdef->forward.managed; - if (virtport) { + if (port->virtPortProfile) { /* make sure type is supported for hostdev connections */ - if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG && - virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) { + if (port->virtPortProfile->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG && + port->virtPortProfile->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("<virtualport type='%s'> not supported for network " "'%s' which uses an SR-IOV Virtual Function " "via PCI passthrough"), - virNetDevVPortTypeToString(virtport->virtPortType), + virNetDevVPortTypeToString(port->virtPortProfile->virtPortType), netdef->name); goto error; } @@ -4643,28 +4602,24 @@ networkAllocateActualDevice(virNetworkPtr net, * is VIR_DOMAIN_NET_TYPE_BRIDGE */ - iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_BRIDGE; - if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname, - netdef->bridge) < 0) + port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE; + if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0) goto error; - iface->data.network.actual->data.bridge.macTableManager - = netdef->macTableManager; + port->plug.bridge.macTableManager = netdef->macTableManager; - if (virtport) { + if (port->virtPortProfile) { /* only type='openvswitch' is allowed for bridges */ - if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { + if (port->virtPortProfile->virtPortType != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("<virtualport type='%s'> not supported for network " "'%s' which uses a bridge device"), - virNetDevVPortTypeToString(virtport->virtPortType), + virNetDevVPortTypeToString(port->virtPortProfile->virtPortType), netdef->name); goto error; } } - if (networkPlugBandwidth(obj, &iface->mac, iface->bandwidth, - iface->data.network.actual ? - &iface->data.network.actual->class_id : NULL) < 0) + if (networkPlugBandwidth(obj, &port->mac, port->bandwidth, &port->class_id) < 0) goto error; break; } @@ -4682,22 +4637,22 @@ networkAllocateActualDevice(virNetworkPtr net, */ /* Set type=direct and appropriate <source mode='xxx'/> */ - iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_DIRECT; + port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_DIRECT; /* NO need to check the value returned from virNetDevMacVLanModeTypeFromString * it must be valid for these forward type(bridge|private|vepa|passthrough) */ - iface->data.network.actual->data.direct.mode = + port->plug.direct.mode = virNetDevMacVLanModeTypeFromString(virNetworkForwardTypeToString(netdef->forward.type)); - if (virtport) { + if (port->virtPortProfile) { /* make sure type is supported for macvtap connections */ - if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG && - virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) { + if (port->virtPortProfile->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG && + port->virtPortProfile->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("<virtualport type='%s'> not supported for network " "'%s' which uses a macvtap device"), - virNetDevVPortTypeToString(virtport->virtPortType), + virNetDevVPortTypeToString(port->virtPortProfile->virtPortType), netdef->name); goto error; } @@ -4726,8 +4681,8 @@ networkAllocateActualDevice(virNetworkPtr net, */ if ((netdef->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH) || ((netdef->forward.type == VIR_NETWORK_FORWARD_PRIVATE) && - iface->data.network.actual->virtPortProfile && - (iface->data.network.actual->virtPortProfile->virtPortType + port->virtPortProfile && + (port->virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH))) { /* pick first dev with 0 connections */ @@ -4753,7 +4708,7 @@ networkAllocateActualDevice(virNetworkPtr net, netdef->name); goto error; } - if (VIR_STRDUP(iface->data.network.actual->data.direct.linkdev, + if (VIR_STRDUP(port->plug.direct.linkdev, dev->device.dev) < 0) goto error; } @@ -4766,30 +4721,30 @@ networkAllocateActualDevice(virNetworkPtr net, } if (virNetworkObjMacMgrAdd(obj, driver->dnsmasqStateDir, - dom->name, &iface->mac) < 0) + dom->name, &port->mac) < 0) goto error; - if (virNetDevVPortProfileCheckComplete(virtport, true) < 0) + if (virNetDevVPortProfileCheckComplete(port->virtPortProfile, true) < 0) goto error; /* make sure that everything now specified for the device is * actually supported on this type of network. NB: network, * netdev, and iface->data.network.actual may all be NULL. */ + VIR_DEBUG("Sanity check port config"); - if (virDomainNetGetActualVlan(iface)) { + if (port->vlan.nTags) { /* 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(iface) - == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) || - (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE && - virtport && virtport->virtPortType - == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) { + if (!(port->plugtype == VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI || + (port->plugtype == VIR_NETWORK_PORT_PLUG_TYPE_DIRECT && + port->plug.direct.mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) || + (port->plugtype == VIR_DOMAIN_NET_TYPE_BRIDGE && + port->virtPortProfile && + port->virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("an interface connecting to network '%s' " "is requesting a vlan tag, but that is not " @@ -4798,16 +4753,15 @@ networkAllocateActualDevice(virNetworkPtr net, goto error; } } - if (virDomainNetGetActualBandwidth(iface)) { - /* bandwidth configuration via libvirt is not supported for - * hostdev network devices - */ - if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("bandwidth settings are not supported " - "for hostdev interfaces")); - goto error; - } + + /* bandwidth configuration via libvirt is not supported for + * hostdev network devices + */ + if (port->bandwidth && port->plugtype == VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("bandwidth settings are not supported " + "for hostdev interfaces")); + goto error; } netdef->connections++; @@ -4825,9 +4779,15 @@ networkAllocateActualDevice(virNetworkPtr net, } networkLogAllocation(netdef, dev, &iface->mac, true); + VIR_DEBUG("Populating net def"); + if (virDomainNetDefActualFromNetworkPort(iface, port) < 0) + goto error; + + VIR_DEBUG("Port allocated"); ret = 0; cleanup: + virNetworkPortDefFree(port); virNetworkObjEndAPI(&obj); return ret; -- 2.19.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list