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); -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list