Skip to content

Commit 31a4562

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
net: bridge: fix dest lookup when vlan proto doesn't match
With 802.1ad support the vlan_ingress code started checking for vlan protocol mismatch which causes the current tag to be inserted and the bridge vlan protocol & pvid to be set. The vlan tag insertion changes the skb mac_header and thus the lookup mac dest pointer which was loaded prior to calling br_allowed_ingress in br_handle_frame_finish is VLAN_HLEN bytes off now, pointing to the last two bytes of the destination mac and the first four of the source mac causing lookups to always fail and broadcasting all such packets to all ports. Same thing happens for locally originated packets when passing via br_dev_xmit. So load the dest pointer after the vlan checks and possible skb change. Fixes: 8580e21 ("bridge: Prepare for 802.1ad vlan filtering support") Reported-by: Anitha Narasimha Murthy <[email protected]> Signed-off-by: Nikolay Aleksandrov <[email protected]> Acked-by: Toshiaki Makita <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 40fbbce commit 31a4562

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

net/bridge/br_device.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ static struct lock_class_key bridge_netdev_addr_lock_key;
3434
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
3535
{
3636
struct net_bridge *br = netdev_priv(dev);
37-
const unsigned char *dest = skb->data;
3837
struct net_bridge_fdb_entry *dst;
3938
struct net_bridge_mdb_entry *mdst;
4039
struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats);
4140
const struct nf_br_ops *nf_ops;
41+
const unsigned char *dest;
4242
u16 vid = 0;
4343

4444
rcu_read_lock();
@@ -61,6 +61,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
6161
if (!br_allowed_ingress(br, br_vlan_group_rcu(br), skb, &vid))
6262
goto out;
6363

64+
dest = eth_hdr(skb)->h_dest;
6465
if (is_broadcast_ether_addr(dest)) {
6566
br_flood(br, skb, BR_PKT_BROADCAST, false, true);
6667
} else if (is_multicast_ether_addr(dest)) {

net/bridge/br_input.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
131131
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
132132
{
133133
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
134-
const unsigned char *dest = eth_hdr(skb)->h_dest;
135134
enum br_pkt_type pkt_type = BR_PKT_UNICAST;
136135
struct net_bridge_fdb_entry *dst = NULL;
137136
struct net_bridge_mdb_entry *mdst;
138137
bool local_rcv, mcast_hit = false;
138+
const unsigned char *dest;
139139
struct net_bridge *br;
140140
u16 vid = 0;
141141

@@ -153,6 +153,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
153153
br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false);
154154

155155
local_rcv = !!(br->dev->flags & IFF_PROMISC);
156+
dest = eth_hdr(skb)->h_dest;
156157
if (is_multicast_ether_addr(dest)) {
157158
/* by definition the broadcast is also a multicast address */
158159
if (is_broadcast_ether_addr(dest)) {

0 commit comments

Comments
 (0)