mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
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>
This commit is contained in:
parent
a19800d704
commit
7c85fbf065
4 changed files with 16 additions and 18 deletions
|
@ -5,6 +5,7 @@
|
||||||
config BRIDGE
|
config BRIDGE
|
||||||
tristate "802.1d Ethernet Bridging"
|
tristate "802.1d Ethernet Bridging"
|
||||||
select LLC
|
select LLC
|
||||||
|
select STP
|
||||||
---help---
|
---help---
|
||||||
If you say Y here, then your Linux box will be able to act as an
|
If you say Y here, then your Linux box will be able to act as an
|
||||||
Ethernet bridge, which means that the different Ethernet segments it
|
Ethernet bridge, which means that the different Ethernet segments it
|
||||||
|
|
|
@ -18,21 +18,24 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/llc.h>
|
#include <linux/llc.h>
|
||||||
#include <net/llc.h>
|
#include <net/llc.h>
|
||||||
|
#include <net/stp.h>
|
||||||
|
|
||||||
#include "br_private.h"
|
#include "br_private.h"
|
||||||
|
|
||||||
int (*br_should_route_hook)(struct sk_buff *skb);
|
int (*br_should_route_hook)(struct sk_buff *skb);
|
||||||
|
|
||||||
static struct llc_sap *br_stp_sap;
|
static const struct stp_proto br_stp_proto = {
|
||||||
|
.rcv = br_stp_rcv,
|
||||||
|
};
|
||||||
|
|
||||||
static int __init br_init(void)
|
static int __init br_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
br_stp_sap = llc_sap_open(LLC_SAP_BSPAN, br_stp_rcv);
|
err = stp_proto_register(&br_stp_proto);
|
||||||
if (!br_stp_sap) {
|
if (err < 0) {
|
||||||
printk(KERN_ERR "bridge: can't register sap for STP\n");
|
printk(KERN_ERR "bridge: can't register sap for STP\n");
|
||||||
return -EADDRINUSE;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = br_fdb_init();
|
err = br_fdb_init();
|
||||||
|
@ -65,13 +68,13 @@ err_out2:
|
||||||
err_out1:
|
err_out1:
|
||||||
br_fdb_fini();
|
br_fdb_fini();
|
||||||
err_out:
|
err_out:
|
||||||
llc_sap_put(br_stp_sap);
|
stp_proto_unregister(&br_stp_proto);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit br_deinit(void)
|
static void __exit br_deinit(void)
|
||||||
{
|
{
|
||||||
rcu_assign_pointer(br_stp_sap->rcv_func, NULL);
|
stp_proto_unregister(&br_stp_proto);
|
||||||
|
|
||||||
br_netlink_fini();
|
br_netlink_fini();
|
||||||
unregister_netdevice_notifier(&br_device_notifier);
|
unregister_netdevice_notifier(&br_device_notifier);
|
||||||
|
@ -82,7 +85,6 @@ static void __exit br_deinit(void)
|
||||||
synchronize_net();
|
synchronize_net();
|
||||||
|
|
||||||
br_netfilter_fini();
|
br_netfilter_fini();
|
||||||
llc_sap_put(br_stp_sap);
|
|
||||||
br_fdb_get_hook = NULL;
|
br_fdb_get_hook = NULL;
|
||||||
br_fdb_put_hook = NULL;
|
br_fdb_put_hook = NULL;
|
||||||
|
|
||||||
|
|
|
@ -226,8 +226,9 @@ extern void br_stp_set_path_cost(struct net_bridge_port *p,
|
||||||
extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
|
extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
|
||||||
|
|
||||||
/* br_stp_bpdu.c */
|
/* br_stp_bpdu.c */
|
||||||
extern int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
|
struct stp_proto;
|
||||||
struct packet_type *pt, struct net_device *orig_dev);
|
extern void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
|
||||||
|
struct net_device *dev);
|
||||||
|
|
||||||
/* br_stp_timer.c */
|
/* br_stp_timer.c */
|
||||||
extern void br_stp_timer_init(struct net_bridge *br);
|
extern void br_stp_timer_init(struct net_bridge *br);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
#include <net/llc.h>
|
#include <net/llc.h>
|
||||||
#include <net/llc_pdu.h>
|
#include <net/llc_pdu.h>
|
||||||
|
#include <net/stp.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#include "br_private.h"
|
#include "br_private.h"
|
||||||
|
@ -131,10 +132,9 @@ void br_send_tcn_bpdu(struct net_bridge_port *p)
|
||||||
*
|
*
|
||||||
* NO locks, but rcu_read_lock (preempt_disabled)
|
* NO locks, but rcu_read_lock (preempt_disabled)
|
||||||
*/
|
*/
|
||||||
int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
|
void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
|
||||||
struct packet_type *pt, struct net_device *orig_dev)
|
struct net_device *dev)
|
||||||
{
|
{
|
||||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
|
||||||
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
||||||
struct net_bridge_port *p = rcu_dereference(dev->br_port);
|
struct net_bridge_port *p = rcu_dereference(dev->br_port);
|
||||||
struct net_bridge *br;
|
struct net_bridge *br;
|
||||||
|
@ -146,11 +146,6 @@ int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
if (!p)
|
if (!p)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (pdu->ssap != LLC_SAP_BSPAN
|
|
||||||
|| pdu->dsap != LLC_SAP_BSPAN
|
|
||||||
|| pdu->ctrl_1 != LLC_PDU_TYPE_U)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, 4))
|
if (!pskb_may_pull(skb, 4))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -224,5 +219,4 @@ int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
spin_unlock(&br->lock);
|
spin_unlock(&br->lock);
|
||||||
err:
|
err:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue