diff options
author | Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> | 2014-05-26 02:15:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-02 16:38:23 -0400 |
commit | e0d7968ab6c8bce2437b36fa7f04117e333f196d (patch) | |
tree | 8b066b3ba7134569ba12b5dd21b31be2621adf3c /net/bridge/br_vlan.c | |
parent | bfc5184b69cf9eeb286137640351c650c27f118a (diff) |
bridge: Prevent insertion of FDB entry with disallowed vlan
br_handle_local_finish() is allowing us to insert an FDB entry with
disallowed vlan. For example, when port 1 and 2 are communicating in
vlan 10, and even if vlan 10 is disallowed on port 3, port 3 can
interfere with their communication by spoofed src mac address with
vlan id 10.
Note: Even if it is judged that a frame should not be learned, it should
not be dropped because it is destined for not forwarding layer but higher
layer. See IEEE 802.1Q-2011 8.13.10.
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Acked-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_vlan.c')
-rw-r--r-- | net/bridge/br_vlan.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 4a3716102789..5fee2feaf292 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -241,6 +241,34 @@ bool br_allowed_egress(struct net_bridge *br, | |||
241 | return false; | 241 | return false; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* Called under RCU */ | ||
245 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) | ||
246 | { | ||
247 | struct net_bridge *br = p->br; | ||
248 | struct net_port_vlans *v; | ||
249 | |||
250 | if (!br->vlan_enabled) | ||
251 | return true; | ||
252 | |||
253 | v = rcu_dereference(p->vlan_info); | ||
254 | if (!v) | ||
255 | return false; | ||
256 | |||
257 | br_vlan_get_tag(skb, vid); | ||
258 | if (!*vid) { | ||
259 | *vid = br_get_pvid(v); | ||
260 | if (*vid == VLAN_N_VID) | ||
261 | return false; | ||
262 | |||
263 | return true; | ||
264 | } | ||
265 | |||
266 | if (test_bit(*vid, v->vlan_bitmap)) | ||
267 | return true; | ||
268 | |||
269 | return false; | ||
270 | } | ||
271 | |||
244 | /* Must be protected by RTNL. | 272 | /* Must be protected by RTNL. |
245 | * Must be called with vid in range from 1 to 4094 inclusive. | 273 | * Must be called with vid in range from 1 to 4094 inclusive. |
246 | */ | 274 | */ |