netfilter: nf_tables: validate the expr explicitly after init successfully
authorLiping Zhang <zlpnobody@gmail.com>
Sun, 5 Mar 2017 13:02:23 +0000 (21:02 +0800)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 6 Mar 2017 17:22:12 +0000 (18:22 +0100)
When we want to validate the expr's dependency or hooks, we must do two
things to accomplish it. First, write a X_validate callback function
and point ->validate to it. Second, call X_validate in init routine.
This is very common, such as fib, nat, reject expr and so on ...

It is a little ugly, since we will call X_validate in the expr's init
routine, it's better to do it in nf_tables_newexpr. So we can avoid to
do this again and again. After doing this, the second step listed above
is not useful anymore, remove them now.

Patch was tested by nftables/tests/py/nft-test.py and
nftables/tests/shell/run-tests.sh.

Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/bridge/netfilter/nft_reject_bridge.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_compat.c
net/netfilter/nft_fib.c
net/netfilter/nft_masq.c
net/netfilter/nft_meta.c
net/netfilter/nft_nat.c
net/netfilter/nft_redir.c
net/netfilter/nft_reject.c
net/netfilter/nft_reject_inet.c

index 206dc266ecd237c2874d25352dd631e3bc31b002..346ef6b00b8f05b62edc911d06c01692624596d9 100644 (file)
@@ -375,11 +375,7 @@ static int nft_reject_bridge_init(const struct nft_ctx *ctx,
                                  const struct nlattr * const tb[])
 {
        struct nft_reject *priv = nft_expr_priv(expr);
-       int icmp_code, err;
-
-       err = nft_reject_bridge_validate(ctx, expr, NULL);
-       if (err < 0)
-               return err;
+       int icmp_code;
 
        if (tb[NFTA_REJECT_TYPE] == NULL)
                return -EINVAL;
index 5e0ccfd5bb37d1cbebb7e03b0998b7c24cca024d..fd8789eccc926a76f4779b1788f4f651382cb3fc 100644 (file)
@@ -1772,8 +1772,19 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx,
                        goto err1;
        }
 
+       if (ops->validate) {
+               const struct nft_data *data = NULL;
+
+               err = ops->validate(ctx, expr, &data);
+               if (err < 0)
+                       goto err2;
+       }
+
        return 0;
 
+err2:
+       if (ops->destroy)
+               ops->destroy(ctx, expr);
 err1:
        expr->ops = NULL;
        return err;
index c21e7eb8dce02a6b73c5a466300ae793a2787b26..fab6bf3f955ed0a9251b4dfc72b41e5948fa4a21 100644 (file)
@@ -230,10 +230,6 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
        union nft_entry e = {};
        int ret;
 
-       ret = nft_compat_chain_validate_dependency(target->table, ctx->chain);
-       if (ret < 0)
-               goto err;
-
        target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
 
        if (ctx->nla[NFTA_RULE_COMPAT]) {
@@ -419,10 +415,6 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
        union nft_entry e = {};
        int ret;
 
-       ret = nft_compat_chain_validate_dependency(match->table, ctx->chain);
-       if (ret < 0)
-               goto err;
-
        match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
 
        if (ctx->nla[NFTA_RULE_COMPAT]) {
index 29a4906adc277cd3a2cf55242224e4c99fd070e7..fd0b19303b0db89faa316f9c9e47ced69cbae3fd 100644 (file)
@@ -112,7 +112,7 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
        if (err < 0)
                return err;
 
-       return nft_fib_validate(ctx, expr, NULL);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(nft_fib_init);
 
index 11ce016cd47948f3a2902402e0cbbda5e22d9438..6ac03d4266c9038cb4ffd3de412a216b769d07a1 100644 (file)
@@ -46,10 +46,6 @@ int nft_masq_init(const struct nft_ctx *ctx,
        struct nft_masq *priv = nft_expr_priv(expr);
        int err;
 
-       err = nft_masq_validate(ctx, expr, NULL);
-       if (err)
-               return err;
-
        if (tb[NFTA_MASQ_FLAGS]) {
                priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
                if (priv->flags & ~NF_NAT_RANGE_MASK)
index e1f5ca9b423b5ffda43ec5519d4c8832ce695899..d14417aaf5d43a4f39f0b752b938fcef218833c2 100644 (file)
@@ -370,10 +370,6 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
                return -EOPNOTSUPP;
        }
 
-       err = nft_meta_set_validate(ctx, expr, NULL);
-       if (err < 0)
-               return err;
-
        priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
        err = nft_validate_register_load(priv->sreg, len);
        if (err < 0)
index 19a7bf3236f968725a29e827012af301781802df..26a74dfb3b7acb85ad523117fdda7146b3706b16 100644 (file)
@@ -138,10 +138,6 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
                return -EINVAL;
        }
 
-       err = nft_nat_validate(ctx, expr, NULL);
-       if (err < 0)
-               return err;
-
        if (tb[NFTA_NAT_FAMILY] == NULL)
                return -EINVAL;
 
index 40dcd05146d5fb0f346e6e170d16de9813e92804..1e66538bf0ff24e3286ec6312e4d593c6197bd9b 100644 (file)
@@ -47,10 +47,6 @@ int nft_redir_init(const struct nft_ctx *ctx,
        unsigned int plen;
        int err;
 
-       err = nft_redir_validate(ctx, expr, NULL);
-       if (err < 0)
-               return err;
-
        plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
        if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
                priv->sreg_proto_min =
index c64de3f7379df551fa413a4af186f3c16886f112..29f5bd2377b0deaf7ede8ec0573bf71cfeef7478 100644 (file)
@@ -42,11 +42,6 @@ int nft_reject_init(const struct nft_ctx *ctx,
                    const struct nlattr * const tb[])
 {
        struct nft_reject *priv = nft_expr_priv(expr);
-       int err;
-
-       err = nft_reject_validate(ctx, expr, NULL);
-       if (err < 0)
-               return err;
 
        if (tb[NFTA_REJECT_TYPE] == NULL)
                return -EINVAL;
index 9e90a02cb104dad81daf84208902e90390a8f504..5a7fb5ff867d382f04633a2fab53997d0ca1f2b2 100644 (file)
@@ -66,11 +66,7 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx,
                                const struct nlattr * const tb[])
 {
        struct nft_reject *priv = nft_expr_priv(expr);
-       int icmp_code, err;
-
-       err = nft_reject_validate(ctx, expr, NULL);
-       if (err < 0)
-               return err;
+       int icmp_code;
 
        if (tb[NFTA_REJECT_TYPE] == NULL)
                return -EINVAL;