[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