}
-int nCallbackDriver;
-#define MAX_CALLBACK_DRIVER 10
-static virNWFilterCallbackDriverPtr callbackDrvArray[MAX_CALLBACK_DRIVER];
-
-void
-virNWFilterRegisterCallbackDriver(virNWFilterCallbackDriverPtr cbd)
-{
- if (nCallbackDriver < MAX_CALLBACK_DRIVER)
- callbackDrvArray[nCallbackDriver++] = cbd;
-}
-
-
-void
-virNWFilterUnRegisterCallbackDriver(virNWFilterCallbackDriverPtr cbd)
-{
- size_t i = 0;
-
- while (i < nCallbackDriver && callbackDrvArray[i] != cbd)
- i++;
-
- if (i < nCallbackDriver) {
- memmove(&callbackDrvArray[i], &callbackDrvArray[i+1],
- (nCallbackDriver - i - 1) * sizeof(callbackDrvArray[i]));
- callbackDrvArray[i] = 0;
- nCallbackDriver--;
- }
-}
-
-
-void
-virNWFilterCallbackDriversLock(void)
-{
- size_t i;
-
- for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmDriverLock();
-}
-
-
-void
-virNWFilterCallbackDriversUnlock(void)
-{
- size_t i;
-
- for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmDriverUnlock();
-}
-
-
-static virDomainObjListIterator virNWFilterDomainFWUpdateCB;
-static void *virNWFilterDomainFWUpdateOpaque;
-
-/**
- * virNWFilterInstFiltersOnAllVMs:
- * Apply all filters on all running VMs. Don't terminate in case of an
- * error. This should be called upon reloading of the driver.
- */
-int
-virNWFilterInstFiltersOnAllVMs(void)
-{
- size_t i;
- struct domUpdateCBStruct cb = {
- .opaque = virNWFilterDomainFWUpdateOpaque,
- .step = STEP_APPLY_CURRENT,
- .skipInterfaces = NULL, /* not needed */
- };
-
- for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
- &cb);
-
- return 0;
-}
-
-
-int
-virNWFilterTriggerVMFilterRebuild(void)
-{
- size_t i;
- int ret = 0;
- struct domUpdateCBStruct cb = {
- .opaque = virNWFilterDomainFWUpdateOpaque,
- .step = STEP_APPLY_NEW,
- .skipInterfaces = virHashCreate(0, NULL),
- };
-
- if (!cb.skipInterfaces)
- return -1;
-
- for (i = 0; i < nCallbackDriver; i++) {
- if (callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
- &cb) < 0)
- ret = -1;
- }
-
- if (ret < 0) {
- cb.step = STEP_TEAR_NEW; /* rollback */
-
- for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
- &cb);
- } else {
- cb.step = STEP_TEAR_OLD; /* switch over */
-
- for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
- &cb);
- }
-
- virHashFree(cb.skipInterfaces);
-
- return ret;
-}
-
-
int
virNWFilterDeleteDef(const char *configDir,
virNWFilterDefPtr def)
return NULL;
}
+static virNWFilterTriggerRebuildCallback rebuildCallback;
+static void *rebuildOpaque;
int
-virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB,
+virNWFilterConfLayerInit(virNWFilterTriggerRebuildCallback cb,
void *opaque)
{
if (initialized)
return -1;
- virNWFilterDomainFWUpdateCB = domUpdateCB;
- virNWFilterDomainFWUpdateOpaque = opaque;
+ rebuildCallback = cb;
+ rebuildOpaque = opaque;
initialized = true;
virRWLockDestroy(&updateLock);
initialized = false;
- virNWFilterDomainFWUpdateOpaque = NULL;
- virNWFilterDomainFWUpdateCB = NULL;
+ rebuildCallback = NULL;
+ rebuildOpaque = NULL;
+}
+
+
+int
+virNWFilterTriggerRebuild(void)
+{
+ if (rebuildCallback)
+ return rebuildCallback(rebuildOpaque);
+ return 0;
}
};
-typedef enum {
- STEP_APPLY_NEW,
- STEP_TEAR_NEW,
- STEP_TEAR_OLD,
- STEP_APPLY_CURRENT,
-} UpdateStep;
-
-struct domUpdateCBStruct {
- void *opaque;
- UpdateStep step;
- virHashTablePtr skipInterfaces;
-};
-
-
void
virNWFilterRuleDefFree(virNWFilterRuleDefPtr def);
virNWFilterDefFree(virNWFilterDefPtr def);
int
-virNWFilterTriggerVMFilterRebuild(void);
+virNWFilterTriggerRebuild(void);
int
virNWFilterDeleteDef(const char *configDir,
void
virNWFilterUnlockFilterUpdates(void);
+typedef int (*virNWFilterTriggerRebuildCallback)(void *opaque);
+
int
-virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB,
+virNWFilterConfLayerInit(virNWFilterTriggerRebuildCallback cb,
void *opaque);
void
virNWFilterConfLayerShutdown(void);
-int
-virNWFilterInstFiltersOnAllVMs(void);
-
-typedef int
-(*virNWFilterRebuild)(virDomainObjListIterator domUpdateCB,
- void *data);
-
-typedef void
-(*virNWFilterVoidCall)(void);
-
-typedef struct _virNWFilterCallbackDriver virNWFilterCallbackDriver;
-typedef virNWFilterCallbackDriver *virNWFilterCallbackDriverPtr;
-struct _virNWFilterCallbackDriver {
- const char *name;
-
- virNWFilterRebuild vmFilterRebuild;
- virNWFilterVoidCall vmDriverLock;
- virNWFilterVoidCall vmDriverUnlock;
-};
-
-void
-virNWFilterRegisterCallbackDriver(virNWFilterCallbackDriverPtr);
-
-void
-virNWFilterUnRegisterCallbackDriver(virNWFilterCallbackDriverPtr);
-
-void
-virNWFilterCallbackDriversLock(void);
-
-void
-virNWFilterCallbackDriversUnlock(void);
char *
virNWFilterPrintTCPFlags(uint8_t flags);
obj->wantRemoved = true;
/* trigger the update on VMs referencing the filter */
- if (virNWFilterTriggerVMFilterRebuild() < 0)
+ if (virNWFilterTriggerRebuild() < 0)
rc = -1;
obj->wantRemoved = false;
obj->newDef = def;
/* trigger the update on VMs referencing the filter */
- if (virNWFilterTriggerVMFilterRebuild() < 0) {
+ if (virNWFilterTriggerRebuild() < 0) {
obj->newDef = NULL;
virNWFilterObjUnlock(obj);
return NULL;
# conf/nwfilter_conf.h
-virNWFilterCallbackDriversLock;
-virNWFilterCallbackDriversUnlock;
virNWFilterChainSuffixTypeToString;
virNWFilterConfLayerInit;
virNWFilterConfLayerShutdown;
virNWFilterDefParseFile;
virNWFilterDefParseString;
virNWFilterDeleteDef;
-virNWFilterInstFiltersOnAllVMs;
virNWFilterJumpTargetTypeToString;
virNWFilterPrintStateMatchFlags;
virNWFilterPrintTCPFlags;
virNWFilterReadLockFilterUpdates;
-virNWFilterRegisterCallbackDriver;
virNWFilterRuleActionTypeToString;
virNWFilterRuleDirectionTypeToString;
virNWFilterRuleIsProtocolEthernet;
virNWFilterRuleIsProtocolIPv6;
virNWFilterRuleProtocolTypeToString;
virNWFilterSaveConfig;
-virNWFilterTriggerVMFilterRebuild;
+virNWFilterTriggerRebuild;
virNWFilterUnlockFilterUpdates;
-virNWFilterUnRegisterCallbackDriver;
virNWFilterWriteLockFilterUpdates;
#include "virfdstream.h"
#include "domain_audit.h"
#include "domain_nwfilter.h"
-#include "nwfilter_conf.h"
#include "virinitctl.h"
#include "virnetdev.h"
#include "virnetdevtap.h"
static int lxcStateCleanup(void);
virLXCDriverPtr lxc_driver = NULL;
-/* callbacks for nwfilter */
-static int
-lxcVMFilterRebuild(virDomainObjListIterator iter, void *data)
-{
- return virDomainObjListForEach(lxc_driver->domains, iter, data);
-}
-
-static void
-lxcVMDriverLock(void)
-{
- lxcDriverLock(lxc_driver);
-}
-
-static void
-lxcVMDriverUnlock(void)
-{
- lxcDriverUnlock(lxc_driver);
-}
-
-static virNWFilterCallbackDriver lxcCallbackDriver = {
- .name = "LXC",
- .vmFilterRebuild = lxcVMFilterRebuild,
- .vmDriverLock = lxcVMDriverLock,
- .vmDriverUnlock = lxcVMDriverUnlock,
-};
/**
* lxcDomObjFromDomain:
NULL, NULL) < 0)
goto cleanup;
- virNWFilterRegisterCallbackDriver(&lxcCallbackDriver);
virObjectUnref(caps);
return 0;
if (lxc_driver == NULL)
return -1;
- virNWFilterUnRegisterCallbackDriver(&lxcCallbackDriver);
virObjectUnref(lxc_driver->domains);
virObjectUnref(lxc_driver->domainEventState);
#endif /* HAVE_FIREWALLD */
+static int
+virNWFilterTriggerRebuildImpl(void *opaque)
+{
+ virNWFilterDriverStatePtr nwdriver = opaque;
+
+ return virNWFilterBuildAll(nwdriver, true);
+}
+
+
/**
* nwfilterStateInitialize:
*
if (virNWFilterTechDriversInit(privileged) < 0)
goto err_dhcpsnoop_shutdown;
- if (virNWFilterConfLayerInit(virNWFilterDomainFWUpdateCB,
+ if (virNWFilterConfLayerInit(virNWFilterTriggerRebuildImpl,
driver) < 0)
goto err_techdrivers_shutdown;
nwfilterDriverLock();
virNWFilterWriteLockFilterUpdates();
- virNWFilterCallbackDriversLock();
virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->configDir);
- virNWFilterCallbackDriversUnlock();
virNWFilterUnlockFilterUpdates();
- nwfilterDriverUnlock();
- virNWFilterInstFiltersOnAllVMs();
+ virNWFilterBuildAll(driver, false);
+
+ nwfilterDriverUnlock();
return 0;
}
nwfilterDriverLock();
virNWFilterWriteLockFilterUpdates();
- virNWFilterCallbackDriversLock();
if (!(def = virNWFilterDefParseString(xml)))
goto cleanup;
if (obj)
virNWFilterObjUnlock(obj);
- virNWFilterCallbackDriversUnlock();
virNWFilterUnlockFilterUpdates();
nwfilterDriverUnlock();
return nwfilter;
nwfilterDriverLock();
virNWFilterWriteLockFilterUpdates();
- virNWFilterCallbackDriversLock();
if (!(obj = nwfilterObjFromNWFilter(nwfilter->uuid)))
goto cleanup;
if (obj)
virNWFilterObjUnlock(obj);
- virNWFilterCallbackDriversUnlock();
virNWFilterUnlockFilterUpdates();
nwfilterDriverUnlock();
return ret;
if (!val)
return -1;
- if (virHashAddEntry(table,
- NWFILTER_STD_VAR_MAC,
- val) < 0) {
+ if (virHashUpdateEntry(table,
+ NWFILTER_STD_VAR_MAC,
+ val) < 0) {
virNWFilterVarValueFree(val);
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not add variable 'MAC' to hashmap"));
if (!val)
return -1;
- if (virHashAddEntry(table,
- NWFILTER_STD_VAR_IP,
- val) < 0) {
+ if (virHashUpdateEntry(table,
+ NWFILTER_STD_VAR_IP,
+ val) < 0) {
virNWFilterVarValueFree(val);
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not add variable 'IP' to hashmap"));
return ret;
}
+enum {
+ STEP_APPLY_NEW,
+ STEP_ROLLBACK,
+ STEP_SWITCH,
+ STEP_APPLY_CURRENT,
+};
-int
-virNWFilterDomainFWUpdateCB(virDomainObjPtr obj,
- void *data)
+static int
+virNWFilterBuildOne(virNWFilterDriverStatePtr driver,
+ virNWFilterBindingDefPtr binding,
+ virHashTablePtr skipInterfaces,
+ int step)
{
- virDomainDefPtr vm = obj->def;
- struct domUpdateCBStruct *cb = data;
- size_t i;
bool skipIface;
int ret = 0;
-
- virObjectLock(obj);
-
- if (virDomainObjIsActive(obj)) {
- for (i = 0; i < vm->nnets; i++) {
- virDomainNetDefPtr net = vm->nets[i];
- virNWFilterBindingDefPtr binding;
-
- if ((net->filter) && (net->ifname) &&
- (binding = virNWFilterBindingDefForNet(
- vm->name, vm->uuid, net))) {
-
- switch (cb->step) {
- case STEP_APPLY_NEW:
- ret = virNWFilterUpdateInstantiateFilter(cb->opaque,
- binding,
- &skipIface);
- if (ret == 0 && skipIface) {
- /* filter tree unchanged -- no update needed */
- ret = virHashAddEntry(cb->skipInterfaces,
- net->ifname,
- (void *)~0);
- }
- break;
-
- case STEP_TEAR_NEW:
- if (!virHashLookup(cb->skipInterfaces, net->ifname))
- ret = virNWFilterRollbackUpdateFilter(binding);
- break;
-
- case STEP_TEAR_OLD:
- if (!virHashLookup(cb->skipInterfaces, net->ifname))
- ret = virNWFilterTearOldFilter(binding);
- break;
-
- case STEP_APPLY_CURRENT:
- ret = virNWFilterInstantiateFilter(cb->opaque,
- binding);
- if (ret)
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Failure while applying current filter on "
- "VM %s"), vm->name);
- break;
- }
- virNWFilterBindingDefFree(binding);
- if (ret)
- break;
- }
+ VIR_DEBUG("Building filter for portdev=%s step=%d", binding->portdevname, step);
+
+ switch (step) {
+ case STEP_APPLY_NEW:
+ ret = virNWFilterUpdateInstantiateFilter(driver,
+ binding,
+ &skipIface);
+ if (ret == 0 && skipIface) {
+ /* filter tree unchanged -- no update needed */
+ ret = virHashAddEntry(skipInterfaces,
+ binding->portdevname,
+ (void *)~0);
}
+ break;
+
+ case STEP_ROLLBACK:
+ if (!virHashLookup(skipInterfaces, binding->portdevname))
+ ret = virNWFilterRollbackUpdateFilter(binding);
+ break;
+
+ case STEP_SWITCH:
+ if (!virHashLookup(skipInterfaces, binding->portdevname))
+ ret = virNWFilterTearOldFilter(binding);
+ break;
+
+ case STEP_APPLY_CURRENT:
+ ret = virNWFilterInstantiateFilter(driver,
+ binding);
+ break;
}
- virObjectUnlock(obj);
+ return ret;
+}
+
+
+struct virNWFilterBuildData {
+ virNWFilterDriverStatePtr driver;
+ virHashTablePtr skipInterfaces;
+ int step;
+};
+
+static int
+virNWFilterBuildIter(virNWFilterBindingObjPtr binding, void *opaque)
+{
+ struct virNWFilterBuildData *data = opaque;
+ virNWFilterBindingDefPtr def = virNWFilterBindingObjGetDef(binding);
+
+ return virNWFilterBuildOne(data->driver, def,
+ data->skipInterfaces, data->step);
+}
+
+int
+virNWFilterBuildAll(virNWFilterDriverStatePtr driver,
+ bool newFilters)
+{
+ struct virNWFilterBuildData data = {
+ .driver = driver,
+ };
+ int ret = 0;
+
+ VIR_DEBUG("Build all filters newFilters=%d", newFilters);
+
+ if (newFilters) {
+ if (!(data.skipInterfaces = virHashCreate(0, NULL)))
+ return -1;
+
+ data.step = STEP_APPLY_NEW;
+ if (virNWFilterBindingObjListForEach(driver->bindings,
+ virNWFilterBuildIter,
+ &data) < 0)
+ ret = -1;
+
+ if (ret == -1) {
+ data.step = STEP_ROLLBACK;
+ virNWFilterBindingObjListForEach(driver->bindings,
+ virNWFilterBuildIter,
+ &data);
+ } else {
+ data.step = STEP_SWITCH;
+ virNWFilterBindingObjListForEach(driver->bindings,
+ virNWFilterBuildIter,
+ &data);
+ }
+
+ virHashFree(data.skipInterfaces);
+ } else {
+ data.step = STEP_APPLY_CURRENT;
+ if (virNWFilterBindingObjListForEach(driver->bindings,
+ virNWFilterBuildIter,
+ &data) < 0)
+ ret = -1;
+ }
return ret;
}
virHashTablePtr virNWFilterCreateVarHashmap(const char *macaddr,
const virNWFilterVarValue *value);
-int virNWFilterDomainFWUpdateCB(virDomainObjPtr vm,
- void *data);
+int virNWFilterBuildAll(virNWFilterDriverStatePtr driver,
+ bool newFilters);
virNWFilterBindingDefPtr virNWFilterBindingDefForNet(const char *vmname,
const unsigned char *vmuuid,
#include "cpu/cpu.h"
#include "virsysinfo.h"
#include "domain_nwfilter.h"
-#include "nwfilter_conf.h"
#include "virhook.h"
#include "virstoragefile.h"
#include "virfile.h"
static virQEMUDriverPtr qemu_driver;
-
-static void
-qemuVMDriverLock(void)
-{}
-static void
-qemuVMDriverUnlock(void)
-{}
-
-static int
-qemuVMFilterRebuild(virDomainObjListIterator iter, void *data)
-{
- return virDomainObjListForEach(qemu_driver->domains, iter, data);
-}
-
-static virNWFilterCallbackDriver qemuCallbackDriver = {
- .name = QEMU_DRIVER_NAME,
- .vmFilterRebuild = qemuVMFilterRebuild,
- .vmDriverLock = qemuVMDriverLock,
- .vmDriverUnlock = qemuVMDriverUnlock,
-};
-
-
/**
* qemuDomObjFromDomain:
* @domain: Domain pointer that has to be looked up
qemuProcessReconnectAll(qemu_driver);
- virNWFilterRegisterCallbackDriver(&qemuCallbackDriver);
return 0;
error:
if (!qemu_driver)
return -1;
- virNWFilterUnRegisterCallbackDriver(&qemuCallbackDriver);
virThreadPoolFree(qemu_driver->workerPool);
virObjectUnref(qemu_driver->config);
virObjectUnref(qemu_driver->hostdevMgr);
#include "datatypes.h"
#include "virlog.h"
#include "domain_nwfilter.h"
-#include "nwfilter_conf.h"
#include "virfile.h"
#include "virfdstream.h"
#include "configmake.h"
static struct uml_driver *uml_driver;
-static int
-umlVMFilterRebuild(virDomainObjListIterator iter, void *data)
-{
- return virDomainObjListForEach(uml_driver->domains, iter, data);
-}
-
-static void
-umlVMDriverLock(void)
-{
- umlDriverLock(uml_driver);
-}
-
-static void
-umlVMDriverUnlock(void)
-{
- umlDriverUnlock(uml_driver);
-}
-
-
static virDomainObjPtr
umlDomObjFromDomainLocked(struct uml_driver *driver,
const unsigned char *uuid)
}
-static virNWFilterCallbackDriver umlCallbackDriver = {
- .name = "UML",
- .vmFilterRebuild = umlVMFilterRebuild,
- .vmDriverLock = umlVMDriverLock,
- .vmDriverUnlock = umlVMDriverUnlock,
-};
-
struct umlAutostartData {
struct uml_driver *driver;
virConnectPtr conn;
VIR_FREE(userdir);
- virNWFilterRegisterCallbackDriver(¨CallbackDriver);
return 0;
out_of_memory:
return -1;
umlDriverLock(uml_driver);
- virNWFilterRegisterCallbackDriver(¨CallbackDriver);
if (uml_driver->inotifyWatch != -1)
virEventRemoveHandle(uml_driver->inotifyWatch);
VIR_FORCE_CLOSE(uml_driver->inotifyFD);