mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
We now have a qemuInterfaceStartDevices() which does the final activation needed for the host-side tap/macvtap devices that are used for qemu network connections. It will soon make sense to have the converse qemuInterfaceStopDevices() which will undo whatever was done during qemuInterfaceStartDevices(). A function to "stop" a single device has also been added, and is called from the appropriate place in qemuDomainDetachNetDevice(), although this is currently unnecessary - the device is going to immediately be deleted anyway, so any extra "deactivation" will be for naught. The call is included for completeness, though, in anticipation that in the future there may be some required action that *isn't* nullified by deleting the device. This patch is a part of a more complete fix for: https://bugzilla.redhat.com/show_bug.cgi?id=1081461
169 lines
4.7 KiB
C
169 lines
4.7 KiB
C
/*
|
|
* 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
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors:
|
|
* Matthew J. Rosato <mjrosato@linux.vnet.ibm.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#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;
|
|
}
|