diff options
author | Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> | 2014-06-10 20:59:24 +0900 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-11 15:22:53 -0700 |
commit | f2808d226f4efe15a0ea44697a3525176d6c8eae (patch) | |
tree | 45b3017e9b56116a23e835b5eeece8aada211f7e /net | |
parent | 8580e2117c06ac0c97a561219eaab6dab968ea3f (diff) |
bridge: Prepare for forwarding another bridge group addresses
If a bridge is an 802.1ad bridge, it must forward another bridge group
addresses (the Nearest Customer Bridge group addresses).
(For details, see IEEE 802.1Q-2011 8.6.3.)
As user might not want group_fwd_mask to be modified by enabling 802.1ad,
introduce a new mask, group_fwd_mask_required, which indicates addresses
the bridge wants to forward. This will be set by enabling 802.1ad.
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_device.c | 1 | ||||
-rw-r--r-- | net/bridge/br_input.c | 8 | ||||
-rw-r--r-- | net/bridge/br_private.h | 3 |
3 files changed, 10 insertions, 2 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 1b797c42ef5..568cccd39a3 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -378,6 +378,7 @@ void br_dev_setup(struct net_device *dev) br->stp_enabled = BR_NO_STP; br->group_fwd_mask = BR_GROUPFWD_DEFAULT; + br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT; br->designated_root = br->bridge_id; br->bridge_max_age = br->max_age = 20 * HZ; diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 04d6348fd53..366c4364907 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -177,6 +177,8 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) p = br_port_get_rcu(skb->dev); if (unlikely(is_link_local_ether_addr(dest))) { + u16 fwd_mask = p->br->group_fwd_mask_required; + /* * See IEEE 802.1D Table 7-10 Reserved addresses * @@ -194,7 +196,8 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) case 0x00: /* Bridge Group Address */ /* If STP is turned off, then must forward to keep loop detection */ - if (p->br->stp_enabled == BR_NO_STP) + if (p->br->stp_enabled == BR_NO_STP || + fwd_mask & (1u << dest[5])) goto forward; break; @@ -203,7 +206,8 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) default: /* Allow selective forwarding for most other protocols */ - if (p->br->group_fwd_mask & (1u << dest[5])) + fwd_mask |= p->br->group_fwd_mask; + if (fwd_mask & (1u << dest[5])) goto forward; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 13e570e8b0f..4eba348a985 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -35,6 +35,8 @@ #define BR_GROUPFWD_DEFAULT 0 /* Don't allow forwarding control protocols like STP and LLDP */ #define BR_GROUPFWD_RESTRICTED 0x4007u +/* The Nearest Customer Bridge Group Address, 01-80-C2-00-00-[00,0B,0C,0D,0F] */ +#define BR_GROUPFWD_8021AD 0xB801u /* Path to usermode spanning tree program */ #define BR_STP_PROG "/sbin/bridge-stp" @@ -226,6 +228,7 @@ struct net_bridge bool nf_call_arptables; #endif u16 group_fwd_mask; + u16 group_fwd_mask_required; /* STP */ bridge_id designated_root; |