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

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Oct 17 16:07:12 UTC 2011


On 10/12/2011 03:50 PM, David L Stevens wrote:
> 	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).
>
Following the above I am not sure what this will be used for as part of 
this extension.

> Signed-off-by: David L Stevens<dlstevens at 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);
As above in the iptables case you should also add the ebtables_cmd into 
the string (... %s -t %s ...).
> +        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
Can you write what happens if a match occurs versus if it does not occur?
>    * @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);




More information about the libvir-list mailing list