From d3aaf373c5c7812a0afab3e7c095e6e1d975b0a4 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Tue, 10 Sep 2002 17:40:54 +0000 Subject: prevent bogus NETFILTER_DEBUG messages --- kernel/linux/net/bridge/br_forward.c | 151 +++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 kernel/linux/net/bridge/br_forward.c (limited to 'kernel/linux') diff --git a/kernel/linux/net/bridge/br_forward.c b/kernel/linux/net/bridge/br_forward.c new file mode 100644 index 0000000..6ffd5a6 --- /dev/null +++ b/kernel/linux/net/bridge/br_forward.c @@ -0,0 +1,151 @@ +/* + * Forwarding decision + * Linux ethernet bridge + * + * Authors: + * Lennert Buytenhek + * + * $Id: br_forward.c,v 1.1 2002/09/10 17:40:54 bdschuym Exp $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include "br_private.h" + +static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb) +{ + if (skb->dev == p->dev || + p->state != BR_STATE_FORWARDING) + return 0; + + return 1; +} + +static int __dev_queue_push_xmit(struct sk_buff *skb) +{ + skb_push(skb, ETH_HLEN); + dev_queue_xmit(skb); + + return 0; +} + +static int __br_forward_finish(struct sk_buff *skb) +{ + NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, + __dev_queue_push_xmit); + + return 0; +} + +static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb) +{ + skb->dev = to->dev; +#ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; +#endif + NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, + __br_forward_finish); +} + +static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb) +{ + struct net_device *indev; + + indev = skb->dev; + skb->dev = to->dev; + + NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, + __br_forward_finish); +} + +/* called under bridge lock */ +void br_deliver(struct net_bridge_port *to, struct sk_buff *skb) +{ + if (should_deliver(to, skb)) { + __br_deliver(to, skb); + return; + } + + kfree_skb(skb); +} + +/* called under bridge lock */ +void br_forward(struct net_bridge_port *to, struct sk_buff *skb) +{ + if (should_deliver(to, skb)) { + __br_forward(to, skb); + return; + } + + kfree_skb(skb); +} + +/* called under bridge lock */ +static void br_flood(struct net_bridge *br, struct sk_buff *skb, int clone, + void (*__packet_hook)(struct net_bridge_port *p, struct sk_buff *skb)) +{ + struct net_bridge_port *p; + struct net_bridge_port *prev; + + if (clone) { + struct sk_buff *skb2; + + if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) { + br->statistics.tx_dropped++; + return; + } + + skb = skb2; + } + + prev = NULL; + + p = br->port_list; + while (p != NULL) { + if (should_deliver(p, skb)) { + if (prev != NULL) { + struct sk_buff *skb2; + + if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) { + br->statistics.tx_dropped++; + kfree_skb(skb); + return; + } + + __packet_hook(prev, skb2); + } + + prev = p; + } + + p = p->next; + } + + if (prev != NULL) { + __packet_hook(prev, skb); + return; + } + + kfree_skb(skb); +} + +/* called under bridge lock */ +void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, int clone) +{ + br_flood(br, skb, clone, __br_deliver); +} + +/* called under bridge lock */ +void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, int clone) +{ + br_flood(br, skb, clone, __br_forward); +} -- cgit v1.2.3