Re: [PATCH 2/2 nft] src: allow variable in chain policy

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

 



On Mon, Jul 22, 2019 at 06:02:39PM +0200, Fernando Fernandez Mancera wrote:
> This patch introduces the use of nft input files variables in chain policy.
> e.g.
> 
> define default_policy = "accept"
> 
> add table ip foo
> add chain ip foo bar {type filter hook input priority filter; policy $default_policy}
> 
> table ip foo {
> 	chain bar {
> 		type filter hook input priority filter; policy accept;
> 	}
> }
> 
> Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
> ---
>  include/rule.h                                |  2 +-
>  src/evaluate.c                                | 51 +++++++++++++++++++
>  src/json.c                                    |  5 +-
>  src/mnl.c                                     |  9 ++--
>  src/netlink.c                                 |  8 ++-
>  src/parser_bison.y                            | 19 +++++--
>  src/parser_json.c                             | 17 +++++--
>  src/rule.c                                    | 13 +++--
>  .../testcases/nft-f/0025policy_variable_0     | 17 +++++++
>  .../testcases/nft-f/0026policy_variable_0     | 17 +++++++
>  .../testcases/nft-f/0027policy_variable_1     | 18 +++++++
>  .../testcases/nft-f/0028policy_variable_1     | 18 +++++++
>  .../nft-f/dumps/0025policy_variable_0.nft     |  5 ++
>  .../nft-f/dumps/0026policy_variable_0.nft     |  5 ++
>  14 files changed, 186 insertions(+), 18 deletions(-)
>  create mode 100755 tests/shell/testcases/nft-f/0025policy_variable_0
>  create mode 100755 tests/shell/testcases/nft-f/0026policy_variable_0
>  create mode 100755 tests/shell/testcases/nft-f/0027policy_variable_1
>  create mode 100755 tests/shell/testcases/nft-f/0028policy_variable_1
>  create mode 100644 tests/shell/testcases/nft-f/dumps/0025policy_variable_0.nft
>  create mode 100644 tests/shell/testcases/nft-f/dumps/0026policy_variable_0.nft
> 
> diff --git a/include/rule.h b/include/rule.h
> index c6e8716..b12165a 100644
> --- a/include/rule.h
> +++ b/include/rule.h
> @@ -209,7 +209,7 @@ struct chain {
>  	const char		*hookstr;
>  	unsigned int		hooknum;
>  	struct prio_spec	priority;
> -	int			policy;
> +	struct expr		*policy;
>  	const char		*type;
>  	const char		*dev;
>  	struct scope		scope;
> diff --git a/src/evaluate.c b/src/evaluate.c
> index d2faee8..4d8bfbf 100755
> --- a/src/evaluate.c
> +++ b/src/evaluate.c
> @@ -3415,6 +3415,52 @@ static uint32_t str2hooknum(uint32_t family, const char *hook)
>  	return NF_INET_NUMHOOKS;
>  }
>  
> +static bool evaluate_policy(struct eval_ctx *ctx, struct expr **policy)

better rename static bool ...(..., struct expr **exprp)

> +{
> +	char policy_str[NFT_NAME_MAXLEN];
> +	struct location loc;
> +	int policy_num;

so you can use 'int policy;'.

> +	ctx->ectx.len = NFT_NAME_MAXLEN * BITS_PER_BYTE;
> +	if (expr_evaluate(ctx, policy) < 0)
> +		return false;

probably cache this here:

        expr = *exprp;

so you don't need:

        (*expr)->...

in all this code below.

> +	if ((*policy)->etype != EXPR_VALUE) {
> +		expr_error(ctx->msgs, *policy, "%s is not a valid "
> +			   "policy expression", expr_name(*policy));
> +		return false;
> +	}
> +
> +	if ((*policy)->dtype->type == TYPE_STRING) {
> +		mpz_export_data(policy_str, (*policy)->value,
> +				BYTEORDER_HOST_ENDIAN,
> +				NFT_NAME_MAXLEN);
> +		loc = (*policy)->location;
> +		if (!strcmp(policy_str, "accept")) {
> +			expr_free(*policy);
> +			policy_num = NF_ACCEPT;
> +			*policy = constant_expr_alloc(&loc,
> +						      &integer_type,
> +						      BYTEORDER_HOST_ENDIAN,
> +						      sizeof(int) * BITS_PER_BYTE,
> +						      &policy_num);
> +		} else if (!strcmp(policy_str, "drop")) {
> +			expr_free(*policy);
> +			policy_num = NF_DROP;
> +			*policy = constant_expr_alloc(&(*policy)->location,
> +						      &integer_type,
> +						      BYTEORDER_HOST_ENDIAN,
> +						      sizeof(int) * BITS_PER_BYTE,
> +						      &policy_num);

Probably:

		if (!strcmp(policy_str, "accept")) {
                        policy = NF_ACCEPT;
                else (!strmp(policy_str, "drop")) {
                        policy = NF_DROP;
                } else {
                        ...
                }

                expr = constant_expr_alloc(...);

so this code becomes shorter and easier to read.

And I think you should do all this from the new policy_datype, not
from the evaluation phase itself.

Thanks.



[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux