netfilter: nf_tables: validate the expr explicitly after init successfully
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>
This commit is contained in:
parent
74664cf286
commit
c56e3956c1
|
@ -375,11 +375,7 @@ static int nft_reject_bridge_init(const struct nft_ctx *ctx,
|
||||||
const struct nlattr * const tb[])
|
const struct nlattr * const tb[])
|
||||||
{
|
{
|
||||||
struct nft_reject *priv = nft_expr_priv(expr);
|
struct nft_reject *priv = nft_expr_priv(expr);
|
||||||
int icmp_code, err;
|
int icmp_code;
|
||||||
|
|
||||||
err = nft_reject_bridge_validate(ctx, expr, NULL);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (tb[NFTA_REJECT_TYPE] == NULL)
|
if (tb[NFTA_REJECT_TYPE] == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -1772,8 +1772,19 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx,
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ops->validate) {
|
||||||
|
const struct nft_data *data = NULL;
|
||||||
|
|
||||||
|
err = ops->validate(ctx, expr, &data);
|
||||||
|
if (err < 0)
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err2:
|
||||||
|
if (ops->destroy)
|
||||||
|
ops->destroy(ctx, expr);
|
||||||
err1:
|
err1:
|
||||||
expr->ops = NULL;
|
expr->ops = NULL;
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -230,10 +230,6 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||||
union nft_entry e = {};
|
union nft_entry e = {};
|
||||||
int ret;
|
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);
|
target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
|
||||||
|
|
||||||
if (ctx->nla[NFTA_RULE_COMPAT]) {
|
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 = {};
|
union nft_entry e = {};
|
||||||
int ret;
|
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);
|
match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
|
||||||
|
|
||||||
if (ctx->nla[NFTA_RULE_COMPAT]) {
|
if (ctx->nla[NFTA_RULE_COMPAT]) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return nft_fib_validate(ctx, expr, NULL);
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nft_fib_init);
|
EXPORT_SYMBOL_GPL(nft_fib_init);
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,6 @@ int nft_masq_init(const struct nft_ctx *ctx,
|
||||||
struct nft_masq *priv = nft_expr_priv(expr);
|
struct nft_masq *priv = nft_expr_priv(expr);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = nft_masq_validate(ctx, expr, NULL);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (tb[NFTA_MASQ_FLAGS]) {
|
if (tb[NFTA_MASQ_FLAGS]) {
|
||||||
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
|
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
|
||||||
if (priv->flags & ~NF_NAT_RANGE_MASK)
|
if (priv->flags & ~NF_NAT_RANGE_MASK)
|
||||||
|
|
|
@ -370,10 +370,6 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nft_meta_set_validate(ctx, expr, NULL);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
|
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
|
||||||
err = nft_validate_register_load(priv->sreg, len);
|
err = nft_validate_register_load(priv->sreg, len);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -138,10 +138,6 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nft_nat_validate(ctx, expr, NULL);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (tb[NFTA_NAT_FAMILY] == NULL)
|
if (tb[NFTA_NAT_FAMILY] == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,6 @@ int nft_redir_init(const struct nft_ctx *ctx,
|
||||||
unsigned int plen;
|
unsigned int plen;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = nft_redir_validate(ctx, expr, NULL);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
|
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
|
||||||
if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
|
if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
|
||||||
priv->sreg_proto_min =
|
priv->sreg_proto_min =
|
||||||
|
|
|
@ -42,11 +42,6 @@ int nft_reject_init(const struct nft_ctx *ctx,
|
||||||
const struct nlattr * const tb[])
|
const struct nlattr * const tb[])
|
||||||
{
|
{
|
||||||
struct nft_reject *priv = nft_expr_priv(expr);
|
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)
|
if (tb[NFTA_REJECT_TYPE] == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -66,11 +66,7 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx,
|
||||||
const struct nlattr * const tb[])
|
const struct nlattr * const tb[])
|
||||||
{
|
{
|
||||||
struct nft_reject *priv = nft_expr_priv(expr);
|
struct nft_reject *priv = nft_expr_priv(expr);
|
||||||
int icmp_code, err;
|
int icmp_code;
|
||||||
|
|
||||||
err = nft_reject_validate(ctx, expr, NULL);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (tb[NFTA_REJECT_TYPE] == NULL)
|
if (tb[NFTA_REJECT_TYPE] == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
Loading…
Reference in New Issue