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 <[email protected]>
> ---
> 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.