aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-07-06 00:25:56 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-06 00:25:56 -0400
commit7c85fbf0657f216557b0c9c4a2e4e07f37d8bb8c (patch)
tree08660067a7f60fdf4e8343ec9481ce6da22ac6d8 /net/bridge
parenta19800d704177caaa5874baf5819307c5b7d5e4f (diff)
bridge: Use STP demux
Use the STP demux layer for receiving STP PDUs instead of directly registering with LLC. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/Kconfig1
-rw-r--r--net/bridge/br.c16
-rw-r--r--net/bridge/br_private.h5
-rw-r--r--net/bridge/br_stp_bpdu.c12
4 files changed, 16 insertions, 18 deletions
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
index 12265aff7099..e143ca678881 100644
--- a/net/bridge/Kconfig
+++ b/net/bridge/Kconfig
@@ -5,6 +5,7 @@
5config BRIDGE 5config BRIDGE
6 tristate "802.1d Ethernet Bridging" 6 tristate "802.1d Ethernet Bridging"
7 select LLC 7 select LLC
8 select STP
8 ---help--- 9 ---help---
9 If you say Y here, then your Linux box will be able to act as an 10 If you say Y here, then your Linux box will be able to act as an
10 Ethernet bridge, which means that the different Ethernet segments it 11 Ethernet bridge, which means that the different Ethernet segments it
diff --git a/net/bridge/br.c b/net/bridge/br.c
index cede010f4ddd..573acdf6f9ff 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -18,21 +18,24 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/llc.h> 19#include <linux/llc.h>
20#include <net/llc.h> 20#include <net/llc.h>
21#include <net/stp.h>
21 22
22#include "br_private.h" 23#include "br_private.h"
23 24
24int (*br_should_route_hook)(struct sk_buff *skb); 25int (*br_should_route_hook)(struct sk_buff *skb);
25 26
26static struct llc_sap *br_stp_sap; 27static const struct stp_proto br_stp_proto = {
28 .rcv = br_stp_rcv,
29};
27 30
28static int __init br_init(void) 31static int __init br_init(void)
29{ 32{
30 int err; 33 int err;
31 34
32 br_stp_sap = llc_sap_open(LLC_SAP_BSPAN, br_stp_rcv); 35 err = stp_proto_register(&br_stp_proto);
33 if (!br_stp_sap) { 36 if (err < 0) {
34 printk(KERN_ERR "bridge: can't register sap for STP\n"); 37 printk(KERN_ERR "bridge: can't register sap for STP\n");
35 return -EADDRINUSE; 38 return err;
36 } 39 }
37 40
38 err = br_fdb_init(); 41 err = br_fdb_init();
@@ -65,13 +68,13 @@ err_out2:
65err_out1: 68err_out1:
66 br_fdb_fini(); 69 br_fdb_fini();
67err_out: 70err_out:
68 llc_sap_put(br_stp_sap); 71 stp_proto_unregister(&br_stp_proto);
69 return err; 72 return err;
70} 73}
71 74
72static void __exit br_deinit(void) 75static void __exit br_deinit(void)
73{ 76{
74 rcu_assign_pointer(br_stp_sap->rcv_func, NULL); 77 stp_proto_unregister(&br_stp_proto);
75 78
76 br_netlink_fini(); 79 br_netlink_fini();
77 unregister_netdevice_notifier(&br_device_notifier); 80 unregister_netdevice_notifier(&br_device_notifier);
@@ -82,7 +85,6 @@ static void __exit br_deinit(void)
82 synchronize_net(); 85 synchronize_net();
83 86
84 br_netfilter_fini(); 87 br_netfilter_fini();
85 llc_sap_put(br_stp_sap);
86 br_fdb_get_hook = NULL; 88 br_fdb_get_hook = NULL;
87 br_fdb_put_hook = NULL; 89 br_fdb_put_hook = NULL;
88 90
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 8593c9f6a302..815ed38925b2 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -226,8 +226,9 @@ extern void br_stp_set_path_cost(struct net_bridge_port *p,
226extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); 226extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
227 227
228/* br_stp_bpdu.c */ 228/* br_stp_bpdu.c */
229extern int br_stp_rcv(struct sk_buff *skb, struct net_device *dev, 229struct stp_proto;
230 struct packet_type *pt, struct net_device *orig_dev); 230extern void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
231 struct net_device *dev);
231 232
232/* br_stp_timer.c */ 233/* br_stp_timer.c */
233extern void br_stp_timer_init(struct net_bridge *br); 234extern void br_stp_timer_init(struct net_bridge *br);
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 9dc2de656965..996476174517 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -18,6 +18,7 @@
18#include <net/net_namespace.h> 18#include <net/net_namespace.h>
19#include <net/llc.h> 19#include <net/llc.h>
20#include <net/llc_pdu.h> 20#include <net/llc_pdu.h>
21#include <net/stp.h>
21#include <asm/unaligned.h> 22#include <asm/unaligned.h>
22 23
23#include "br_private.h" 24#include "br_private.h"
@@ -131,10 +132,9 @@ void br_send_tcn_bpdu(struct net_bridge_port *p)
131 * 132 *
132 * NO locks, but rcu_read_lock (preempt_disabled) 133 * NO locks, but rcu_read_lock (preempt_disabled)
133 */ 134 */
134int br_stp_rcv(struct sk_buff *skb, struct net_device *dev, 135void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
135 struct packet_type *pt, struct net_device *orig_dev) 136 struct net_device *dev)
136{ 137{
137 const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
138 const unsigned char *dest = eth_hdr(skb)->h_dest; 138 const unsigned char *dest = eth_hdr(skb)->h_dest;
139 struct net_bridge_port *p = rcu_dereference(dev->br_port); 139 struct net_bridge_port *p = rcu_dereference(dev->br_port);
140 struct net_bridge *br; 140 struct net_bridge *br;
@@ -146,11 +146,6 @@ int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
146 if (!p) 146 if (!p)
147 goto err; 147 goto err;
148 148
149 if (pdu->ssap != LLC_SAP_BSPAN
150 || pdu->dsap != LLC_SAP_BSPAN
151 || pdu->ctrl_1 != LLC_PDU_TYPE_U)
152 goto err;
153
154 if (!pskb_may_pull(skb, 4)) 149 if (!pskb_may_pull(skb, 4))
155 goto err; 150 goto err;
156 151
@@ -224,5 +219,4 @@ int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
224 spin_unlock(&br->lock); 219 spin_unlock(&br->lock);
225 err: 220 err:
226 kfree_skb(skb); 221 kfree_skb(skb);
227 return 0;
228} 222}