mirror of
https://github.com/libvirt/libvirt.git
synced 2026-10-02 12:20:06 -05:00
nwfilter: add used firewall backend to nwfilterbinding
Updates nwfilterbinding.rng to support the 'backend' XML element. Defaults the def->backend field to the existing ebiptables firewall backend inside nwfilter_gentech_driver.c. This new element allows us to check the definition's firewall backend against the current firewall backend and remove old existing rules via the previous firewall backend. This switch between firewall backends happens inside virNWFilterSwitchTechDriver. Updated virnwfilterbindingxml2xmltest to test parsing and formatting of the new nwfilterbinding backend element. Signed-off-by: Dion Bosschieter <dionbosschieter@gmail.com>
This commit is contained in:
1 parent
eb65962fb6
commit
78b183d578
8 files changed
+100
-17
No files matched your search
@@ -44,6 +44,13 @@
|
||||
<element name="filterref">
|
||||
<ref name="filterref-node-attributes"/>
|
||||
</element>
|
||||
|
||||
<optional>
|
||||
<element name="backend">
|
||||
<attribute name="name"/>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "virnwfilterbindingdef.h"
|
||||
#include "viruuid.h"
|
||||
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
||||
|
||||
void
|
||||
@@ -40,6 +39,7 @@ virNWFilterBindingDefFree(virNWFilterBindingDef *def)
|
||||
g_free(def->linkdevname);
|
||||
g_free(def->filter);
|
||||
g_clear_pointer(&def->filterparams, g_hash_table_unref);
|
||||
g_free(def->backend);
|
||||
|
||||
g_free(def);
|
||||
}
|
||||
@@ -67,6 +67,8 @@ virNWFilterBindingDefCopy(virNWFilterBindingDef *src)
|
||||
if (virNWFilterHashTablePutAll(src->filterparams, ret->filterparams) < 0)
|
||||
return NULL;
|
||||
|
||||
ret->backend = g_strdup(src->backend);
|
||||
|
||||
return g_steal_pointer(&ret);
|
||||
}
|
||||
|
||||
@@ -143,8 +145,18 @@ virNWFilterBindingDefParseXML(xmlXPathContextPtr ctxt)
|
||||
|
||||
node = virXPathNode("./filterref", ctxt);
|
||||
if (node &&
|
||||
!(ret->filterparams = virNWFilterParseParamAttributes(node)))
|
||||
!(ret->filterparams = virNWFilterParseParamAttributes(node))) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virXPathNode("./backend", ctxt)) {
|
||||
ret->backend = virXPathString("string(./backend/@name)", ctxt);
|
||||
if (!ret->backend) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("filter binding has no firewall backend name"));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -211,6 +223,7 @@ virNWFilterBindingDefFormatBuf(virBuffer *buf,
|
||||
if (virNWFilterFormatParamAttributes(buf, def->filterparams, def->filter) < 0)
|
||||
return -1;
|
||||
|
||||
virBufferEscapeString(buf, "<backend name='%s'/>\n", def->backend);
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</filterbinding>\n");
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ struct _virNWFilterBindingDef {
|
||||
virMacAddr mac;
|
||||
char *filter;
|
||||
GHashTable *filterparams;
|
||||
char *backend;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -725,6 +725,7 @@ nwfilterBindingCreateXML(virConnectPtr conn,
|
||||
def = virNWFilterBindingDefParse(xml, NULL, flags);
|
||||
if (!def)
|
||||
return NULL;
|
||||
def->backend = g_strdup(virFirewallBackendTypeToString(cfg->firewallBackend));
|
||||
|
||||
if (virNWFilterBindingCreateXMLEnsureACL(conn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@@ -70,6 +70,20 @@ int virNWFilterTechDriversInit(bool privileged, virNWFilterDriverConfig *config)
|
||||
}
|
||||
|
||||
|
||||
static virNWFilterTechDriver *
|
||||
virNWFilterTechDriversByName(const char *firewallBackend)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) {
|
||||
if (STREQ(filter_tech_drivers[i]->name, firewallBackend))
|
||||
return filter_tech_drivers[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void virNWFilterTechDriversShutdown(void)
|
||||
{
|
||||
size_t i = 0;
|
||||
@@ -786,6 +800,33 @@ virNWFilterRollbackUpdateFilter(virNWFilterBindingDef *binding)
|
||||
return techdriver->tearNewRules(binding->portdevname);
|
||||
}
|
||||
|
||||
static int
|
||||
virNWFilterSwitchTechDriver(virNWFilterDriverState *driver,
|
||||
virNWFilterBindingObj *binding,
|
||||
virNWFilterBindingDef *def)
|
||||
{
|
||||
int ret = 0;
|
||||
virNWFilterTechDriver *oldTechDriver = virNWFilterTechDriversByName(def->backend);
|
||||
g_autoptr(virNWFilterDriverConfig) cfg = virNWFilterDriverGetConfig(driver);
|
||||
|
||||
VIR_DEBUG("Detected change in nwfilter firewall backend '%1$s' -> '%2$s', cleaning up '%1$s'",
|
||||
def->backend,
|
||||
virFirewallBackendTypeToString(driver->config->firewallBackend));
|
||||
|
||||
// first we'll apply the rules with the new tech driver
|
||||
if ((ret = virNWFilterInstantiateFilter(driver, def)) < 0)
|
||||
return ret;
|
||||
|
||||
// then we'll cleanup the rules from the old driver
|
||||
if ((ret = oldTechDriver->allTeardown(def->portdevname)) < 0)
|
||||
return ret;
|
||||
|
||||
// update binding backend
|
||||
def->backend = g_strdup(virFirewallBackendTypeToString(driver->config->firewallBackend));
|
||||
|
||||
// save changed binding xml file
|
||||
return virNWFilterBindingObjSave(binding, cfg->bindingDir);
|
||||
}
|
||||
|
||||
static int
|
||||
virNWFilterTearOldFilter(virNWFilterBindingDef *binding)
|
||||
@@ -854,40 +895,49 @@ enum {
|
||||
|
||||
static int
|
||||
virNWFilterBuildOne(virNWFilterDriverState *driver,
|
||||
virNWFilterBindingDef *binding,
|
||||
virNWFilterBindingObj *binding,
|
||||
GHashTable *skipInterfaces,
|
||||
int step)
|
||||
{
|
||||
bool skipIface;
|
||||
int ret = 0;
|
||||
VIR_DEBUG("Building filter for portdev=%s step=%d", binding->portdevname, step);
|
||||
virNWFilterBindingDef *def = virNWFilterBindingObjGetDef(binding);
|
||||
|
||||
VIR_DEBUG("Building filter for portdev=%s step=%d", def->portdevname, step);
|
||||
|
||||
switch (step) {
|
||||
case STEP_APPLY_NEW:
|
||||
ret = virNWFilterUpdateInstantiateFilter(driver,
|
||||
binding,
|
||||
def,
|
||||
&skipIface);
|
||||
if (ret == 0 && skipIface) {
|
||||
/* filter tree unchanged -- no update needed */
|
||||
ret = virHashAddEntry(skipInterfaces,
|
||||
binding->portdevname,
|
||||
def->portdevname,
|
||||
(void *)~0);
|
||||
}
|
||||
break;
|
||||
|
||||
case STEP_ROLLBACK:
|
||||
if (!virHashLookup(skipInterfaces, binding->portdevname))
|
||||
ret = virNWFilterRollbackUpdateFilter(binding);
|
||||
if (!virHashLookup(skipInterfaces, def->portdevname))
|
||||
ret = virNWFilterRollbackUpdateFilter(def);
|
||||
break;
|
||||
|
||||
case STEP_SWITCH:
|
||||
if (!virHashLookup(skipInterfaces, binding->portdevname))
|
||||
ret = virNWFilterTearOldFilter(binding);
|
||||
if (!virHashLookup(skipInterfaces, def->portdevname))
|
||||
ret = virNWFilterTearOldFilter(def);
|
||||
break;
|
||||
|
||||
case STEP_APPLY_CURRENT:
|
||||
ret = virNWFilterInstantiateFilter(driver,
|
||||
binding);
|
||||
// prev is always ebiptables if unset
|
||||
if (def->backend == NULL)
|
||||
def->backend = g_strdup(ebiptables_driver.name);
|
||||
|
||||
// detect change in backend
|
||||
if (STRNEQ(def->backend,
|
||||
virFirewallBackendTypeToString(driver->config->firewallBackend))) {
|
||||
ret = virNWFilterSwitchTechDriver(driver, binding, def);
|
||||
} else {
|
||||
ret = virNWFilterInstantiateFilter(driver, def);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -905,9 +955,8 @@ static int
|
||||
virNWFilterBuildIter(virNWFilterBindingObj *binding, void *opaque)
|
||||
{
|
||||
struct virNWFilterBuildData *data = opaque;
|
||||
virNWFilterBindingDef *def = virNWFilterBindingObjGetDef(binding);
|
||||
|
||||
return virNWFilterBuildOne(data->driver, def,
|
||||
return virNWFilterBuildOne(data->driver, binding,
|
||||
data->skipInterfaces, data->step);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
<filterref filter='clean-traffic'>
|
||||
<parameter name='MAC' value='52:54:00:7b:35:93'/>
|
||||
</filterref>
|
||||
<backend name='iptables'/>
|
||||
</filterbinding>
|
||||
@@ -0,0 +1,10 @@
|
||||
<filterbinding>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<portdev name='vnet0'/>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
<filterref filter='clean-traffic'/>
|
||||
<backend name='iptables'/>
|
||||
</filterbinding>
|
||||
@@ -92,6 +92,7 @@ mymain(void)
|
||||
} while (0)
|
||||
|
||||
DO_TEST("simple");
|
||||
DO_TEST("simple-backend");
|
||||
DO_TEST("filter-vars");
|
||||
|
||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
|
||||
Reference in new issue
Block a user