aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Berger <stefanb@us.ibm.com>2010-05-03 18:14:58 -0400
committerStefan Berger <stefanb@us.ibm.com>2010-05-03 18:14:58 -0400
commit018fd697b6a98230d007c2c729bdd2688c218ff6 (patch)
treeff81310cdea078f805bd750479ad0779aa14f1d0 /src/nwfilter/nwfilter_gentech_driver.c
parentpass info where request stems from to have rules applied (diff)
downloadlibvirt-018fd697b6a98230d007c2c729bdd2688c218ff6.tar.gz
libvirt-018fd697b6a98230d007c2c729bdd2688c218ff6.tar.bz2
libvirt-018fd697b6a98230d007c2c729bdd2688c218ff6.zip
nwfilter: skip some interfaces on filter update
When a filter is updated, only those interfaces must have their old rules cleared that either reference the filter directly or indirectly through another filter. Remember between the different steps of the instantiation of the filters which interfaces must be skipped. I am using a hash map to remember the names of the interfaces and store a bogus pointer to ~0 into it that need not be freed.
Diffstat (limited to 'src/nwfilter/nwfilter_gentech_driver.c')
-rw-r--r--src/nwfilter/nwfilter_gentech_driver.c66
1 files changed, 48 insertions, 18 deletions
diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c
index 515d381a1..494637354 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -316,7 +316,7 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
virNWFilterHashTablePtr vars,
int *nEntries,
virNWFilterRuleInstPtr **insts,
- enum instCase useNewFilter, int *foundNewFilter,
+ enum instCase useNewFilter, bool *foundNewFilter,
virNWFilterDriverStatePtr driver)
{
virNWFilterPoolObjPtr obj;
@@ -381,7 +381,7 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
case INSTANTIATE_FOLLOW_NEWFILTER:
if (obj->newDef) {
next_filter = obj->newDef;
- *foundNewFilter = 1;
+ *foundNewFilter = true;
}
break;
case INSTANTIATE_ALWAYS:
@@ -562,7 +562,7 @@ virNWFilterInstantiate(virConnectPtr conn,
int ifindex,
const char *linkdev,
virNWFilterHashTablePtr vars,
- enum instCase useNewFilter, int *foundNewFilter,
+ enum instCase useNewFilter, bool *foundNewFilter,
bool teardownOld,
const unsigned char *macaddr,
virNWFilterDriverStatePtr driver,
@@ -693,7 +693,8 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
virNWFilterHashTablePtr filterparams,
enum instCase useNewFilter,
virNWFilterDriverStatePtr driver,
- bool forceWithPendingReq)
+ bool forceWithPendingReq,
+ bool *foundNewFilter)
{
int rc;
const char *drvname = EBIPTABLES_DRIVER_ID;
@@ -702,7 +703,6 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
virNWFilterHashTablePtr vars, vars1;
virNWFilterDefPtr filter;
char vmmacaddr[VIR_MAC_STRING_BUFLEN] = {0};
- int foundNewFilter = 0;
char *str_macaddr = NULL;
const char *ipaddr;
char *str_ipaddr = NULL;
@@ -775,7 +775,7 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
case INSTANTIATE_FOLLOW_NEWFILTER:
if (obj->newDef) {
filter = obj->newDef;
- foundNewFilter = 1;
+ *foundNewFilter = true;
}
break;
@@ -791,7 +791,7 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
ifindex,
linkdev,
vars,
- useNewFilter, &foundNewFilter,
+ useNewFilter, foundNewFilter,
teardownOld,
macaddr,
driver,
@@ -816,7 +816,8 @@ static int
_virNWFilterInstantiateFilter(virConnectPtr conn,
const virDomainNetDefPtr net,
bool teardownOld,
- enum instCase useNewFilter)
+ enum instCase useNewFilter,
+ bool *foundNewFilter)
{
const char *linkdev = (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
? net->data.direct.linkdev
@@ -837,7 +838,8 @@ _virNWFilterInstantiateFilter(virConnectPtr conn,
net->filterparams,
useNewFilter,
conn->nwfilterPrivateData,
- false);
+ false,
+ foundNewFilter);
}
@@ -853,6 +855,8 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn,
virNWFilterDriverStatePtr driver)
{
int rc;
+ bool foundNewFilter = false;
+
rc = __virNWFilterInstantiateFilter(conn,
1,
ifname,
@@ -864,7 +868,8 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn,
filterparams,
INSTANTIATE_ALWAYS,
driver,
- true);
+ true,
+ &foundNewFilter);
if (rc) {
//something went wrong... 'DOWN' the interface
if (ifaceCheck(false, ifname, NULL, ifindex) != 0 ||
@@ -881,19 +886,29 @@ int
virNWFilterInstantiateFilter(virConnectPtr conn,
const virDomainNetDefPtr net)
{
+ bool foundNewFilter = false;
+
return _virNWFilterInstantiateFilter(conn, net,
1,
- INSTANTIATE_ALWAYS);
+ INSTANTIATE_ALWAYS,
+ &foundNewFilter);
}
int
virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
- const virDomainNetDefPtr net)
+ const virDomainNetDefPtr net,
+ bool *skipIface)
{
- return _virNWFilterInstantiateFilter(conn, net,
- 0,
- INSTANTIATE_FOLLOW_NEWFILTER);
+ bool foundNewFilter = false;
+
+ int rc = _virNWFilterInstantiateFilter(conn, net,
+ 0,
+ INSTANTIATE_FOLLOW_NEWFILTER,
+ &foundNewFilter);
+
+ *skipIface = !foundNewFilter;
+ return rc;
}
int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
@@ -993,6 +1008,7 @@ virNWFilterDomainFWUpdateCB(void *payload,
virDomainDefPtr vm = obj->def;
struct domUpdateCBStruct *cb = data;
int i;
+ bool skipIface;
virDomainObjLock(obj);
@@ -1003,15 +1019,29 @@ virNWFilterDomainFWUpdateCB(void *payload,
switch (cb->step) {
case STEP_APPLY_NEW:
cb->err = virNWFilterUpdateInstantiateFilter(cb->conn,
- net);
+ net,
+ &skipIface);
+ if (cb->err == 0 && skipIface == true) {
+ // filter tree unchanged -- no update needed
+ cb->err = virHashAddEntry(cb->skipInterfaces,
+ net->ifname,
+ (void *)~0);
+ if (cb->err)
+ virReportOOMError();
+ }
break;
case STEP_TEAR_NEW:
- cb->err = virNWFilterRollbackUpdateFilter(cb->conn, net);
+ if ( !virHashLookup(cb->skipInterfaces, net->ifname)) {
+ cb->err = virNWFilterRollbackUpdateFilter(cb->conn,
+ net);
+ }
break;
case STEP_TEAR_OLD:
- cb->err = virNWFilterTearOldFilter(cb->conn, net);
+ if ( !virHashLookup(cb->skipInterfaces, net->ifname)) {
+ cb->err = virNWFilterTearOldFilter(cb->conn, net);
+ }
break;
}
if (cb->err)