aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_input.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-03-21 01:59:06 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-21 01:59:06 -0500
commitcf0f02d04a830c8202e6a8f8bb37acc6c1629a91 (patch)
tree8f3c7af9aee5ea2e1b889c27660e8587307025df /net/bridge/br_input.c
parent18fdb2b25be37e49b1669b5c394671f8c5b6550f (diff)
[BRIDGE]: use llc for receiving STP packets
Use LLC for the receive path of Spanning Tree Protocol packets. This allows link local multicast packets to be received by other protocols (if they care), and uses the existing LLC code to get STP packets back into bridge code. The bridge multicast address is also checked, so bridges using other link local multicast addresses are ignored. This allows for use of different multicast addresses to define separate STP domains. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_input.c')
-rw-r--r--net/bridge/br_input.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 6e223723cc8d..dad409489753 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -94,6 +94,25 @@ drop:
94 goto out; 94 goto out;
95} 95}
96 96
97/* note: already called with rcu_read_lock (preempt_disabled) */
98static int br_handle_local_finish(struct sk_buff *skb)
99{
100 struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
101
102 if (p && p->state != BR_STATE_DISABLED)
103 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
104
105 return 0; /* process further */
106}
107
108/* Does address match the link local multicast address.
109 * 01:80:c2:00:00:0X
110 */
111static inline int is_link_local(const unsigned char *dest)
112{
113 return memcmp(dest, bridge_ula, 5) == 0 && (dest[5] & 0xf0) == 0;
114}
115
97/* 116/*
98 * Called via br_handle_frame_hook. 117 * Called via br_handle_frame_hook.
99 * Return 0 if *pskb should be processed furthur 118 * Return 0 if *pskb should be processed furthur
@@ -111,15 +130,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
111 if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) 130 if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
112 goto err; 131 goto err;
113 132
114 if (p->br->stp_enabled && 133 if (unlikely(is_link_local(dest))) {
115 !memcmp(dest, bridge_ula, 5) && 134 skb->pkt_type = PACKET_HOST;
116 !(dest[5] & 0xF0)) { 135 return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
117 if (!dest[5]) { 136 NULL, br_handle_local_finish) != 0;
118 NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
119 NULL, br_stp_handle_bpdu);
120 return 1;
121 }
122 goto err;
123 } 137 }
124 138
125 if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) { 139 if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {