aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-10-27 09:08:17 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2014-10-31 07:50:09 -0400
commit127917c29a432c3b798e014a1714e9c1af0f87fe (patch)
tree9a488cb70c3b6e802829b4cf6060aad86850c47b /net
parent523b929d5446c023e1219aa81455a8c766cac883 (diff)
netfilter: nft_reject_bridge: restrict reject to prerouting and input
Restrict the reject expression to the prerouting and input bridge hooks. If we allow this to be used from forward or any other later bridge hook, if the frame is flooded to several ports, we'll end up sending several reject packets, one per cloned packet. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/nft_reject_bridge.c33
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
23static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, 24static 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
309static 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
308static int nft_reject_bridge_init(const struct nft_ctx *ctx, 327static 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
385static 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
362static struct nft_expr_type nft_reject_bridge_type; 392static struct nft_expr_type nft_reject_bridge_type;
363static const struct nft_expr_ops nft_reject_bridge_ops = { 393static 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
371static struct nft_expr_type nft_reject_bridge_type __read_mostly = { 402static struct nft_expr_type nft_reject_bridge_type __read_mostly = {