diff options
-rw-r--r-- | net/bridge/netfilter/nft_reject_bridge.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index 31b27e1bab9f..654c9018e3e7 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <net/netfilter/ipv6/nf_reject.h> | 18 | #include <net/netfilter/ipv6/nf_reject.h> |
19 | #include <linux/ip.h> | 19 | #include <linux/ip.h> |
20 | #include <net/ip.h> | 20 | #include <net/ip.h> |
21 | #include <linux/netfilter_bridge.h> | ||
21 | #include "../br_private.h" | 22 | #include "../br_private.h" |
22 | 23 | ||
23 | static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, | 24 | static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, |
@@ -305,12 +306,34 @@ out: | |||
305 | data[NFT_REG_VERDICT].verdict = NF_DROP; | 306 | data[NFT_REG_VERDICT].verdict = NF_DROP; |
306 | } | 307 | } |
307 | 308 | ||
309 | static int nft_reject_bridge_validate_hooks(const struct nft_chain *chain) | ||
310 | { | ||
311 | struct nft_base_chain *basechain; | ||
312 | |||
313 | if (chain->flags & NFT_BASE_CHAIN) { | ||
314 | basechain = nft_base_chain(chain); | ||
315 | |||
316 | switch (basechain->ops[0].hooknum) { | ||
317 | case NF_BR_PRE_ROUTING: | ||
318 | case NF_BR_LOCAL_IN: | ||
319 | break; | ||
320 | default: | ||
321 | return -EOPNOTSUPP; | ||
322 | } | ||
323 | } | ||
324 | return 0; | ||
325 | } | ||
326 | |||
308 | static int nft_reject_bridge_init(const struct nft_ctx *ctx, | 327 | static int nft_reject_bridge_init(const struct nft_ctx *ctx, |
309 | const struct nft_expr *expr, | 328 | const struct nft_expr *expr, |
310 | const struct nlattr * const tb[]) | 329 | const struct nlattr * const tb[]) |
311 | { | 330 | { |
312 | struct nft_reject *priv = nft_expr_priv(expr); | 331 | struct nft_reject *priv = nft_expr_priv(expr); |
313 | int icmp_code; | 332 | int icmp_code, err; |
333 | |||
334 | err = nft_reject_bridge_validate_hooks(ctx->chain); | ||
335 | if (err < 0) | ||
336 | return err; | ||
314 | 337 | ||
315 | if (tb[NFTA_REJECT_TYPE] == NULL) | 338 | if (tb[NFTA_REJECT_TYPE] == NULL) |
316 | return -EINVAL; | 339 | return -EINVAL; |
@@ -359,6 +382,13 @@ nla_put_failure: | |||
359 | return -1; | 382 | return -1; |
360 | } | 383 | } |
361 | 384 | ||
385 | static int nft_reject_bridge_validate(const struct nft_ctx *ctx, | ||
386 | const struct nft_expr *expr, | ||
387 | const struct nft_data **data) | ||
388 | { | ||
389 | return nft_reject_bridge_validate_hooks(ctx->chain); | ||
390 | } | ||
391 | |||
362 | static struct nft_expr_type nft_reject_bridge_type; | 392 | static struct nft_expr_type nft_reject_bridge_type; |
363 | static const struct nft_expr_ops nft_reject_bridge_ops = { | 393 | static const struct nft_expr_ops nft_reject_bridge_ops = { |
364 | .type = &nft_reject_bridge_type, | 394 | .type = &nft_reject_bridge_type, |
@@ -366,6 +396,7 @@ static const struct nft_expr_ops nft_reject_bridge_ops = { | |||
366 | .eval = nft_reject_bridge_eval, | 396 | .eval = nft_reject_bridge_eval, |
367 | .init = nft_reject_bridge_init, | 397 | .init = nft_reject_bridge_init, |
368 | .dump = nft_reject_bridge_dump, | 398 | .dump = nft_reject_bridge_dump, |
399 | .validate = nft_reject_bridge_validate, | ||
369 | }; | 400 | }; |
370 | 401 | ||
371 | static struct nft_expr_type nft_reject_bridge_type __read_mostly = { | 402 | static struct nft_expr_type nft_reject_bridge_type __read_mostly = { |