[libvirt] [PATCH 1/2] nwfilter: Pass the VM's UUID into the nwfilter subsystem

A preparatory patch for DHCP snooping where we want to be able to differentiate between a VM's interface using the tuple of <VM UUID, Interface MAC address>. We assume that MAC addresses could possibly be re-used between different networks (VLANs) thus do not only want to rely on the MAC address to identify an interface. At the current 'final destination' in virNWFilterInstantiate I am leaving the vmuuid parameter as ATTRIBUTE_UNUSED until the DHCP snooping patches arrive. (we may not post the DHCP snooping patches for 0.9.8, though) Mostly this is a pretty trivial patch. On the lowest layers, in lxc_driver and uml_conf, I am passing the virDomainDefPtr around until I am passing only the VM's uuid into the NWFilter calls. --- src/conf/domain_nwfilter.c | 3 ++- src/conf/domain_nwfilter.h | 2 ++ src/lxc/lxc_driver.c | 5 ++++- src/nwfilter/nwfilter_driver.c | 6 ++++-- src/nwfilter/nwfilter_gentech_driver.c | 27 +++++++++++++++++++-------- src/nwfilter/nwfilter_gentech_driver.h | 5 ++++- src/nwfilter/nwfilter_learnipaddr.c | 3 ++- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_process.c | 2 +- src/uml/uml_conf.c | 11 +++++++---- 10 files changed, 46 insertions(+), 20 deletions(-) Index: libvirt-acl/src/nwfilter/nwfilter_driver.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c +++ libvirt-acl/src/nwfilter/nwfilter_driver.c @@ -443,8 +443,10 @@ cleanup: static int nwfilterInstantiateFilter(virConnectPtr conn, - virDomainNetDefPtr net) { - return virNWFilterInstantiateFilter(conn, net); + const unsigned char *vmuuid, + virDomainNetDefPtr net) +{ + return virNWFilterInstantiateFilter(conn, vmuuid, 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 @@ -607,6 +607,7 @@ virNWFilterRuleInstancesToArray(int nEnt /** * virNWFilterInstantiate: + * @vmuuid: The UUID of the VM * @techdriver: The driver to use for instantiation * @filter: The filter to instantiate * @ifname: The name of the interface to apply the rules to @@ -625,7 +626,8 @@ virNWFilterRuleInstancesToArray(int nEnt * Call this function while holding the NWFilter filter update lock */ static int -virNWFilterInstantiate(virNWFilterTechDriverPtr techdriver, +virNWFilterInstantiate(const unsigned char *vmuuid ATTRIBUTE_UNUSED, + virNWFilterTechDriverPtr techdriver, enum virDomainNetType nettype, virNWFilterDefPtr filter, const char *ifname, @@ -761,7 +763,8 @@ err_unresolvable_vars: * Call this function while holding the NWFilter filter update lock */ static int -__virNWFilterInstantiateFilter(bool teardownOld, +__virNWFilterInstantiateFilter(const unsigned char *vmuuid, + bool teardownOld, const char *ifname, int ifindex, const char *linkdev, @@ -853,7 +856,8 @@ __virNWFilterInstantiateFilter(bool tear break; } - rc = virNWFilterInstantiate(techdriver, + rc = virNWFilterInstantiate(vmuuid, + techdriver, nettype, filter, ifname, @@ -883,6 +887,7 @@ err_exit: static int _virNWFilterInstantiateFilter(virConnectPtr conn, + const unsigned char *vmuuid, const virDomainNetDefPtr net, bool teardownOld, enum instCase useNewFilter, @@ -908,7 +913,8 @@ _virNWFilterInstantiateFilter(virConnect goto cleanup; } - rc = __virNWFilterInstantiateFilter(teardownOld, + rc = __virNWFilterInstantiateFilter(vmuuid, + teardownOld, net->ifname, ifindex, linkdev, @@ -929,7 +935,8 @@ cleanup: int -virNWFilterInstantiateFilterLate(const char *ifname, +virNWFilterInstantiateFilterLate(const unsigned char *vmuuid, + const char *ifname, int ifindex, const char *linkdev, enum virDomainNetType nettype, @@ -943,7 +950,8 @@ virNWFilterInstantiateFilterLate(const c virNWFilterLockFilterUpdates(); - rc = __virNWFilterInstantiateFilter(true, + rc = __virNWFilterInstantiateFilter(vmuuid, + true, ifname, ifindex, linkdev, @@ -973,11 +981,12 @@ virNWFilterInstantiateFilterLate(const c int virNWFilterInstantiateFilter(virConnectPtr conn, + const unsigned char *vmuuid, const virDomainNetDefPtr net) { bool foundNewFilter = false; - return _virNWFilterInstantiateFilter(conn, net, + return _virNWFilterInstantiateFilter(conn, vmuuid, net, 1, INSTANTIATE_ALWAYS, &foundNewFilter); @@ -986,12 +995,13 @@ virNWFilterInstantiateFilter(virConnectP int virNWFilterUpdateInstantiateFilter(virConnectPtr conn, + const unsigned char *vmuuid, const virDomainNetDefPtr net, bool *skipIface) { bool foundNewFilter = false; - int rc = _virNWFilterInstantiateFilter(conn, net, + int rc = _virNWFilterInstantiateFilter(conn, vmuuid, net, 0, INSTANTIATE_FOLLOW_NEWFILTER, &foundNewFilter); @@ -1108,6 +1118,7 @@ virNWFilterDomainFWUpdateCB(void *payloa switch (cb->step) { case STEP_APPLY_NEW: cb->err = virNWFilterUpdateInstantiateFilter(cb->conn, + vm->uuid, net, &skipIface); if (cb->err == 0 && skipIface) { 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 @@ -38,15 +38,18 @@ enum instCase { int virNWFilterInstantiateFilter(virConnectPtr conn, + const unsigned char *vmuuid, const virDomainNetDefPtr net); int virNWFilterUpdateInstantiateFilter(virConnectPtr conn, + const unsigned char *vmuuid, const virDomainNetDefPtr net, bool *skipIface); int virNWFilterRollbackUpdateFilter(const virDomainNetDefPtr net); int virNWFilterTearOldFilter(const virDomainNetDefPtr net); -int virNWFilterInstantiateFilterLate(const char *ifname, +int virNWFilterInstantiateFilterLate(const unsigned char *vmuuid, + const char *ifname, int ifindex, const char *linkdev, enum virDomainNetType nettype, Index: libvirt-acl/src/conf/domain_nwfilter.h =================================================================== --- libvirt-acl.orig/src/conf/domain_nwfilter.h +++ libvirt-acl/src/conf/domain_nwfilter.h @@ -24,6 +24,7 @@ # define DOMAIN_NWFILTER_H typedef int (*virDomainConfInstantiateNWFilter)(virConnectPtr conn, + const unsigned char *vmuuid, virDomainNetDefPtr net); typedef void (*virDomainConfTeardownNWFilter)(virDomainNetDefPtr net); @@ -36,6 +37,7 @@ typedef virDomainConfNWFilterDriver *vir void virDomainConfNWFilterRegister(virDomainConfNWFilterDriverPtr driver); int virDomainConfNWFilterInstantiate(virConnectPtr conn, + const unsigned char *vmuuid, virDomainNetDefPtr net); void virDomainConfNWFilterTeardown(virDomainNetDefPtr net); void virDomainConfVMNWFilterTeardown(virDomainObjPtr vm); Index: libvirt-acl/src/uml/uml_conf.c =================================================================== --- libvirt-acl.orig/src/uml/uml_conf.c +++ libvirt-acl/src/uml/uml_conf.c @@ -117,6 +117,7 @@ virCapsPtr umlCapsInit(void) { static int umlConnectTapDevice(virConnectPtr conn, + virDomainDefPtr vm, virDomainNetDefPtr net, const char *bridge) { @@ -143,7 +144,7 @@ umlConnectTapDevice(virConnectPtr conn, } if (net->filter) { - if (virDomainConfNWFilterInstantiate(conn, net) < 0) { + if (virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0) { if (template_ifname) VIR_FREE(net->ifname); goto error; @@ -160,6 +161,7 @@ error: static char * umlBuildCommandLineNet(virConnectPtr conn, + virDomainDefPtr vm, virDomainNetDefPtr def, int idx) { @@ -225,7 +227,7 @@ umlBuildCommandLineNet(virConnectPtr con goto error; } - if (umlConnectTapDevice(conn, def, bridge) < 0) { + if (umlConnectTapDevice(conn, vm, def, bridge) < 0) { VIR_FREE(bridge); goto error; } @@ -236,7 +238,8 @@ umlBuildCommandLineNet(virConnectPtr con } case VIR_DOMAIN_NET_TYPE_BRIDGE: - if (umlConnectTapDevice(conn, def, def->data.bridge.brname) < 0) + if (umlConnectTapDevice(conn, vm, def, + def->data.bridge.brname) < 0) goto error; /* ethNNN=tuntap,tapname,macaddr,gateway */ @@ -429,7 +432,7 @@ virCommandPtr umlBuildCommandLine(virCon } for (i = 0 ; i < vm->def->nnets ; i++) { - char *ret = umlBuildCommandLineNet(conn, vm->def->nets[i], i); + char *ret = umlBuildCommandLineNet(conn, vm->def, vm->def->nets[i], i); if (!ret) goto error; virCommandAddArg(cmd, ret); Index: libvirt-acl/src/lxc/lxc_driver.c =================================================================== --- libvirt-acl.orig/src/lxc/lxc_driver.c +++ libvirt-acl/src/lxc/lxc_driver.c @@ -1183,6 +1183,7 @@ static void lxcVmCleanup(lxc_driver_t *d static int lxcSetupInterfaceBridged(virConnectPtr conn, + virDomainDefPtr vm, virDomainNetDefPtr net, const char *brname, unsigned int *nveths, @@ -1227,7 +1228,7 @@ static int lxcSetupInterfaceBridged(virC } if (net->filter && - virDomainConfNWFilterInstantiate(conn, net) < 0) + virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0) goto cleanup; ret = 0; @@ -1347,6 +1348,7 @@ static int lxcSetupInterfaces(virConnect goto cleanup; if (lxcSetupInterfaceBridged(conn, + def, def->nets[i], brname, nveths, @@ -1365,6 +1367,7 @@ static int lxcSetupInterfaces(virConnect goto cleanup; } if (lxcSetupInterfaceBridged(conn, + def, def->nets[i], brname, nveths, Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c +++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c @@ -704,7 +704,8 @@ learnIPAddressThread(void *arg) "cache for interface %s"), inetaddr, req->ifname); } - ret = virNWFilterInstantiateFilterLate(req->ifname, + ret = virNWFilterInstantiateFilterLate(NULL, + req->ifname, req->ifindex, req->linkdev, req->nettype, Index: libvirt-acl/src/conf/domain_nwfilter.c =================================================================== --- libvirt-acl.orig/src/conf/domain_nwfilter.c +++ libvirt-acl/src/conf/domain_nwfilter.c @@ -37,9 +37,10 @@ virDomainConfNWFilterRegister(virDomainC int virDomainConfNWFilterInstantiate(virConnectPtr conn, + const unsigned char *vmuuid, virDomainNetDefPtr net) { if (nwfilterDriver != NULL) - return nwfilterDriver->instantiateFilter(conn, net); + return nwfilterDriver->instantiateFilter(conn, vmuuid, net); /* driver module not available -- don't indicate failure */ return 0; } Index: libvirt-acl/src/qemu/qemu_command.c =================================================================== --- libvirt-acl.orig/src/qemu/qemu_command.c +++ libvirt-acl/src/qemu/qemu_command.c @@ -275,7 +275,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr if (tapfd >= 0) { if ((net->filter) && (net->ifname)) { - if (virDomainConfNWFilterInstantiate(conn, net) < 0) + if (virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) VIR_FORCE_CLOSE(tapfd); } } Index: libvirt-acl/src/qemu/qemu_process.c =================================================================== --- libvirt-acl.orig/src/qemu/qemu_process.c +++ libvirt-acl/src/qemu/qemu_process.c @@ -2321,7 +2321,7 @@ qemuProcessFiltersInstantiate(virConnect for (i = 0 ; i < def->nnets ; i++) { virDomainNetDefPtr net = def->nets[i]; if ((net->filter) && (net->ifname)) { - if (virDomainConfNWFilterInstantiate(conn, net) < 0) { + if (virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) { err = 1; break; }

On 11/28/2011 11:32 AM, Stefan Berger wrote:
A preparatory patch for DHCP snooping where we want to be able to differentiate between a VM's interface using the tuple of <VM UUID, Interface MAC address>. We assume that MAC addresses could possibly be re-used between different networks (VLANs) thus do not only want to rely on the MAC address to identify an interface.
At the current 'final destination' in virNWFilterInstantiate I am leaving the vmuuid parameter as ATTRIBUTE_UNUSED until the DHCP snooping patches arrive. (we may not post the DHCP snooping patches for 0.9.8, though)
You may want to tweak the commit message, now that 0.9.8 is out :)
Mostly this is a pretty trivial patch. On the lowest layers, in lxc_driver and uml_conf, I am passing the virDomainDefPtr around until I am passing only the VM's uuid into the NWFilter calls.
This patch applied cleanly after your return status cleanup, and does indeed look straight-forward.
--- src/conf/domain_nwfilter.c | 3 ++- src/conf/domain_nwfilter.h | 2 ++ src/lxc/lxc_driver.c | 5 ++++- src/nwfilter/nwfilter_driver.c | 6 ++++-- src/nwfilter/nwfilter_gentech_driver.c | 27 +++++++++++++++++++-------- src/nwfilter/nwfilter_gentech_driver.h | 5 ++++- src/nwfilter/nwfilter_learnipaddr.c | 3 ++- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_process.c | 2 +- src/uml/uml_conf.c | 11 +++++++---- 10 files changed, 46 insertions(+), 20 deletions(-)
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c +++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c @@ -704,7 +704,8 @@ learnIPAddressThread(void *arg) "cache for interface %s"), inetaddr, req->ifname); }
- ret = virNWFilterInstantiateFilterLate(req->ifname, + ret = virNWFilterInstantiateFilterLate(NULL, + req->ifname,
Is this going to bite us later? Obviously, with the ATTRIBUTE_UNUSED in this patch, it won't, but I'm wondering if you need to pass the uuid through a few more calls (but that can be a separate patch). ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 12/08/2011 06:32 PM, Eric Blake wrote:
On 11/28/2011 11:32 AM, Stefan Berger wrote:
A preparatory patch for DHCP snooping where we want to be able to differentiate between a VM's interface using the tuple of <VM UUID, Interface MAC address>. We assume that MAC addresses could possibly be re-used between different networks (VLANs) thus do not only want to rely on the MAC address to identify an interface.
At the current 'final destination' in virNWFilterInstantiate I am leaving the vmuuid parameter as ATTRIBUTE_UNUSED until the DHCP snooping patches arrive. (we may not post the DHCP snooping patches for 0.9.8, though) You may want to tweak the commit message, now that 0.9.8 is out :)
Mostly this is a pretty trivial patch. On the lowest layers, in lxc_driver and uml_conf, I am passing the virDomainDefPtr around until I am passing only the VM's uuid into the NWFilter calls. This patch applied cleanly after your return status cleanup, and does indeed look straight-forward.
--- src/conf/domain_nwfilter.c | 3 ++- src/conf/domain_nwfilter.h | 2 ++ src/lxc/lxc_driver.c | 5 ++++- src/nwfilter/nwfilter_driver.c | 6 ++++-- src/nwfilter/nwfilter_gentech_driver.c | 27 +++++++++++++++++++-------- src/nwfilter/nwfilter_gentech_driver.h | 5 ++++- src/nwfilter/nwfilter_learnipaddr.c | 3 ++- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_process.c | 2 +- src/uml/uml_conf.c | 11 +++++++---- 10 files changed, 46 insertions(+), 20 deletions(-)
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c +++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c @@ -704,7 +704,8 @@ learnIPAddressThread(void *arg) "cache for interface %s"), inetaddr, req->ifname); }
- ret = virNWFilterInstantiateFilterLate(req->ifname, + ret = virNWFilterInstantiateFilterLate(NULL, + req->ifname, Is this going to bite us later? Obviously, with the ATTRIBUTE_UNUSED in It shouldn't. The DHCP snooping code is the final recipient of the UUID. If the above filter instantiation function was to call into the DHCP snooping code we'd have a different type of problem. this patch, it won't, but I'm wondering if you need to pass the uuid through a few more calls (but that can be a separate patch). ACK.
Thanks for the review. Stefan
participants (2)
-
Eric Blake
-
Stefan Berger