3 * Linux ethernet bridge
6 * Lennert Buytenhek <buytenh@gnu.org>
8 * $Id: br_forward.c,v 1.4 2001/08/14 22:05:57 davem Exp $
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
16 #include <linux/kernel.h>
17 #include <linux/netdevice.h>
18 #include <linux/skbuff.h>
19 #include <linux/netfilter_bridge.h>
20 #include "br_private.h"
22 static inline int should_deliver(const struct net_bridge_port *p,
23 const struct sk_buff *skb)
25 if (skb->dev == p->dev ||
26 p->state != BR_STATE_FORWARDING)
29 #if defined(CONFIG_MIPS_BRCM)
31 * Do not forward any packets received from
32 * one WAN interface to other WAN interfaces in multiple PVC case
33 * In the following condition, if a new interface is added, please
34 * add the check to compare the first 3 chars from the name as
35 * shown below. Using strcmp will be expensive in this path.
37 if ((skb->nfmark & FROM_WAN) &&
38 ((*(p->dev->name) == 'n') &&
39 (*(p->dev->name + 1) == 'a') &&
40 (*(p->dev->name + 2) == 's')))
47 int br_dev_queue_push_xmit(struct sk_buff *skb)
49 #if defined(CONFIG_MIPS_BRCM)
50 // Just to make it consistent with 2.4 so it will not surprise the customers.(Should be more intelligent.)
51 #ifdef CONFIG_BRIDGE_NETFILTER
52 /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
53 nf_bridge_maybe_copy_header(skb);
55 skb_push(skb, ETH_HLEN);
59 if (skb->len > skb->dev->mtu)
62 #ifdef CONFIG_BRIDGE_NETFILTER
63 /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
64 nf_bridge_maybe_copy_header(skb);
66 skb_push(skb, ETH_HLEN);
75 int br_forward_finish(struct sk_buff *skb)
77 NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
78 br_dev_queue_push_xmit);
83 static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
86 #ifdef CONFIG_NETFILTER_DEBUG
89 NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
93 static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
95 struct net_device *indev;
99 skb->ip_summed = CHECKSUM_NONE;
101 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
105 /* called with rcu_read_lock */
106 void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
108 if (should_deliver(to, skb)) {
109 __br_deliver(to, skb);
116 /* called with rcu_read_lock */
117 void br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
119 if (should_deliver(to, skb)) {
120 __br_forward(to, skb);
127 /* called under bridge lock */
128 static void br_flood(struct net_bridge *br, struct sk_buff *skb, int clone,
129 void (*__packet_hook)(const struct net_bridge_port *p,
130 struct sk_buff *skb))
132 struct net_bridge_port *p;
133 struct net_bridge_port *prev;
136 struct sk_buff *skb2;
138 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
139 br->statistics.tx_dropped++;
148 list_for_each_entry_rcu(p, &br->port_list, list) {
149 if (should_deliver(p, skb)) {
151 struct sk_buff *skb2;
153 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
154 br->statistics.tx_dropped++;
159 __packet_hook(prev, skb2);
167 __packet_hook(prev, skb);
175 /* called with rcu_read_lock */
176 void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, int clone)
178 br_flood(br, skb, clone, __br_deliver);
181 /* called under bridge lock */
182 void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, int clone)
184 br_flood(br, skb, clone, __br_forward);