Skip to content

Commit

Permalink
netfilter: nft_meta: improve the validity check of pkttype set expr
Browse files Browse the repository at this point in the history
"meta pkttype set" is only supported on prerouting chain with bridge
family and ingress chain with netdev family.

But the validate check is incomplete, and the user can add the nft
rules on input chain with bridge family, for example:
  # nft add table bridge filter
  # nft add chain bridge filter input {type filter hook input \
    priority 0 \;}
  # nft add chain bridge filter test
  # nft add rule bridge filter test meta pkttype set unicast
  # nft add rule bridge filter input jump test

This patch fixes the problem.

Signed-off-by: Liping Zhang <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
  • Loading branch information
Liping Zhang authored and ummakynes committed Aug 25, 2016
1 parent 533e330 commit 960fa72
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
4 changes: 4 additions & 0 deletions include/net/netfilter/nft_meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ void nft_meta_set_eval(const struct nft_expr *expr,
void nft_meta_set_destroy(const struct nft_ctx *ctx,
const struct nft_expr *expr);

int nft_meta_set_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nft_data **data);

#endif
1 change: 1 addition & 0 deletions net/bridge/netfilter/nft_meta_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static const struct nft_expr_ops nft_meta_bridge_set_ops = {
.init = nft_meta_set_init,
.destroy = nft_meta_set_destroy,
.dump = nft_meta_set_dump,
.validate = nft_meta_set_validate,
};

static const struct nft_expr_ops *
Expand Down
17 changes: 13 additions & 4 deletions net/netfilter/nft_meta.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,16 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
}
EXPORT_SYMBOL_GPL(nft_meta_get_init);

static int nft_meta_set_init_pkttype(const struct nft_ctx *ctx)
int nft_meta_set_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nft_data **data)
{
struct nft_meta *priv = nft_expr_priv(expr);
unsigned int hooks;

if (priv->key != NFT_META_PKTTYPE)
return 0;

switch (ctx->afi->family) {
case NFPROTO_BRIDGE:
hooks = 1 << NF_BR_PRE_ROUTING;
Expand All @@ -308,6 +314,7 @@ static int nft_meta_set_init_pkttype(const struct nft_ctx *ctx)

return nft_chain_validate_hooks(ctx->chain, hooks);
}
EXPORT_SYMBOL_GPL(nft_meta_set_validate);

int nft_meta_set_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
Expand All @@ -327,15 +334,16 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
len = sizeof(u8);
break;
case NFT_META_PKTTYPE:
err = nft_meta_set_init_pkttype(ctx);
if (err)
return err;
len = sizeof(u8);
break;
default:
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)
Expand Down Expand Up @@ -407,6 +415,7 @@ static const struct nft_expr_ops nft_meta_set_ops = {
.init = nft_meta_set_init,
.destroy = nft_meta_set_destroy,
.dump = nft_meta_set_dump,
.validate = nft_meta_set_validate,
};

static const struct nft_expr_ops *
Expand Down

0 comments on commit 960fa72

Please sign in to comment.