Another preparatory patch for DHCP snooping where we want to be able to
differentiate between a VM start/interface attach and other operations
like VM resume and libvirtd restart so that upon VM start we can internally
discard all DHCP leases that may still be active for a VM's interface
identified by its MAC address (and the VM's UUID). This then helps to prevent
installation of filters with IP addresses from a previous run of the VM upon
for example a libvird restart or a 'kill -SIGHUP':
Pass the VM operation into the nwfilter subsystem. Also this parameter
currently is an ATTRIBUTE_UNUSED in 'virNWFilterInstantiate' until the
DHCP snooping patches make use of it.
I am 'abusing' the enum type originally introduced for 802.1Qb{g|h} to
determine what type of operation is being used. Introducing another type
probably doesn't make much sense but maybe renaming this enum type to
something like 'virVMOperation' would?
---
src/conf/domain_nwfilter.c | 3 ++-
src/conf/domain_nwfilter.h | 2 ++
src/lxc/lxc_driver.c | 10 ++++++++--
src/nwfilter/nwfilter_driver.c | 3 ++-
src/nwfilter/nwfilter_gentech_driver.c | 15 +++++++++++----
src/nwfilter/nwfilter_gentech_driver.h | 1 +
src/qemu/qemu_command.c | 8 +++++---
src/qemu/qemu_command.h | 1 +
src/qemu/qemu_hotplug.c | 4 +++-
src/qemu/qemu_process.c | 7 +++++--
src/uml/uml_conf.c | 14 +++++++++-----
src/uml/uml_conf.h | 3 ++-
src/uml/uml_driver.c | 3 ++-
13 files changed, 53 insertions(+), 21 deletions(-)
Index: libvirt-acl/src/conf/domain_nwfilter.c
===================================================================
--- libvirt-acl.orig/src/conf/domain_nwfilter.c
+++ libvirt-acl/src/conf/domain_nwfilter.c
@@ -38,9 +38,10 @@ virDomainConfNWFilterRegister(virDomainC
int
virDomainConfNWFilterInstantiate(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
virDomainNetDefPtr net) {
if (nwfilterDriver != NULL)
- return nwfilterDriver->instantiateFilter(conn, vmuuid, net);
+ return nwfilterDriver->instantiateFilter(conn, vmuuid, vmOp, net);
/* driver module not available -- don't indicate failure */
return 0;
}
Index: libvirt-acl/src/conf/domain_nwfilter.h
===================================================================
--- libvirt-acl.orig/src/conf/domain_nwfilter.h
+++ libvirt-acl/src/conf/domain_nwfilter.h
@@ -25,6 +25,7 @@
typedef int (*virDomainConfInstantiateNWFilter)(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp,
virDomainNetDefPtr net);
typedef void (*virDomainConfTeardownNWFilter)(virDomainNetDefPtr net);
@@ -38,6 +39,7 @@ void virDomainConfNWFilterRegister(virDo
int virDomainConfNWFilterInstantiate(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
virDomainNetDefPtr net);
void virDomainConfNWFilterTeardown(virDomainNetDefPtr net);
void virDomainConfVMNWFilterTeardown(virDomainObjPtr vm);
Index: libvirt-acl/src/nwfilter/nwfilter_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_driver.c
@@ -444,9 +444,10 @@ cleanup:
static int
nwfilterInstantiateFilter(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
virDomainNetDefPtr net)
{
- return virNWFilterInstantiateFilter(conn, vmuuid, net);
+ return virNWFilterInstantiateFilter(conn, vmuuid, vmOp, net);
}
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
@@ -627,6 +627,7 @@ virNWFilterRuleInstancesToArray(int nEnt
*/
static int
virNWFilterInstantiate(const unsigned char *vmuuid ATTRIBUTE_UNUSED,
+ enum virNetDevVPortProfileOp vmOp ATTRIBUTE_UNUSED,
virNWFilterTechDriverPtr techdriver,
enum virDomainNetType nettype,
virNWFilterDefPtr filter,
@@ -764,6 +765,7 @@ err_unresolvable_vars:
*/
static int
__virNWFilterInstantiateFilter(const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
bool teardownOld,
const char *ifname,
int ifindex,
@@ -856,7 +858,7 @@ __virNWFilterInstantiateFilter(const uns
break;
}
- rc = virNWFilterInstantiate(vmuuid,
+ rc = virNWFilterInstantiate(vmuuid, vmOp,
techdriver,
nettype,
filter,
@@ -888,6 +890,7 @@ err_exit:
static int
_virNWFilterInstantiateFilter(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
const virDomainNetDefPtr net,
bool teardownOld,
enum instCase useNewFilter,
@@ -913,7 +916,7 @@ _virNWFilterInstantiateFilter(virConnect
goto cleanup;
}
- rc = __virNWFilterInstantiateFilter(vmuuid,
+ rc = __virNWFilterInstantiateFilter(vmuuid, vmOp,
teardownOld,
net->ifname,
ifindex,
@@ -951,6 +954,7 @@ virNWFilterInstantiateFilterLate(const u
virNWFilterLockFilterUpdates();
rc = __virNWFilterInstantiateFilter(vmuuid,
+ VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
true,
ifname,
ifindex,
@@ -982,11 +986,12 @@ virNWFilterInstantiateFilterLate(const u
int
virNWFilterInstantiateFilter(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
const virDomainNetDefPtr net)
{
bool foundNewFilter = false;
- return _virNWFilterInstantiateFilter(conn, vmuuid, net,
+ return _virNWFilterInstantiateFilter(conn, vmuuid, vmOp, net,
1,
INSTANTIATE_ALWAYS,
&foundNewFilter);
@@ -1001,7 +1006,9 @@ virNWFilterUpdateInstantiateFilter(virCo
{
bool foundNewFilter = false;
- int rc = _virNWFilterInstantiateFilter(conn, vmuuid, net,
+ int rc = _virNWFilterInstantiateFilter(conn, vmuuid,
+ VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
+ net,
0,
INSTANTIATE_FOLLOW_NEWFILTER,
&foundNewFilter);
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.h
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
@@ -39,6 +39,7 @@ enum instCase {
int virNWFilterInstantiateFilter(virConnectPtr conn,
const unsigned char *vmuuid,
+ enum virNetDevVPortProfileOp vmOp,
const virDomainNetDefPtr net);
int virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
const unsigned char *vmuuid,
Index: libvirt-acl/src/qemu/qemu_command.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_command.c
+++ libvirt-acl/src/qemu/qemu_command.c
@@ -171,6 +171,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def
int
qemuNetworkIfaceConnect(virDomainDefPtr def,
virConnectPtr conn,
+ enum virNetDevVPortProfileOp vmOp,
struct qemud_driver *driver,
virDomainNetDefPtr net,
virBitmapPtr qemuCaps)
@@ -275,7 +276,8 @@ qemuNetworkIfaceConnect(virDomainDefPtr
if (tapfd >= 0) {
if ((net->filter) && (net->ifname)) {
- if (virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0)
+ if (virDomainConfNWFilterInstantiate(conn, def->uuid, vmOp,
+ net) < 0)
VIR_FORCE_CLOSE(tapfd);
}
}
@@ -4339,8 +4341,8 @@ qemuBuildCommandLine(virConnectPtr conn,
actualType = virDomainNetGetActualType(net);
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
- int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
- qemuCaps);
+ int tapfd = qemuNetworkIfaceConnect(def, conn, vmop, driver,
+ net, qemuCaps);
if (tapfd < 0)
goto error;
Index: libvirt-acl/src/lxc/lxc_driver.c
===================================================================
--- libvirt-acl.orig/src/lxc/lxc_driver.c
+++ libvirt-acl/src/lxc/lxc_driver.c
@@ -1184,6 +1184,7 @@ static void lxcVmCleanup(lxc_driver_t *d
static int lxcSetupInterfaceBridged(virConnectPtr conn,
virDomainDefPtr vm,
+ enum virNetDevVPortProfileOp vmOp,
virDomainNetDefPtr net,
const char *brname,
unsigned int *nveths,
@@ -1228,7 +1229,8 @@ static int lxcSetupInterfaceBridged(virC
}
if (net->filter &&
- virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0)
+ virDomainConfNWFilterInstantiate(conn, vm->uuid, vmOp,
+ net) < 0)
goto cleanup;
ret = 0;
@@ -1319,6 +1321,7 @@ cleanup:
*/
static int lxcSetupInterfaces(virConnectPtr conn,
virDomainDefPtr def,
+ enum virNetDevVPortProfileOp vmOp,
unsigned int *nveths,
char ***veths)
{
@@ -1349,6 +1352,7 @@ static int lxcSetupInterfaces(virConnect
if (lxcSetupInterfaceBridged(conn,
def,
+ vmOp,
def->nets[i],
brname,
nveths,
@@ -1368,6 +1372,7 @@ static int lxcSetupInterfaces(virConnect
}
if (lxcSetupInterfaceBridged(conn,
def,
+ vmOp,
def->nets[i],
brname,
nveths,
@@ -1818,7 +1823,8 @@ static int lxcVmStart(virConnectPtr conn
}
}
- if (lxcSetupInterfaces(conn, vm->def, &nveths, &veths) != 0)
+ if (lxcSetupInterfaces(conn, vm->def, VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
+ &nveths, &veths) != 0)
goto cleanup;
/* Save the configuration for the controller */
Index: libvirt-acl/src/qemu/qemu_command.h
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_command.h
+++ libvirt-acl/src/qemu/qemu_command.h
@@ -126,6 +126,7 @@ char * qemuBuildRedirdevDevStr(virDomain
int qemuNetworkIfaceConnect(virDomainDefPtr def,
virConnectPtr conn,
+ enum virNetDevVPortProfileOp vmOp,
struct qemud_driver *driver,
virDomainNetDefPtr net,
virBitmapPtr qemuCaps)
Index: libvirt-acl/src/qemu/qemu_hotplug.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_hotplug.c
+++ libvirt-acl/src/qemu/qemu_hotplug.c
@@ -669,7 +669,9 @@ int qemuDomainAttachNetDevice(virConnect
actualType = virDomainNetGetActualType(net);
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
- if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
+ if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
+ driver, net,
priv->qemuCaps)) < 0)
goto cleanup;
iface_connected = true;
Index: libvirt-acl/src/qemu/qemu_process.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_process.c
+++ libvirt-acl/src/qemu/qemu_process.c
@@ -2310,6 +2310,7 @@ qemuProcessNotifyNets(virDomainDefPtr de
static int
qemuProcessFiltersInstantiate(virConnectPtr conn,
+ enum virNetDevVPortProfileOp vmOp,
virDomainDefPtr def)
{
int err = 0;
@@ -2321,7 +2322,8 @@ qemuProcessFiltersInstantiate(virConnect
for (i = 0 ; i < def->nnets ; i++) {
virDomainNetDefPtr net = def->nets[i];
if ((net->filter) && (net->ifname)) {
- if (virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) {
+ if (virDomainConfNWFilterInstantiate(conn, def->uuid, vmOp,
+ net) < 0) {
err = 1;
break;
}
@@ -2662,7 +2664,8 @@ qemuProcessReconnect(void *opaque)
if (qemuProcessNotifyNets(obj->def) < 0)
goto error;
- if (qemuProcessFiltersInstantiate(conn, obj->def))
+ if (qemuProcessFiltersInstantiate(conn, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
+ obj->def))
goto error;
if (qemuDomainCheckEjectableMedia(driver, obj) < 0)
Index: libvirt-acl/src/uml/uml_conf.c
===================================================================
--- libvirt-acl.orig/src/uml/uml_conf.c
+++ libvirt-acl/src/uml/uml_conf.c
@@ -118,6 +118,7 @@ virCapsPtr umlCapsInit(void) {
static int
umlConnectTapDevice(virConnectPtr conn,
virDomainDefPtr vm,
+ enum virNetDevVPortProfileOp vmOp,
virDomainNetDefPtr net,
const char *bridge)
{
@@ -144,7 +145,7 @@ umlConnectTapDevice(virConnectPtr conn,
}
if (net->filter) {
- if (virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0) {
+ if (virDomainConfNWFilterInstantiate(conn, vm->uuid, vmOp, net) < 0) {
if (template_ifname)
VIR_FREE(net->ifname);
goto error;
@@ -162,6 +163,7 @@ error:
static char *
umlBuildCommandLineNet(virConnectPtr conn,
virDomainDefPtr vm,
+ enum virNetDevVPortProfileOp vmOp,
virDomainNetDefPtr def,
int idx)
{
@@ -227,7 +229,7 @@ umlBuildCommandLineNet(virConnectPtr con
goto error;
}
- if (umlConnectTapDevice(conn, vm, def, bridge) < 0) {
+ if (umlConnectTapDevice(conn, vm, vmOp, def, bridge) < 0) {
VIR_FREE(bridge);
goto error;
}
@@ -238,7 +240,7 @@ umlBuildCommandLineNet(virConnectPtr con
}
case VIR_DOMAIN_NET_TYPE_BRIDGE:
- if (umlConnectTapDevice(conn, vm, def,
+ if (umlConnectTapDevice(conn, vm, vmOp, def,
def->data.bridge.brname) < 0)
goto error;
@@ -399,7 +401,8 @@ static char *umlNextArg(char *args)
*/
virCommandPtr umlBuildCommandLine(virConnectPtr conn,
struct uml_driver *driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ enum virNetDevVPortProfileOp vmOp)
{
int i, j;
struct utsname ut;
@@ -432,7 +435,8 @@ virCommandPtr umlBuildCommandLine(virCon
}
for (i = 0 ; i < vm->def->nnets ; i++) {
- char *ret = umlBuildCommandLineNet(conn, vm->def, vm->def->nets[i], i);
+ char *ret = umlBuildCommandLineNet(conn, vm->def, vmOp,
+ vm->def->nets[i], i);
if (!ret)
goto error;
virCommandAddArg(cmd, ret);
Index: libvirt-acl/src/uml/uml_conf.h
===================================================================
--- libvirt-acl.orig/src/uml/uml_conf.h
+++ libvirt-acl/src/uml/uml_conf.h
@@ -79,6 +79,7 @@ virCapsPtr umlCapsInit (v
virCommandPtr umlBuildCommandLine(virConnectPtr conn,
struct uml_driver *driver,
- virDomainObjPtr dom);
+ virDomainObjPtr dom,
+ enum virNetDevVPortProfileOp vmOp);
#endif /* __UML_CONF_H */
Index: libvirt-acl/src/uml/uml_driver.c
===================================================================
--- libvirt-acl.orig/src/uml/uml_driver.c
+++ libvirt-acl/src/uml/uml_driver.c
@@ -1039,7 +1039,8 @@ static int umlStartVMDaemon(virConnectPt
return -1;
}
- if (!(cmd = umlBuildCommandLine(conn, driver, vm))) {
+ if (!(cmd = umlBuildCommandLine(conn, driver, vm,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE))) {
VIR_FORCE_CLOSE(logfd);
virDomainConfVMNWFilterTeardown(vm);
umlCleanupTapDevices(vm);