/* * qemu_interface.c: QEMU interface management * * Copyright IBM Corp. 2014 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . * * Authors: * Matthew J. Rosato */ #include #include "qemu_interface.h" #include "virnetdev.h" #include "virnetdevtap.h" #include "virnetdevmacvlan.h" #include "virnetdevvportprofile.h" /** * qemuInterfaceStartDevice: * @net: net device to start * * Based upon the type of device provided, perform the appropriate * work to completely activate the device and make it reachable from * the rest of the network. */ int qemuInterfaceStartDevice(virDomainNetDefPtr net) { int ret = -1; virDomainNetType actualType = virDomainNetGetActualType(net); switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: break; case VIR_DOMAIN_NET_TYPE_DIRECT: /* macvtap devices share their MAC address with the guest * domain, and if they are set online prior to the domain CPUs * being started, the host may send out traffic from this * device that could confuse other entities on the network (in * particular, if this new domain is the destination of a * migration, and the source domain is still running, another * host may mistakenly direct traffic for the guest to the * destination domain rather than source domain). To prevent * this, we create the macvtap device with IFF_UP false * (i.e. "offline") then wait to bring it online until just as * we are starting the domain CPUs. */ if (virNetDevSetOnline(net->ifname, true) < 0) goto cleanup; break; case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: case VIR_DOMAIN_NET_TYPE_MCAST: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_LAST: /* these types all require no action */ break; } ret = 0; cleanup: return ret; } /** * qemuInterfaceStartDevices: * @def: domain definition * * Set all ifaces associated with this domain to the online state. */ int qemuInterfaceStartDevices(virDomainDefPtr def) { size_t i; for (i = 0; i < def->nnets; i++) { if (qemuInterfaceStartDevice(def->nets[i]) < 0) return -1; } return 0; } /** * qemuInterfaceStopDevice: * @net: net device to stop * * Based upon the type of device provided, perform the appropriate * work to deactivate the device so that packets aren't forwarded to * it from the rest of the network. */ int qemuInterfaceStopDevice(virDomainNetDefPtr net) { int ret = -1; virDomainNetType actualType = virDomainNetGetActualType(net); switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_NETWORK: break; case VIR_DOMAIN_NET_TYPE_DIRECT: /* macvtap interfaces need to be marked !IFF_UP (ie "down") to * prevent any host-generated traffic sent from this interface * from putting bad info into the arp caches of other machines * on this network. */ if (virNetDevSetOnline(net->ifname, false) < 0) goto cleanup; break; case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_ETHERNET: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: case VIR_DOMAIN_NET_TYPE_MCAST: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_LAST: /* these types all require no action */ break; } ret = 0; cleanup: return ret; } /** * qemuInterfaceStopDevices: * @def: domain definition * * Make all interfaces associated with this domain inaccessible from * the rest of the network. */ int qemuInterfaceStopDevices(virDomainDefPtr def) { size_t i; for (i = 0; i < def->nnets; i++) { if (qemuInterfaceStopDevice(def->nets[i]) < 0) return -1; } return 0; }