Stephen Hemminger
2007-Apr-25 16:56 UTC
[Bridge] [PATCH 1/4] bridge: don't change packet type
The change to forward STP bpdu's (for usermode STP) through normal path, changed the packet type in the process. Since link local stuff is multicast, it should stay pkt_type = PACKET_MULTICAST. The code was probably copy/pasted incorrectly from the bridge pseudo-device receive path. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> --- bridge-2.6.22.orig/net/bridge/br_input.c +++ bridge-2.6.22/net/bridge/br_input.c @@ -131,12 +131,9 @@ struct sk_buff *br_handle_frame(struct n if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) goto drop; - if (unlikely(is_link_local(dest))) { - skb->pkt_type = PACKET_HOST; - + if (unlikely(is_link_local(dest))) return (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, NULL, br_handle_local_finish) == 0) ? skb : NULL; - } switch (p->state) { case BR_STATE_FORWARDING: --
Here are some patches for bridge code in 2.6.22. The user mode RSTP from Aji is working. Anyone who wants to test it can get it from: git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/rstp.git Thanks --
Pause frames should never make it out of the network device into the stack. But if a device was misconfigured, it might happen. So drop pause frames in bridge. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> --- bridge-2.6.22.orig/include/linux/if_ether.h +++ bridge-2.6.22/include/linux/if_ether.h @@ -61,6 +61,7 @@ #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */ #define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */ #define ETH_P_WCCP 0x883E /* Web-cache coordination protocol * defined in draft-wilson-wrec-wccp-v2-00.txt */ --- bridge-2.6.22.orig/net/bridge/br_input.c +++ bridge-2.6.22/net/bridge/br_input.c @@ -131,9 +131,14 @@ struct sk_buff *br_handle_frame(struct n if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) goto drop; - if (unlikely(is_link_local(dest))) + if (unlikely(is_link_local(dest))) { + /* Pause frames shouldn't be passed up by driver anyway */ + if (skb->protocol == htons(ETH_P_PAUSE)) + goto drop; + return (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, NULL, br_handle_local_finish) == 0) ? skb : NULL; + } switch (p->state) { case BR_STATE_FORWARDING: --
Writing to /sys/class/net/brX/bridge/stp_state causes a warning because RTNL is not held when call br_stp_if.c Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> --- net/bridge/br_sysfs_br.c | 2 ++ 1 file changed, 2 insertions(+) --- bridge-2.6.22.orig/net/bridge/br_sysfs_br.c +++ bridge-2.6.22/net/bridge/br_sysfs_br.c @@ -149,9 +149,11 @@ static ssize_t show_stp_state(struct dev static void set_stp_state(struct net_bridge *br, unsigned long val) { + rtnl_lock(); spin_unlock_bh(&br->lock); br_stp_set_enabled(br, val); spin_lock_bh(&br->lock); + rtnl_unlock(); } static ssize_t store_stp_state(struct device *d, --
Stephen Hemminger
2007-Apr-25 16:56 UTC
[Bridge] [PATCH 3/4] bridge: if no STP then forward all BPDUs
If a bridge is not running STP, then it has no way to detect a cycle in the network. But if it is not running STP and some other machine or device is running STP, then if STP BPDU's get forwarded to it can detect the cycle. This is how the old 2.4 and early 2.6 code worked. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> --- net/bridge/br_input.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) --- bridge-2.6.22.orig/net/bridge/br_input.c +++ bridge-2.6.22/net/bridge/br_input.c @@ -136,8 +136,14 @@ struct sk_buff *br_handle_frame(struct n if (skb->protocol == htons(ETH_P_PAUSE)) goto drop; - return (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, - NULL, br_handle_local_finish) == 0) ? skb : NULL; + /* Process STP BPDU's through normal netif_receive_skb() path */ + if (p->br->stp_enabled != BR_NO_STP) { + if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, + NULL, br_handle_local_finish)) + return NULL; + else + return skb; + } } switch (p->state) { --
From: Stephen Hemminger <shemminger@linux-foundation.org> Date: Wed, 25 Apr 2007 16:47:41 -0700> Writing to /sys/class/net/brX/bridge/stp_state causes a warning because > RTNL is not held when call br_stp_if.c > > Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>Applied, thanks Stephen.