]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
nwfilter: skip some interfaces on filter update
authorStefan Berger <stefanb@us.ibm.com>
Mon, 3 May 2010 22:14:58 +0000 (18:14 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Mon, 3 May 2010 22:14:58 +0000 (18:14 -0400)
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.

src/conf/nwfilter_conf.c
src/conf/nwfilter_conf.h
src/nwfilter/nwfilter_gentech_driver.c
src/nwfilter/nwfilter_gentech_driver.h

index a8a6a78ab6834eee1405eafbaa2421842f8a9b1b..ea73a33e0fcc56ef989894ddf9066639bc5da957 100644 (file)
@@ -2088,8 +2088,14 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
         .conn = conn,
         .err = 0,
         .step = STEP_APPLY_NEW,
+        .skipInterfaces = virHashCreate(0),
     };
 
+    if (!cb.skipInterfaces) {
+        virReportOOMError();
+        return 1;
+    }
+
     for (i = 0; i < nCallbackDriver; i++) {
         callbackDrvArray[i]->vmFilterRebuild(conn,
                                              virNWFilterDomainFWUpdateCB,
@@ -2115,6 +2121,8 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
                                                  &cb);
     }
 
+    virHashFree(cb.skipInterfaces, NULL);
+
     return err;
 }
 
index 3aef3fb1100d824a397e79b0226fa0435cf58e4b..b7b62adc33b7fddd24090f0b1cb404c47e86382f 100644 (file)
@@ -471,6 +471,7 @@ struct domUpdateCBStruct {
     virConnectPtr conn;
     enum UpdateStep step;
     int err;
+    virHashTablePtr skipInterfaces;
 };
 
 
index 515d381a184511ce5dd98c83c17e3dc27e02dc76..494637354e211563fbe3ea9bb8acf554c976f7f7 100644 (file)
@@ -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)
index 646a558d2958c2140d4f6fa26ddb68dc3035a441..7328c516e3767049e4bcc156ef28a17584307af4 100644 (file)
@@ -40,7 +40,8 @@ enum instCase {
 int virNWFilterInstantiateFilter(virConnectPtr conn,
                                  const virDomainNetDefPtr net);
 int virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
-                                       const virDomainNetDefPtr net);
+                                       const virDomainNetDefPtr net,
+                                       bool *skipIface);
 int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
                                     const virDomainNetDefPtr net);