[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [libvirt PATCHv3 05/10] allow chain modification



	This patch adds the internal capability to add rules to existing
chains instead of using temporary chains and to generate placeholders for
chains that are referenced without generating a rule for them immediately.
Finally, it includes variable matching for filter instantiation
(i.e., instantiate only when a given variable is present in a filter, or
only when it is not).

Signed-off-by: David L Stevens <dlstevens us ibm com>
---
 src/conf/nwfilter_conf.h                  |    4 +-
 src/nwfilter/nwfilter_ebiptables_driver.c |   93 +++++++++++++++++++++--------
 src/nwfilter/nwfilter_gentech_driver.c    |   32 +++++++++-
 3 files changed, 100 insertions(+), 29 deletions(-)

diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 17e954e..4348378 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -525,7 +525,9 @@ typedef int (*virNWFilterRuleCreateInstance)(virConnectPtr conn,
                                              virNWFilterRuleDefPtr rule,
                                              const char *ifname,
                                              virNWFilterHashTablePtr vars,
-                                             virNWFilterRuleInstPtr res);
+                                             virNWFilterRuleInstPtr res,
+                                             bool usetemp,
+                                             bool dummy);
 
 typedef int (*virNWFilterRuleApplyNewRules)(virConnectPtr conn,
                                             const char *ifname,
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c
index e6a4880..918625c 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -1136,6 +1136,7 @@ iptablesEnforceDirection(int directionIn,
  * @isIPv6 : Whether this is an IPv6 rule
  * @maySkipICMP : whether this rule may under certain circumstances skip
  *           the ICMP rule from being created
+ * @dummy : generate rule placeholder without installing
  *
  * Convert a single rule into its representation for later instantiation
  *
@@ -1154,7 +1155,8 @@ _iptablesCreateRuleInstance(int directionIn,
                             const char *match, bool defMatch,
                             const char *accept_target,
                             bool isIPv6,
-                            bool maySkipICMP)
+                            bool maySkipICMP,
+                            bool dummy)
 {
     char chain[MAX_CHAINNAME_LENGTH];
     char number[20];
@@ -1181,6 +1183,13 @@ _iptablesCreateRuleInstance(int directionIn,
 
     PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
 
+    if (dummy) {
+        virBufferAsprintf(&buf, CMD_DEF_PRE "%s -- %s -%%c %s %%s",
+                          "echo", iptables_cmd, chain);
+        bufUsed = virBufferUse(&buf);
+        goto prskip;
+    }
+
     switch (rule->prtclType) {
     case VIR_NWFILTER_RULE_PROTOCOL_TCP:
     case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6:
@@ -1521,6 +1530,8 @@ _iptablesCreateRuleInstance(int directionIn,
         return -1;
     }
 
+prskip:
+
     if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) ||
          skipRule) {
         virBufferFreeAndReset(&buf);
@@ -1636,7 +1647,9 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
                                     const char *ifname,
                                     virNWFilterHashTablePtr vars,
                                     virNWFilterRuleInstPtr res,
-                                    bool isIPv6)
+                                    bool isIPv6,
+                                    bool usetemp,
+                                    bool dummy)
 {
     int rc;
     int directionIn = 0;
@@ -1668,7 +1681,7 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
             return 1;
     }
 
-    chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
+    chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN;
     if (create) {
         rc = _iptablesCreateRuleInstance(directionIn,
                                          chainPrefix,
@@ -1680,7 +1693,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
                                          matchState, false,
                                          "RETURN",
                                          isIPv6,
-                                         maySkipICMP);
+                                         maySkipICMP,
+                                         dummy);
 
         VIR_FREE(matchState);
         if (rc)
@@ -1700,7 +1714,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
             return 1;
     }
 
-    chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP;
+    chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_OUT_TEMP :
+                     CHAINPREFIX_HOST_OUT;
     if (create) {
         rc = _iptablesCreateRuleInstance(!directionIn,
                                          chainPrefix,
@@ -1712,7 +1727,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
                                          matchState, false,
                                          "ACCEPT",
                                          isIPv6,
-                                         maySkipICMP);
+                                         maySkipICMP,
+                                         dummy);
 
         VIR_FREE(matchState);
 
@@ -1736,7 +1752,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
 
     if (create) {
         chainPrefix[0] = 'H';
-        chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
+        chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP :
+                         CHAINPREFIX_HOST_IN;
         rc = _iptablesCreateRuleInstance(directionIn,
                                          chainPrefix,
                                          nwfilter,
@@ -1747,7 +1764,8 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
                                          matchState, false,
                                          "RETURN",
                                          isIPv6,
-                                         maySkipICMP);
+                                         maySkipICMP,
+                                         dummy);
         VIR_FREE(matchState);
     }
 
@@ -1761,7 +1779,9 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
                            const char *ifname,
                            virNWFilterHashTablePtr vars,
                            virNWFilterRuleInstPtr res,
-                           bool isIPv6)
+                           bool isIPv6,
+                           bool usetemp,
+                           bool dummy)
 {
     int rc;
     int directionIn = 0;
@@ -1777,7 +1797,9 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
                                                    ifname,
                                                    vars,
                                                    res,
-                                                   isIPv6);
+                                                   isIPv6,
+                                                   usetemp,
+                                                   dummy);
     }
 
     if ((rule->tt == VIR_NWFILTER_RULE_DIRECTION_IN) ||
@@ -1800,7 +1822,7 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
     else
         matchState = NULL;
 
-    chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
+    chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN;
     rc = _iptablesCreateRuleInstance(directionIn,
                                      chainPrefix,
                                      nwfilter,
@@ -1811,7 +1833,8 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
                                      matchState, true,
                                      "RETURN",
                                      isIPv6,
-                                     maySkipICMP);
+                                     maySkipICMP,
+                                     dummy);
     if (rc)
         return rc;
 
@@ -1822,7 +1845,7 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
     else
         matchState = NULL;
 
-    chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP;
+    chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_OUT_TEMP : CHAINPREFIX_HOST_OUT;
     rc = _iptablesCreateRuleInstance(!directionIn,
                                      chainPrefix,
                                      nwfilter,
@@ -1833,7 +1856,8 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
                                      matchState, true,
                                      "ACCEPT",
                                      isIPv6,
-                                     maySkipICMP);
+                                     maySkipICMP,
+                                     dummy);
     if (rc)
         return rc;
 
@@ -1844,7 +1868,7 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
         matchState = NULL;
 
     chainPrefix[0] = 'H';
-    chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
+    chainPrefix[1] = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN;
     rc = _iptablesCreateRuleInstance(directionIn,
                                      chainPrefix,
                                      nwfilter,
@@ -1855,7 +1879,8 @@ iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
                                      matchState, true,
                                      "RETURN",
                                      isIPv6,
-                                     maySkipICMP);
+                                     maySkipICMP,
+                                     dummy);
 
     return rc;
 }
@@ -1886,7 +1911,8 @@ ebtablesCreateRuleInstance(char chainPrefix,
                            const char *ifname,
                            virNWFilterHashTablePtr vars,
                            virNWFilterRuleInstPtr res,
-                           bool reverse)
+                           bool reverse,
+                           bool dummy)
 {
     char macaddr[VIR_MAC_STRING_BUFLEN],
          ipaddr[INET_ADDRSTRLEN],
@@ -1909,6 +1935,11 @@ ebtablesCreateRuleInstance(char chainPrefix,
         PRINT_CHAIN(chain, chainPrefix, ifname,
                     virNWFilterChainSuffixTypeToString(nwfilter->chainsuffix));
 
+    if (dummy) {
+        virBufferAsprintf(&buf, CMD_DEF_PRE "%s -- -t %s -%%c %s %%s",
+                          "echo", EBTABLES_DEFAULT_TABLE, chain);
+        goto prskip;
+    }
 
     switch (rule->prtclType) {
     case VIR_NWFILTER_RULE_PROTOCOL_MAC:
@@ -2317,6 +2348,8 @@ ebtablesCreateRuleInstance(char chainPrefix,
         return -1;
     }
 
+prskip:
+
     switch (rule->action) {
     case VIR_NWFILTER_RULE_ACTION_REJECT:
         /* REJECT not supported */
@@ -2374,11 +2407,15 @@ ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
                              virNWFilterRuleDefPtr rule,
                              const char *ifname,
                              virNWFilterHashTablePtr vars,
-                             virNWFilterRuleInstPtr res)
+                             virNWFilterRuleInstPtr res,
+                             bool usetemp,
+                             bool dummy)
 {
     int rc = 0;
     bool isIPv6;
+    char chainPrefix;
 
+    chainPrefix = usetemp ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_IN;
     switch (rule->prtclType) {
     case VIR_NWFILTER_RULE_PROTOCOL_IP:
     case VIR_NWFILTER_RULE_PROTOCOL_MAC:
@@ -2389,26 +2426,30 @@ ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
 
         if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
             rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
-            rc = ebtablesCreateRuleInstance(CHAINPREFIX_HOST_IN_TEMP,
+            rc = ebtablesCreateRuleInstance(chainPrefix,
                                             nwfilter,
                                             rule,
                                             ifname,
                                             vars,
                                             res,
-                                            rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT);
+                                            rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT,
+                                            dummy);
             if (rc)
                 return rc;
         }
 
+        chainPrefix = usetemp ? CHAINPREFIX_HOST_OUT_TEMP :
+                      CHAINPREFIX_HOST_OUT;
         if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_IN ||
             rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
-            rc = ebtablesCreateRuleInstance(CHAINPREFIX_HOST_OUT_TEMP,
+            rc = ebtablesCreateRuleInstance(chainPrefix,
                                             nwfilter,
                                             rule,
                                             ifname,
                                             vars,
                                             res,
-                                            false);
+                                            false,
+                                            dummy);
         }
     break;
 
@@ -2427,7 +2468,9 @@ ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
                                         ifname,
                                         vars,
                                         res,
-                                        isIPv6);
+                                        isIPv6,
+                                        usetemp,
+                                        dummy);
     break;
 
     case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6:
@@ -2444,7 +2487,9 @@ ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
                                         ifname,
                                         vars,
                                         res,
-                                        isIPv6);
+                                        isIPv6,
+                                        usetemp,
+                                        dummy);
     break;
 
     case VIR_NWFILTER_RULE_PROTOCOL_LAST:
diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c
index 7891983..79350ac 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -284,7 +284,9 @@ virNWFilterRuleInstantiate(virConnectPtr conn,
                            virNWFilterDefPtr filter,
                            virNWFilterRuleDefPtr rule,
                            const char *ifname,
-                           virNWFilterHashTablePtr vars)
+                           virNWFilterHashTablePtr vars,
+                           bool usetemp,
+                           bool dummy)
 {
     int rc;
     int i;
@@ -297,8 +299,8 @@ virNWFilterRuleInstantiate(virConnectPtr conn,
 
     ret->techdriver = techdriver;
 
-    rc = techdriver->createRuleInstance(conn, nettype, filter,
-                                        rule, ifname, vars, ret);
+    rc = techdriver->createRuleInstance(conn, nettype, filter, rule, ifname,
+                                        vars, ret, usetemp, dummy);
 
     if (rc) {
         for (i = 0; i < ret->ndata; i++)
@@ -354,6 +356,8 @@ err_exit:
  * @ifname: The name of the interface to apply the rules to
  * @vars: A map holding variable names and values used for instantiating
  *  the filter and its subfilters.
+ * @matchvar: if non-null, variable name to match
+ * @notmatch: if matchvar set, match filters that do not reference matchvar
  * @nEntries: number of virNWFilterInst objects collected
  * @insts: pointer to array for virNWFilterIns object pointers
  * @useNewFilter: instruct whether to use a newDef pointer rather than a
@@ -377,6 +381,8 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
                            virNWFilterDefPtr filter,
                            const char *ifname,
                            virNWFilterHashTablePtr vars,
+                           const char *matchvar,
+                           bool notmatch,
                            int *nEntries,
                            virNWFilterRuleInstPtr **insts,
                            enum instCase useNewFilter, bool *foundNewFilter,
@@ -387,18 +393,34 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
     int i;
     virNWFilterRuleInstPtr inst;
     virNWFilterDefPtr next_filter;
+    bool usetemp, dummy;
 
     for (i = 0; i < filter->nentries; i++) {
         virNWFilterRuleDefPtr    rule = filter->filterEntries[i]->rule;
         virNWFilterIncludeDefPtr inc  = filter->filterEntries[i]->include;
         if (rule) {
+            usetemp = 1;
+            dummy = 0;
+            if (matchvar) {
+                int j;
+
+                for (j = 0; j < rule->nvars; ++j)
+                     if (strcmp(rule->vars[j], matchvar) == 0)
+                         break;
+                /* use temp chains only on base rule install */
+                usetemp = notmatch;
+                /* skip if not found; notmatch reverses the sense */
+                dummy = (j == rule->nvars) ^ notmatch;
+            }
             inst = virNWFilterRuleInstantiate(conn,
                                               techdriver,
                                               nettype,
                                               filter,
                                               rule,
                                               ifname,
-                                              vars);
+                                              vars,
+                                              usetemp,
+                                              dummy);
             if (!inst) {
                 rc = 1;
                 break;
@@ -456,6 +478,7 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
                                                 next_filter,
                                                 ifname,
                                                 tmpvars,
+                                                matchvar, notmatch,
                                                 nEntries, insts,
                                                 useNewFilter,
                                                 foundNewFilter,
@@ -684,6 +707,7 @@ virNWFilterInstantiate(virConnectPtr conn,
                                     filter,
                                     ifname,
                                     vars,
+                                    0, 0,
                                     &nEntries, &insts,
                                     useNewFilter, foundNewFilter,
                                     driver);
-- 
1.7.6.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]