mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 09:17:52 +03:00
conf: Introduce virnwfilterobj
Move all the NWFilterObj API's into their own module virnwfilterobj from the nwfilter_conf Purely code motion at this point, plus adjustments to cleanly build.
This commit is contained in:
parent
cab7b8c276
commit
079747a36d
@ -44,6 +44,7 @@ src/conf/virchrdev.c
|
||||
src/conf/virdomainobjlist.c
|
||||
src/conf/virinterfaceobj.c
|
||||
src/conf/virnodedeviceobj.c
|
||||
src/conf/virnwfilterobj.c
|
||||
src/conf/virsecretobj.c
|
||||
src/cpu/cpu.c
|
||||
src/cpu/cpu_arm.c
|
||||
|
@ -369,11 +369,13 @@ NWFILTER_PARAM_CONF_SOURCES = \
|
||||
conf/nwfilter_params.c conf/nwfilter_params.h \
|
||||
conf/nwfilter_ipaddrmap.c \
|
||||
conf/nwfilter_ipaddrmap.h \
|
||||
conf/nwfilter_conf.h
|
||||
conf/nwfilter_conf.h \
|
||||
conf/virnwfilterobj.h
|
||||
|
||||
NWFILTER_CONF_SOURCES = \
|
||||
$(NWFILTER_PARAM_CONF_SOURCES) \
|
||||
conf/nwfilter_conf.c conf/nwfilter_conf.h
|
||||
conf/nwfilter_conf.c conf/nwfilter_conf.h \
|
||||
conf/virnwfilterobj.c conf/virnwfilterobj.h
|
||||
|
||||
# Storage driver generic impl APIs
|
||||
STORAGE_CONF_SOURCES = \
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#if HAVE_NET_ETHERNET_H
|
||||
# include <net/ethernet.h>
|
||||
#endif
|
||||
@ -344,32 +343,6 @@ virNWFilterDefFree(virNWFilterDefPtr def)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virNWFilterObjFree(virNWFilterObjPtr obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
virNWFilterDefFree(obj->def);
|
||||
virNWFilterDefFree(obj->newDef);
|
||||
|
||||
virMutexDestroy(&obj->lock);
|
||||
|
||||
VIR_FREE(obj);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virNWFilterObjListFree(virNWFilterObjListPtr nwfilters)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < nwfilters->count; i++)
|
||||
virNWFilterObjFree(nwfilters->objs[i]);
|
||||
VIR_FREE(nwfilters->objs);
|
||||
nwfilters->count = 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virNWFilterRuleDefAddVar(virNWFilterRuleDefPtr nwf,
|
||||
nwItemDesc *item,
|
||||
@ -418,27 +391,6 @@ virNWFilterRuleDefAddString(virNWFilterRuleDefPtr nwf,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterObjPtr nwfilter)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
|
||||
for (i = 0; i < nwfilters->count; i++) {
|
||||
virNWFilterObjLock(nwfilters->objs[i]);
|
||||
if (nwfilters->objs[i] == nwfilter) {
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
virNWFilterObjFree(nwfilters->objs[i]);
|
||||
|
||||
VIR_DELETE_ELEMENT(nwfilters->objs, i, nwfilters->count);
|
||||
break;
|
||||
}
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
union data {
|
||||
void *v;
|
||||
char *c;
|
||||
@ -2779,39 +2731,6 @@ virNWFilterDefParseFile(const char *filename)
|
||||
}
|
||||
|
||||
|
||||
virNWFilterObjPtr
|
||||
virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
|
||||
const unsigned char *uuid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nwfilters->count; i++) {
|
||||
virNWFilterObjLock(nwfilters->objs[i]);
|
||||
if (!memcmp(nwfilters->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
|
||||
return nwfilters->objs[i];
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
virNWFilterObjPtr
|
||||
virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nwfilters->count; i++) {
|
||||
virNWFilterObjLock(nwfilters->objs[i]);
|
||||
if (STREQ_NULLABLE(nwfilters->objs[i]->def->name, name))
|
||||
return nwfilters->objs[i];
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int virNWFilterSaveXML(const char *configDir,
|
||||
virNWFilterDefPtr def,
|
||||
const char *xml)
|
||||
@ -2860,62 +2779,6 @@ int virNWFilterSaveConfig(const char *configDir,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def,
|
||||
const char *filtername)
|
||||
{
|
||||
int rc = 0;
|
||||
size_t i;
|
||||
virNWFilterEntryPtr entry;
|
||||
virNWFilterObjPtr obj;
|
||||
|
||||
if (!def)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < def->nentries; i++) {
|
||||
entry = def->filterEntries[i];
|
||||
if (entry->include) {
|
||||
|
||||
if (STREQ(filtername, entry->include->filterref)) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
obj = virNWFilterObjFindByName(nwfilters,
|
||||
entry->include->filterref);
|
||||
if (obj) {
|
||||
rc = _virNWFilterDefLoopDetect(nwfilters,
|
||||
obj->def, filtername);
|
||||
|
||||
virNWFilterObjUnlock(obj);
|
||||
if (rc < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* virNWFilterDefLoopDetect:
|
||||
* @nwfilters : the nwfilters to search
|
||||
* @def : the filter definition that may add a loop and is to be tested
|
||||
*
|
||||
* Detect a loop introduced through the filters being able to
|
||||
* reference each other.
|
||||
*
|
||||
* Returns 0 in case no loop was detected, -1 otherwise.
|
||||
*/
|
||||
static int
|
||||
virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def)
|
||||
{
|
||||
return _virNWFilterDefLoopDetect(nwfilters, def, def->name);
|
||||
}
|
||||
|
||||
int nCallbackDriver;
|
||||
#define MAX_CALLBACK_DRIVER 10
|
||||
static virNWFilterCallbackDriverPtr callbackDrvArray[MAX_CALLBACK_DRIVER];
|
||||
@ -2987,7 +2850,7 @@ virNWFilterInstFiltersOnAllVMs(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
virNWFilterTriggerVMFilterRebuild(void)
|
||||
{
|
||||
size_t i;
|
||||
@ -3027,204 +2890,6 @@ virNWFilterTriggerVMFilterRebuild(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
nwfilter->wantRemoved = 1;
|
||||
/* trigger the update on VMs referencing the filter */
|
||||
if (virNWFilterTriggerVMFilterRebuild())
|
||||
rc = -1;
|
||||
|
||||
nwfilter->wantRemoved = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool
|
||||
virNWFilterDefEqual(const virNWFilterDef *def1, virNWFilterDefPtr def2,
|
||||
bool cmpUUIDs)
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned char rem_uuid[VIR_UUID_BUFLEN];
|
||||
char *xml1, *xml2 = NULL;
|
||||
|
||||
if (!cmpUUIDs) {
|
||||
/* make sure the UUIDs are equal */
|
||||
memcpy(rem_uuid, def2->uuid, sizeof(rem_uuid));
|
||||
memcpy(def2->uuid, def1->uuid, sizeof(def2->uuid));
|
||||
}
|
||||
|
||||
if (!(xml1 = virNWFilterDefFormat(def1)) ||
|
||||
!(xml2 = virNWFilterDefFormat(def2)))
|
||||
goto cleanup;
|
||||
|
||||
ret = STREQ(xml1, xml2);
|
||||
|
||||
cleanup:
|
||||
if (!cmpUUIDs)
|
||||
memcpy(def2->uuid, rem_uuid, sizeof(rem_uuid));
|
||||
|
||||
VIR_FREE(xml1);
|
||||
VIR_FREE(xml2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
virNWFilterObjPtr
|
||||
virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def)
|
||||
{
|
||||
virNWFilterObjPtr nwfilter;
|
||||
|
||||
nwfilter = virNWFilterObjFindByUUID(nwfilters, def->uuid);
|
||||
|
||||
if (nwfilter) {
|
||||
if (STRNEQ(def->name, nwfilter->def->name)) {
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("filter with same UUID but different name "
|
||||
"('%s') already exists"),
|
||||
nwfilter->def->name);
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
} else {
|
||||
nwfilter = virNWFilterObjFindByName(nwfilters, def->name);
|
||||
if (nwfilter) {
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virUUIDFormat(nwfilter->def->uuid, uuidstr);
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("filter '%s' already exists with uuid %s"),
|
||||
def->name, uuidstr);
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (virNWFilterDefLoopDetect(nwfilters, def) < 0) {
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
"%s", _("filter would introduce a loop"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((nwfilter = virNWFilterObjFindByName(nwfilters, def->name))) {
|
||||
|
||||
if (virNWFilterDefEqual(def, nwfilter->def, false)) {
|
||||
virNWFilterDefFree(nwfilter->def);
|
||||
nwfilter->def = def;
|
||||
return nwfilter;
|
||||
}
|
||||
|
||||
nwfilter->newDef = def;
|
||||
/* trigger the update on VMs referencing the filter */
|
||||
if (virNWFilterTriggerVMFilterRebuild()) {
|
||||
nwfilter->newDef = NULL;
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virNWFilterDefFree(nwfilter->def);
|
||||
nwfilter->def = def;
|
||||
nwfilter->newDef = NULL;
|
||||
return nwfilter;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(nwfilter) < 0)
|
||||
return NULL;
|
||||
|
||||
if (virMutexInitRecursive(&nwfilter->lock) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("cannot initialize mutex"));
|
||||
VIR_FREE(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
virNWFilterObjLock(nwfilter);
|
||||
nwfilter->active = 0;
|
||||
|
||||
if (VIR_APPEND_ELEMENT_COPY(nwfilters->objs,
|
||||
nwfilters->count, nwfilter) < 0) {
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
virNWFilterObjFree(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
nwfilter->def = def;
|
||||
|
||||
return nwfilter;
|
||||
}
|
||||
|
||||
|
||||
static virNWFilterObjPtr
|
||||
virNWFilterLoadConfig(virNWFilterObjListPtr nwfilters,
|
||||
const char *configDir,
|
||||
const char *name)
|
||||
{
|
||||
virNWFilterDefPtr def = NULL;
|
||||
virNWFilterObjPtr nwfilter;
|
||||
char *configFile = NULL;
|
||||
|
||||
if (!(configFile = virFileBuildPath(configDir, name, ".xml")))
|
||||
goto error;
|
||||
|
||||
if (!(def = virNWFilterDefParseFile(configFile)))
|
||||
goto error;
|
||||
|
||||
if (STRNEQ(name, def->name)) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("network filter config filename '%s' "
|
||||
"does not match name '%s'"),
|
||||
configFile, def->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* We generated a UUID, make it permanent by saving the config to disk */
|
||||
if (!def->uuid_specified &&
|
||||
virNWFilterSaveConfig(configDir, def) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(nwfilter = virNWFilterObjAssignDef(nwfilters, def)))
|
||||
goto error;
|
||||
|
||||
VIR_FREE(configFile);
|
||||
return nwfilter;
|
||||
|
||||
error:
|
||||
VIR_FREE(configFile);
|
||||
virNWFilterDefFree(def);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
|
||||
const char *configDir)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int ret = -1;
|
||||
int rc;
|
||||
|
||||
if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
|
||||
return rc;
|
||||
|
||||
while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
|
||||
virNWFilterObjPtr nwfilter;
|
||||
|
||||
if (!virFileStripSuffix(entry->d_name, ".xml"))
|
||||
continue;
|
||||
|
||||
nwfilter = virNWFilterLoadConfig(nwfilters, configDir, entry->d_name);
|
||||
if (nwfilter)
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
}
|
||||
|
||||
VIR_DIR_CLOSE(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virNWFilterSaveDef(const char *configDir,
|
||||
virNWFilterDefPtr def)
|
||||
@ -3568,17 +3233,6 @@ void virNWFilterConfLayerShutdown(void)
|
||||
}
|
||||
|
||||
|
||||
void virNWFilterObjLock(virNWFilterObjPtr obj)
|
||||
{
|
||||
virMutexLock(&obj->lock);
|
||||
}
|
||||
|
||||
void virNWFilterObjUnlock(virNWFilterObjPtr obj)
|
||||
{
|
||||
virMutexUnlock(&obj->lock);
|
||||
}
|
||||
|
||||
|
||||
bool virNWFilterRuleIsProtocolIPv4(virNWFilterRuleDefPtr rule)
|
||||
{
|
||||
if (rule->prtclType >= VIR_NWFILTER_RULE_PROTOCOL_TCP &&
|
||||
|
@ -546,41 +546,6 @@ struct _virNWFilterDef {
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virNWFilterObj virNWFilterObj;
|
||||
typedef virNWFilterObj *virNWFilterObjPtr;
|
||||
|
||||
struct _virNWFilterObj {
|
||||
virMutex lock;
|
||||
|
||||
int active;
|
||||
int wantRemoved;
|
||||
|
||||
virNWFilterDefPtr def;
|
||||
virNWFilterDefPtr newDef;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virNWFilterObjList virNWFilterObjList;
|
||||
typedef virNWFilterObjList *virNWFilterObjListPtr;
|
||||
struct _virNWFilterObjList {
|
||||
size_t count;
|
||||
virNWFilterObjPtr *objs;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virNWFilterDriverState virNWFilterDriverState;
|
||||
typedef virNWFilterDriverState *virNWFilterDriverStatePtr;
|
||||
struct _virNWFilterDriverState {
|
||||
virMutex lock;
|
||||
bool privileged;
|
||||
|
||||
virNWFilterObjList nwfilters;
|
||||
|
||||
char *configDir;
|
||||
bool watchingFirewallD;
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
STEP_APPLY_NEW,
|
||||
STEP_TEAR_NEW,
|
||||
@ -598,18 +563,8 @@ struct domUpdateCBStruct {
|
||||
void virNWFilterRuleDefFree(virNWFilterRuleDefPtr def);
|
||||
|
||||
void virNWFilterDefFree(virNWFilterDefPtr def);
|
||||
void virNWFilterObjListFree(virNWFilterObjListPtr nwfilters);
|
||||
void virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterObjPtr nwfilter);
|
||||
|
||||
void virNWFilterObjFree(virNWFilterObjPtr obj);
|
||||
|
||||
virNWFilterObjPtr virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
|
||||
const unsigned char *uuid);
|
||||
|
||||
virNWFilterObjPtr virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters,
|
||||
const char *name);
|
||||
|
||||
int virNWFilterTriggerVMFilterRebuild(void);
|
||||
|
||||
int virNWFilterSaveDef(const char *configDir,
|
||||
virNWFilterDefPtr def);
|
||||
@ -617,11 +572,6 @@ int virNWFilterSaveDef(const char *configDir,
|
||||
int virNWFilterDeleteDef(const char *configDir,
|
||||
virNWFilterDefPtr def);
|
||||
|
||||
virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def);
|
||||
|
||||
int virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter);
|
||||
|
||||
virNWFilterDefPtr virNWFilterDefParseNode(xmlDocPtr xml,
|
||||
xmlNodePtr root);
|
||||
|
||||
@ -634,18 +584,12 @@ int virNWFilterSaveXML(const char *configDir,
|
||||
int virNWFilterSaveConfig(const char *configDir,
|
||||
virNWFilterDefPtr def);
|
||||
|
||||
int virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
|
||||
const char *configDir);
|
||||
|
||||
char *virNWFilterConfigFile(const char *dir,
|
||||
const char *name);
|
||||
|
||||
virNWFilterDefPtr virNWFilterDefParseString(const char *xml);
|
||||
virNWFilterDefPtr virNWFilterDefParseFile(const char *filename);
|
||||
|
||||
void virNWFilterObjLock(virNWFilterObjPtr obj);
|
||||
void virNWFilterObjUnlock(virNWFilterObjPtr obj);
|
||||
|
||||
void virNWFilterWriteLockFilterUpdates(void);
|
||||
void virNWFilterReadLockFilterUpdates(void);
|
||||
void virNWFilterUnlockFilterUpdates(void);
|
||||
|
382
src/conf/virnwfilterobj.c
Normal file
382
src/conf/virnwfilterobj.c
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* virnwfilterobj.c: network filter object processing
|
||||
* (derived from nwfilter_conf.c)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
#include "viralloc.h"
|
||||
#include "virerror.h"
|
||||
#include "virfile.h"
|
||||
#include "virlog.h"
|
||||
#include "virnwfilterobj.h"
|
||||
#include "virstring.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
||||
|
||||
VIR_LOG_INIT("conf.virnwfilterobj");
|
||||
|
||||
|
||||
void
|
||||
virNWFilterObjFree(virNWFilterObjPtr obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
virNWFilterDefFree(obj->def);
|
||||
virNWFilterDefFree(obj->newDef);
|
||||
|
||||
virMutexDestroy(&obj->lock);
|
||||
|
||||
VIR_FREE(obj);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virNWFilterObjListFree(virNWFilterObjListPtr nwfilters)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < nwfilters->count; i++)
|
||||
virNWFilterObjFree(nwfilters->objs[i]);
|
||||
VIR_FREE(nwfilters->objs);
|
||||
nwfilters->count = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterObjPtr nwfilter)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
|
||||
for (i = 0; i < nwfilters->count; i++) {
|
||||
virNWFilterObjLock(nwfilters->objs[i]);
|
||||
if (nwfilters->objs[i] == nwfilter) {
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
virNWFilterObjFree(nwfilters->objs[i]);
|
||||
|
||||
VIR_DELETE_ELEMENT(nwfilters->objs, i, nwfilters->count);
|
||||
break;
|
||||
}
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virNWFilterObjPtr
|
||||
virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
|
||||
const unsigned char *uuid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nwfilters->count; i++) {
|
||||
virNWFilterObjLock(nwfilters->objs[i]);
|
||||
if (!memcmp(nwfilters->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
|
||||
return nwfilters->objs[i];
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
virNWFilterObjPtr
|
||||
virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nwfilters->count; i++) {
|
||||
virNWFilterObjLock(nwfilters->objs[i]);
|
||||
if (STREQ_NULLABLE(nwfilters->objs[i]->def->name, name))
|
||||
return nwfilters->objs[i];
|
||||
virNWFilterObjUnlock(nwfilters->objs[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def,
|
||||
const char *filtername)
|
||||
{
|
||||
int rc = 0;
|
||||
size_t i;
|
||||
virNWFilterEntryPtr entry;
|
||||
virNWFilterObjPtr obj;
|
||||
|
||||
if (!def)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < def->nentries; i++) {
|
||||
entry = def->filterEntries[i];
|
||||
if (entry->include) {
|
||||
|
||||
if (STREQ(filtername, entry->include->filterref)) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
obj = virNWFilterObjFindByName(nwfilters,
|
||||
entry->include->filterref);
|
||||
if (obj) {
|
||||
rc = _virNWFilterDefLoopDetect(nwfilters,
|
||||
obj->def, filtername);
|
||||
|
||||
virNWFilterObjUnlock(obj);
|
||||
if (rc < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* virNWFilterDefLoopDetect:
|
||||
* @nwfilters : the nwfilters to search
|
||||
* @def : the filter definition that may add a loop and is to be tested
|
||||
*
|
||||
* Detect a loop introduced through the filters being able to
|
||||
* reference each other.
|
||||
*
|
||||
* Returns 0 in case no loop was detected, -1 otherwise.
|
||||
*/
|
||||
static int
|
||||
virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def)
|
||||
{
|
||||
return _virNWFilterDefLoopDetect(nwfilters, def, def->name);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
nwfilter->wantRemoved = 1;
|
||||
/* trigger the update on VMs referencing the filter */
|
||||
if (virNWFilterTriggerVMFilterRebuild())
|
||||
rc = -1;
|
||||
|
||||
nwfilter->wantRemoved = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool
|
||||
virNWFilterDefEqual(const virNWFilterDef *def1, virNWFilterDefPtr def2,
|
||||
bool cmpUUIDs)
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned char rem_uuid[VIR_UUID_BUFLEN];
|
||||
char *xml1, *xml2 = NULL;
|
||||
|
||||
if (!cmpUUIDs) {
|
||||
/* make sure the UUIDs are equal */
|
||||
memcpy(rem_uuid, def2->uuid, sizeof(rem_uuid));
|
||||
memcpy(def2->uuid, def1->uuid, sizeof(def2->uuid));
|
||||
}
|
||||
|
||||
if (!(xml1 = virNWFilterDefFormat(def1)) ||
|
||||
!(xml2 = virNWFilterDefFormat(def2)))
|
||||
goto cleanup;
|
||||
|
||||
ret = STREQ(xml1, xml2);
|
||||
|
||||
cleanup:
|
||||
if (!cmpUUIDs)
|
||||
memcpy(def2->uuid, rem_uuid, sizeof(rem_uuid));
|
||||
|
||||
VIR_FREE(xml1);
|
||||
VIR_FREE(xml2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
virNWFilterObjPtr
|
||||
virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def)
|
||||
{
|
||||
virNWFilterObjPtr nwfilter;
|
||||
|
||||
nwfilter = virNWFilterObjFindByUUID(nwfilters, def->uuid);
|
||||
|
||||
if (nwfilter) {
|
||||
if (STRNEQ(def->name, nwfilter->def->name)) {
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("filter with same UUID but different name "
|
||||
"('%s') already exists"),
|
||||
nwfilter->def->name);
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
} else {
|
||||
nwfilter = virNWFilterObjFindByName(nwfilters, def->name);
|
||||
if (nwfilter) {
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virUUIDFormat(nwfilter->def->uuid, uuidstr);
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("filter '%s' already exists with uuid %s"),
|
||||
def->name, uuidstr);
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (virNWFilterDefLoopDetect(nwfilters, def) < 0) {
|
||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
"%s", _("filter would introduce a loop"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((nwfilter = virNWFilterObjFindByName(nwfilters, def->name))) {
|
||||
|
||||
if (virNWFilterDefEqual(def, nwfilter->def, false)) {
|
||||
virNWFilterDefFree(nwfilter->def);
|
||||
nwfilter->def = def;
|
||||
return nwfilter;
|
||||
}
|
||||
|
||||
nwfilter->newDef = def;
|
||||
/* trigger the update on VMs referencing the filter */
|
||||
if (virNWFilterTriggerVMFilterRebuild()) {
|
||||
nwfilter->newDef = NULL;
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virNWFilterDefFree(nwfilter->def);
|
||||
nwfilter->def = def;
|
||||
nwfilter->newDef = NULL;
|
||||
return nwfilter;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(nwfilter) < 0)
|
||||
return NULL;
|
||||
|
||||
if (virMutexInitRecursive(&nwfilter->lock) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("cannot initialize mutex"));
|
||||
VIR_FREE(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
virNWFilterObjLock(nwfilter);
|
||||
nwfilter->active = 0;
|
||||
|
||||
if (VIR_APPEND_ELEMENT_COPY(nwfilters->objs,
|
||||
nwfilters->count, nwfilter) < 0) {
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
virNWFilterObjFree(nwfilter);
|
||||
return NULL;
|
||||
}
|
||||
nwfilter->def = def;
|
||||
|
||||
return nwfilter;
|
||||
}
|
||||
|
||||
|
||||
static virNWFilterObjPtr
|
||||
virNWFilterLoadConfig(virNWFilterObjListPtr nwfilters,
|
||||
const char *configDir,
|
||||
const char *name)
|
||||
{
|
||||
virNWFilterDefPtr def = NULL;
|
||||
virNWFilterObjPtr nwfilter;
|
||||
char *configFile = NULL;
|
||||
|
||||
if (!(configFile = virFileBuildPath(configDir, name, ".xml")))
|
||||
goto error;
|
||||
|
||||
if (!(def = virNWFilterDefParseFile(configFile)))
|
||||
goto error;
|
||||
|
||||
if (STRNEQ(name, def->name)) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("network filter config filename '%s' "
|
||||
"does not match name '%s'"),
|
||||
configFile, def->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* We generated a UUID, make it permanent by saving the config to disk */
|
||||
if (!def->uuid_specified &&
|
||||
virNWFilterSaveConfig(configDir, def) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(nwfilter = virNWFilterObjAssignDef(nwfilters, def)))
|
||||
goto error;
|
||||
|
||||
VIR_FREE(configFile);
|
||||
return nwfilter;
|
||||
|
||||
error:
|
||||
VIR_FREE(configFile);
|
||||
virNWFilterDefFree(def);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
|
||||
const char *configDir)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int ret = -1;
|
||||
int rc;
|
||||
|
||||
if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
|
||||
return rc;
|
||||
|
||||
while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
|
||||
virNWFilterObjPtr nwfilter;
|
||||
|
||||
if (!virFileStripSuffix(entry->d_name, ".xml"))
|
||||
continue;
|
||||
|
||||
nwfilter = virNWFilterLoadConfig(nwfilters, configDir, entry->d_name);
|
||||
if (nwfilter)
|
||||
virNWFilterObjUnlock(nwfilter);
|
||||
}
|
||||
|
||||
VIR_DIR_CLOSE(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void virNWFilterObjLock(virNWFilterObjPtr obj)
|
||||
{
|
||||
virMutexLock(&obj->lock);
|
||||
}
|
||||
|
||||
|
||||
void virNWFilterObjUnlock(virNWFilterObjPtr obj)
|
||||
{
|
||||
virMutexUnlock(&obj->lock);
|
||||
}
|
85
src/conf/virnwfilterobj.h
Normal file
85
src/conf/virnwfilterobj.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* virnwfilterobj.h: network filter object processing
|
||||
* (derived from nwfilter_conf.h)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef VIRNWFILTEROBJ_H
|
||||
# define VIRNWFILTEROBJ_H
|
||||
|
||||
# include "internal.h"
|
||||
|
||||
# include "nwfilter_conf.h"
|
||||
|
||||
typedef struct _virNWFilterObj virNWFilterObj;
|
||||
typedef virNWFilterObj *virNWFilterObjPtr;
|
||||
|
||||
struct _virNWFilterObj {
|
||||
virMutex lock;
|
||||
|
||||
int active;
|
||||
int wantRemoved;
|
||||
|
||||
virNWFilterDefPtr def;
|
||||
virNWFilterDefPtr newDef;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virNWFilterObjList virNWFilterObjList;
|
||||
typedef virNWFilterObjList *virNWFilterObjListPtr;
|
||||
struct _virNWFilterObjList {
|
||||
size_t count;
|
||||
virNWFilterObjPtr *objs;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virNWFilterDriverState virNWFilterDriverState;
|
||||
typedef virNWFilterDriverState *virNWFilterDriverStatePtr;
|
||||
struct _virNWFilterDriverState {
|
||||
virMutex lock;
|
||||
bool privileged;
|
||||
|
||||
virNWFilterObjList nwfilters;
|
||||
|
||||
char *configDir;
|
||||
bool watchingFirewallD;
|
||||
};
|
||||
|
||||
void virNWFilterObjListFree(virNWFilterObjListPtr nwfilters);
|
||||
|
||||
void virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterObjPtr nwfilter);
|
||||
|
||||
void virNWFilterObjFree(virNWFilterObjPtr obj);
|
||||
|
||||
virNWFilterObjPtr virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
|
||||
const unsigned char *uuid);
|
||||
|
||||
virNWFilterObjPtr virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters,
|
||||
const char *name);
|
||||
|
||||
virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
|
||||
virNWFilterDefPtr def);
|
||||
|
||||
int virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter);
|
||||
|
||||
int virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
|
||||
const char *configDir);
|
||||
|
||||
void virNWFilterObjLock(virNWFilterObjPtr obj);
|
||||
|
||||
void virNWFilterObjUnlock(virNWFilterObjPtr obj);
|
||||
|
||||
#endif /* VIRNWFILTEROBJ_H */
|
@ -746,14 +746,6 @@ virNWFilterDefParseString;
|
||||
virNWFilterDeleteDef;
|
||||
virNWFilterInstFiltersOnAllVMs;
|
||||
virNWFilterJumpTargetTypeToString;
|
||||
virNWFilterLoadAllConfigs;
|
||||
virNWFilterObjAssignDef;
|
||||
virNWFilterObjFindByName;
|
||||
virNWFilterObjFindByUUID;
|
||||
virNWFilterObjListFree;
|
||||
virNWFilterObjLock;
|
||||
virNWFilterObjRemove;
|
||||
virNWFilterObjUnlock;
|
||||
virNWFilterPrintStateMatchFlags;
|
||||
virNWFilterPrintTCPFlags;
|
||||
virNWFilterReadLockFilterUpdates;
|
||||
@ -765,7 +757,7 @@ virNWFilterRuleIsProtocolIPv4;
|
||||
virNWFilterRuleIsProtocolIPv6;
|
||||
virNWFilterRuleProtocolTypeToString;
|
||||
virNWFilterSaveDef;
|
||||
virNWFilterTestUnassignDef;
|
||||
virNWFilterTriggerVMFilterRebuild;
|
||||
virNWFilterUnlockFilterUpdates;
|
||||
virNWFilterUnRegisterCallbackDriver;
|
||||
virNWFilterWriteLockFilterUpdates;
|
||||
@ -964,6 +956,18 @@ virNodeDeviceObjRemove;
|
||||
virNodeDeviceObjUnlock;
|
||||
|
||||
|
||||
# conf/virnwfilterobj.h
|
||||
virNWFilterLoadAllConfigs;
|
||||
virNWFilterObjAssignDef;
|
||||
virNWFilterObjFindByName;
|
||||
virNWFilterObjFindByUUID;
|
||||
virNWFilterObjListFree;
|
||||
virNWFilterObjLock;
|
||||
virNWFilterObjRemove;
|
||||
virNWFilterObjUnlock;
|
||||
virNWFilterTestUnassignDef;
|
||||
|
||||
|
||||
# conf/virsecretobj.h
|
||||
virSecretLoadAllConfigs;
|
||||
virSecretObjDeleteConfig;
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "viralloc.h"
|
||||
#include "domain_conf.h"
|
||||
#include "domain_nwfilter.h"
|
||||
#include "nwfilter_conf.h"
|
||||
#include "nwfilter_driver.h"
|
||||
#include "nwfilter_gentech_driver.h"
|
||||
#include "configmake.h"
|
||||
|
@ -24,7 +24,7 @@
|
||||
#ifndef __NWFILTER_GENTECH_DRIVER_H
|
||||
# define __NWFILTER_GENTECH_DRIVER_H
|
||||
|
||||
# include "nwfilter_conf.h"
|
||||
# include "virnwfilterobj.h"
|
||||
# include "nwfilter_tech_driver.h"
|
||||
|
||||
virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char *name);
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef __NWFILTER_TECH_DRIVER_H__
|
||||
# define __NWFILTER_TECH_DRIVER_H__
|
||||
|
||||
# include "nwfilter_conf.h"
|
||||
# include "virnwfilterobj.h"
|
||||
|
||||
typedef struct _virNWFilterTechDriver virNWFilterTechDriver;
|
||||
typedef virNWFilterTechDriver *virNWFilterTechDriverPtr;
|
||||
|
Loading…
Reference in New Issue
Block a user