diff options
author | Patrick McHardy <kaber@trash.net> | 2008-07-06 00:25:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-06 00:25:56 -0400 |
commit | 7c85fbf0657f216557b0c9c4a2e4e07f37d8bb8c (patch) | |
tree | 08660067a7f60fdf4e8343ec9481ce6da22ac6d8 | |
parent | a19800d704177caaa5874baf5819307c5b7d5e4f (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>
-rw-r--r-- | net/bridge/Kconfig | 1 | ||||
-rw-r--r-- | net/bridge/br.c | 16 | ||||
-rw-r--r-- | net/bridge/br_private.h | 5 | ||||
-rw-r--r-- | net/bridge/br_stp_bpdu.c | 12 |
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 @@ | |||
5 | config BRIDGE | 5 | config 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 | ||
24 | int (*br_should_route_hook)(struct sk_buff *skb); | 25 | int (*br_should_route_hook)(struct sk_buff *skb); |
25 | 26 | ||
26 | static struct llc_sap *br_stp_sap; | 27 | static const struct stp_proto br_stp_proto = { |
28 | .rcv = br_stp_rcv, | ||
29 | }; | ||
27 | 30 | ||
28 | static int __init br_init(void) | 31 | static 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: | |||
65 | err_out1: | 68 | err_out1: |
66 | br_fdb_fini(); | 69 | br_fdb_fini(); |
67 | err_out: | 70 | err_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 | ||
72 | static void __exit br_deinit(void) | 75 | static 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, | |||
226 | extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); | 226 | extern 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 */ |
229 | extern int br_stp_rcv(struct sk_buff *skb, struct net_device *dev, | 229 | struct stp_proto; |
230 | struct packet_type *pt, struct net_device *orig_dev); | 230 | extern 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 */ |
233 | extern void br_stp_timer_init(struct net_bridge *br); | 234 | extern 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 | */ |
134 | int br_stp_rcv(struct sk_buff *skb, struct net_device *dev, | 135 | void 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 | } |