diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b1cc8349ce..4636194b6e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -54,6 +54,7 @@ #include "network.h" #include "macvtap.h" #include "cpu/cpu.h" +#include "nwfilter/nwfilter_gentech_driver.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -1472,6 +1473,17 @@ qemudPhysIfaceConnect(virConnectPtr conn, net->ifname); } } + + if (rc >= 0) { + if ((net->filter) && (net->ifname)) { + err = virNWFilterInstantiateFilter(conn, net); + if (err) { + close(rc); + rc = -1; + delMacvtap(net->ifname); + } + } + } #else (void)conn; (void)net; @@ -1594,6 +1606,16 @@ qemudNetworkIfaceConnect(virConnectPtr conn, } } + if (tapfd >= 0) { + if ((net->filter) && (net->ifname)) { + err = virNWFilterInstantiateFilter(conn, net); + if (err) { + close(tapfd); + tapfd = -1; + } + } + } + cleanup: VIR_FREE(brname); @@ -3309,6 +3331,7 @@ int qemudBuildCommandLine(virConnectPtr conn, char domid[50]; char *cpu; char *smp; + int last_good_net = -1; uname_normalize(&ut); @@ -3963,6 +3986,7 @@ int qemudBuildCommandLine(virConnectPtr conn, goto error; ADD_ARG(host); } + last_good_net = i; } } @@ -4423,6 +4447,11 @@ int qemudBuildCommandLine(virConnectPtr conn, VIR_FREE((qenv)[i]); VIR_FREE(qenv); } + for (i = 0; i <= last_good_net; i++) { + virDomainNetDefPtr net = def->nets[i]; + if ((net->filter) && (net->ifname)) + virNWFilterTeardownFilter(net); + } return -1; #undef ADD_ARG diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5b263a7d8e..dfa6ea3e89 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -83,6 +83,7 @@ #include "xml.h" #include "cpu/cpu.h" #include "macvtap.h" +#include "nwfilter/nwfilter_gentech_driver.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -2870,6 +2871,21 @@ cleanup: } +static void +qemuTearNWFilter(virDomainNetDefPtr net) { + if ((net->filter) && (net->ifname)) + virNWFilterTeardownFilter(net); +} + + +static void +qemuTearVMNWFilters(virDomainObjPtr vm) { + int i; + for (i = 0; i < vm->def->nnets; i++) + qemuTearNWFilter(vm->def->nets[i]); +} + + struct qemudHookData { virConnectPtr conn; virDomainObjPtr vm; @@ -3219,6 +3235,8 @@ cleanup: /* We jump here if we failed to start the VM for any reason * XXX investigate if we can kill this block and safely call * qemudShutdownVMDaemon even though no PID is running */ + qemuTearVMNWFilters(vm); + qemuDomainReAttachHostDevices(driver, vm->def); if (driver->securityDriver && @@ -3267,6 +3285,8 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver, * reporting so we don't squash a legit error. */ orig_err = virSaveLastError(); + qemuTearVMNWFilters(vm); + if (driver->macFilter) { def = vm->def; for (i = 0 ; i < def->nnets ; i++) { @@ -6659,6 +6679,8 @@ cleanup: qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &net->info) < 0) VIR_WARN0("Unable to release PCI address on NIC"); + qemuTearNWFilter(net); + VIR_FREE(nicstr); VIR_FREE(netstr); VIR_FREE(tapfd_name); @@ -7474,6 +7496,8 @@ qemudDomainDetachNetDevice(struct qemud_driver *driver, } } + qemuTearNWFilter(detach); + if (vm->def->nnets > 1) { memmove(vm->def->nets + i, vm->def->nets + i + 1, @@ -10156,8 +10180,24 @@ static virStateDriver qemuStateDriver = { .active = qemudActive, }; +static int +qemudVMFilterRebuild(virConnectPtr conn, + virHashIterator iter, void *data) +{ + (void)conn; + virHashForEach(qemu_driver->domains.objs, iter, data); + return 0; +} + + +static virNWFilterCallbackDriver qemuCallbackDriver = { + .name = "QEMU", + .vmFilterRebuild = qemudVMFilterRebuild, +}; + int qemuRegister(void) { virRegisterDriver(&qemuDriver); virRegisterStateDriver(&qemuStateDriver); + virNWFilterRegisterCallbackDriver(&qemuCallbackDriver); return 0; }