diff options
author | David S. Miller <davem@davemloft.net> | 2014-03-29 18:48:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-29 18:48:54 -0400 |
commit | 64c27237a07129758e33f5f824ba5c33b7f57417 (patch) | |
tree | 4c0c0a9b6d282d600f2226e1b3510096b9d789dd /net/bridge | |
parent | 77a9939426f7a3f35f460afc9b11f1fe45955409 (diff) | |
parent | 49d8137a4039c63c834827f4bfe875e27bb9c521 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/marvell/mvneta.c
The mvneta.c conflict is a case of overlapping changes,
a conversion to devm_ioremap_resource() vs. a conversion
to netdev_alloc_pcpu_stats.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_device.c | 6 | ||||
-rw-r--r-- | net/bridge/br_input.c | 11 | ||||
-rw-r--r-- | net/bridge/br_vlan.c | 44 |
3 files changed, 36 insertions, 25 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 0dd01a05bd59..3e2da2cb72db 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -49,14 +49,14 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
49 | brstats->tx_bytes += skb->len; | 49 | brstats->tx_bytes += skb->len; |
50 | u64_stats_update_end(&brstats->syncp); | 50 | u64_stats_update_end(&brstats->syncp); |
51 | 51 | ||
52 | if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid)) | ||
53 | goto out; | ||
54 | |||
55 | BR_INPUT_SKB_CB(skb)->brdev = dev; | 52 | BR_INPUT_SKB_CB(skb)->brdev = dev; |
56 | 53 | ||
57 | skb_reset_mac_header(skb); | 54 | skb_reset_mac_header(skb); |
58 | skb_pull(skb, ETH_HLEN); | 55 | skb_pull(skb, ETH_HLEN); |
59 | 56 | ||
57 | if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid)) | ||
58 | goto out; | ||
59 | |||
60 | if (is_broadcast_ether_addr(dest)) | 60 | if (is_broadcast_ether_addr(dest)) |
61 | br_flood_deliver(br, skb, false); | 61 | br_flood_deliver(br, skb, false); |
62 | else if (is_multicast_ether_addr(dest)) { | 62 | else if (is_multicast_ether_addr(dest)) { |
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 5d5b101be102..91510712c7a7 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -119,22 +119,6 @@ static void __vlan_flush(struct net_port_vlans *v) | |||
119 | kfree_rcu(v, rcu); | 119 | kfree_rcu(v, rcu); |
120 | } | 120 | } |
121 | 121 | ||
122 | /* Strip the tag from the packet. Will return skb with tci set 0. */ | ||
123 | static struct sk_buff *br_vlan_untag(struct sk_buff *skb) | ||
124 | { | ||
125 | if (skb->protocol != htons(ETH_P_8021Q)) { | ||
126 | skb->vlan_tci = 0; | ||
127 | return skb; | ||
128 | } | ||
129 | |||
130 | skb->vlan_tci = 0; | ||
131 | skb = vlan_untag(skb); | ||
132 | if (skb) | ||
133 | skb->vlan_tci = 0; | ||
134 | |||
135 | return skb; | ||
136 | } | ||
137 | |||
138 | struct sk_buff *br_handle_vlan(struct net_bridge *br, | 122 | struct sk_buff *br_handle_vlan(struct net_bridge *br, |
139 | const struct net_port_vlans *pv, | 123 | const struct net_port_vlans *pv, |
140 | struct sk_buff *skb) | 124 | struct sk_buff *skb) |
@@ -144,13 +128,27 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
144 | if (!br->vlan_enabled) | 128 | if (!br->vlan_enabled) |
145 | goto out; | 129 | goto out; |
146 | 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 | |||
147 | /* 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 |
148 | * 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, |
149 | * send untagged; otherwise, send tagged. | 147 | * send untagged; otherwise, send tagged. |
150 | */ | 148 | */ |
151 | br_vlan_get_tag(skb, &vid); | 149 | br_vlan_get_tag(skb, &vid); |
152 | if (test_bit(vid, pv->untagged_bitmap)) | 150 | if (test_bit(vid, pv->untagged_bitmap)) |
153 | skb = br_vlan_untag(skb); | 151 | skb->vlan_tci = 0; |
154 | 152 | ||
155 | out: | 153 | out: |
156 | return skb; | 154 | return skb; |
@@ -174,6 +172,18 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
174 | if (!v) | 172 | if (!v) |
175 | return false; | 173 | return false; |
176 | 174 | ||
175 | /* If vlan tx offload is disabled on bridge device and frame was | ||
176 | * sent from vlan device on the bridge device, it does not have | ||
177 | * HW accelerated vlan tag. | ||
178 | */ | ||
179 | if (unlikely(!vlan_tx_tag_present(skb) && | ||
180 | (skb->protocol == htons(ETH_P_8021Q) || | ||
181 | skb->protocol == htons(ETH_P_8021AD)))) { | ||
182 | skb = vlan_untag(skb); | ||
183 | if (unlikely(!skb)) | ||
184 | return false; | ||
185 | } | ||
186 | |||
177 | err = br_vlan_get_tag(skb, vid); | 187 | err = br_vlan_get_tag(skb, vid); |
178 | if (!*vid) { | 188 | if (!*vid) { |
179 | u16 pvid = br_get_pvid(v); | 189 | u16 pvid = br_get_pvid(v); |