diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_input.c | 11 | ||||
-rw-r--r-- | net/bridge/br_vlan.c | 14 |
2 files changed, 20 insertions, 5 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 28d544627422..d0cca3c65f01 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -29,6 +29,7 @@ static int br_pass_frame_up(struct sk_buff *skb) | |||
29 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; | 29 | struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; |
30 | struct net_bridge *br = netdev_priv(brdev); | 30 | struct net_bridge *br = netdev_priv(brdev); |
31 | struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); | 31 | struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); |
32 | struct net_port_vlans *pv; | ||
32 | 33 | ||
33 | u64_stats_update_begin(&brstats->syncp); | 34 | u64_stats_update_begin(&brstats->syncp); |
34 | brstats->rx_packets++; | 35 | brstats->rx_packets++; |
@@ -39,18 +40,18 @@ static int br_pass_frame_up(struct sk_buff *skb) | |||
39 | * packet is allowed except in promisc modue when someone | 40 | * packet is allowed except in promisc modue when someone |
40 | * may be running packet capture. | 41 | * may be running packet capture. |
41 | */ | 42 | */ |
43 | pv = br_get_vlan_info(br); | ||
42 | if (!(brdev->flags & IFF_PROMISC) && | 44 | if (!(brdev->flags & IFF_PROMISC) && |
43 | !br_allowed_egress(br, br_get_vlan_info(br), skb)) { | 45 | !br_allowed_egress(br, pv, skb)) { |
44 | kfree_skb(skb); | 46 | kfree_skb(skb); |
45 | return NET_RX_DROP; | 47 | return NET_RX_DROP; |
46 | } | 48 | } |
47 | 49 | ||
48 | skb = br_handle_vlan(br, br_get_vlan_info(br), skb); | ||
49 | if (!skb) | ||
50 | return NET_RX_DROP; | ||
51 | |||
52 | indev = skb->dev; | 50 | indev = skb->dev; |
53 | skb->dev = brdev; | 51 | skb->dev = brdev; |
52 | skb = br_handle_vlan(br, pv, skb); | ||
53 | if (!skb) | ||
54 | return NET_RX_DROP; | ||
54 | 55 | ||
55 | return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, | 56 | return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, |
56 | netif_receive_skb); | 57 | netif_receive_skb); |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index c77eed56b045..f23c74b3a953 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -128,6 +128,20 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
128 | if (!br->vlan_enabled) | 128 | if (!br->vlan_enabled) |
129 | goto out; | 129 | goto out; |
130 | 130 | ||
131 | /* Vlan filter table must be configured at this point. The | ||
132 | * only exception is the bridge is set in promisc mode and the | ||
133 | * packet is destined for the bridge device. In this case | ||
134 | * pass the packet as is. | ||
135 | */ | ||
136 | if (!pv) { | ||
137 | if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { | ||
138 | goto out; | ||
139 | } else { | ||
140 | kfree_skb(skb); | ||
141 | return NULL; | ||
142 | } | ||
143 | } | ||
144 | |||
131 | /* At this point, we know that the frame was filtered and contains | 145 | /* At this point, we know that the frame was filtered and contains |
132 | * a valid vlan id. If the vlan id is set in the untagged bitmap, | 146 | * a valid vlan id. If the vlan id is set in the untagged bitmap, |
133 | * send untagged; otherwise, send tagged. | 147 | * send untagged; otherwise, send tagged. |