diff options
| -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. |
