aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan_core.c7
-rw-r--r--net/core/dev.c4
2 files changed, 7 insertions, 4 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index f1f2f7bb6661..163397f1fd5a 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -4,7 +4,7 @@
4#include <linux/netpoll.h> 4#include <linux/netpoll.h>
5#include "vlan.h" 5#include "vlan.h"
6 6
7bool vlan_do_receive(struct sk_buff **skbp) 7bool vlan_do_receive(struct sk_buff **skbp, bool last_handler)
8{ 8{
9 struct sk_buff *skb = *skbp; 9 struct sk_buff *skb = *skbp;
10 u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; 10 u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
@@ -13,7 +13,10 @@ bool vlan_do_receive(struct sk_buff **skbp)
13 13
14 vlan_dev = vlan_find_dev(skb->dev, vlan_id); 14 vlan_dev = vlan_find_dev(skb->dev, vlan_id);
15 if (!vlan_dev) { 15 if (!vlan_dev) {
16 if (vlan_id) 16 /* Only the last call to vlan_do_receive() should change
17 * pkt_type to PACKET_OTHERHOST
18 */
19 if (vlan_id && last_handler)
17 skb->pkt_type = PACKET_OTHERHOST; 20 skb->pkt_type = PACKET_OTHERHOST;
18 return false; 21 return false;
19 } 22 }
diff --git a/net/core/dev.c b/net/core/dev.c
index edcf019c056d..6ba50a1e404c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3283,18 +3283,18 @@ another_round:
3283ncls: 3283ncls:
3284#endif 3284#endif
3285 3285
3286 rx_handler = rcu_dereference(skb->dev->rx_handler);
3286 if (vlan_tx_tag_present(skb)) { 3287 if (vlan_tx_tag_present(skb)) {
3287 if (pt_prev) { 3288 if (pt_prev) {
3288 ret = deliver_skb(skb, pt_prev, orig_dev); 3289 ret = deliver_skb(skb, pt_prev, orig_dev);
3289 pt_prev = NULL; 3290 pt_prev = NULL;
3290 } 3291 }
3291 if (vlan_do_receive(&skb)) 3292 if (vlan_do_receive(&skb, !rx_handler))
3292 goto another_round; 3293 goto another_round;
3293 else if (unlikely(!skb)) 3294 else if (unlikely(!skb))
3294 goto out; 3295 goto out;
3295 } 3296 }
3296 3297
3297 rx_handler = rcu_dereference(skb->dev->rx_handler);
3298 if (rx_handler) { 3298 if (rx_handler) {
3299 if (pt_prev) { 3299 if (pt_prev) {
3300 ret = deliver_skb(skb, pt_prev, orig_dev); 3300 ret = deliver_skb(skb, pt_prev, orig_dev);