diff options
-rw-r--r-- | include/linux/skbuff.h | 5 | ||||
-rw-r--r-- | net/8021q/vlan_core.c | 4 | ||||
-rw-r--r-- | net/core/dev.c | 17 |
3 files changed, 20 insertions, 6 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index bf243fc54959..f89e7fd59a4c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -380,7 +380,10 @@ struct sk_buff { | |||
380 | kmemcheck_bitfield_begin(flags2); | 380 | kmemcheck_bitfield_begin(flags2); |
381 | __u16 queue_mapping:16; | 381 | __u16 queue_mapping:16; |
382 | #ifdef CONFIG_IPV6_NDISC_NODETYPE | 382 | #ifdef CONFIG_IPV6_NDISC_NODETYPE |
383 | __u8 ndisc_nodetype:2; | 383 | __u8 ndisc_nodetype:2, |
384 | deliver_no_wcard:1; | ||
385 | #else | ||
386 | __u8 deliver_no_wcard:1; | ||
384 | #endif | 387 | #endif |
385 | kmemcheck_bitfield_end(flags2); | 388 | kmemcheck_bitfield_end(flags2); |
386 | 389 | ||
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index bd537fc10254..50f58f5f1c34 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -12,7 +12,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
12 | return NET_RX_DROP; | 12 | return NET_RX_DROP; |
13 | 13 | ||
14 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) | 14 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) |
15 | goto drop; | 15 | skb->deliver_no_wcard = 1; |
16 | 16 | ||
17 | skb->skb_iif = skb->dev->ifindex; | 17 | skb->skb_iif = skb->dev->ifindex; |
18 | __vlan_hwaccel_put_tag(skb, vlan_tci); | 18 | __vlan_hwaccel_put_tag(skb, vlan_tci); |
@@ -84,7 +84,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, | |||
84 | struct sk_buff *p; | 84 | struct sk_buff *p; |
85 | 85 | ||
86 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) | 86 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) |
87 | goto drop; | 87 | skb->deliver_no_wcard = 1; |
88 | 88 | ||
89 | skb->skb_iif = skb->dev->ifindex; | 89 | skb->skb_iif = skb->dev->ifindex; |
90 | __vlan_hwaccel_put_tag(skb, vlan_tci); | 90 | __vlan_hwaccel_put_tag(skb, vlan_tci); |
diff --git a/net/core/dev.c b/net/core/dev.c index 14a85682af38..2b3bf53bc687 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2810,13 +2810,24 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
2810 | if (!skb->skb_iif) | 2810 | if (!skb->skb_iif) |
2811 | skb->skb_iif = skb->dev->ifindex; | 2811 | skb->skb_iif = skb->dev->ifindex; |
2812 | 2812 | ||
2813 | /* | ||
2814 | * bonding note: skbs received on inactive slaves should only | ||
2815 | * be delivered to pkt handlers that are exact matches. Also | ||
2816 | * the deliver_no_wcard flag will be set. If packet handlers | ||
2817 | * are sensitive to duplicate packets these skbs will need to | ||
2818 | * be dropped at the handler. The vlan accel path may have | ||
2819 | * already set the deliver_no_wcard flag. | ||
2820 | */ | ||
2813 | null_or_orig = NULL; | 2821 | null_or_orig = NULL; |
2814 | orig_dev = skb->dev; | 2822 | orig_dev = skb->dev; |
2815 | master = ACCESS_ONCE(orig_dev->master); | 2823 | master = ACCESS_ONCE(orig_dev->master); |
2816 | if (master) { | 2824 | if (skb->deliver_no_wcard) |
2817 | if (skb_bond_should_drop(skb, master)) | 2825 | null_or_orig = orig_dev; |
2826 | else if (master) { | ||
2827 | if (skb_bond_should_drop(skb, master)) { | ||
2828 | skb->deliver_no_wcard = 1; | ||
2818 | null_or_orig = orig_dev; /* deliver only exact match */ | 2829 | null_or_orig = orig_dev; /* deliver only exact match */ |
2819 | else | 2830 | } else |
2820 | skb->dev = master; | 2831 | skb->dev = master; |
2821 | } | 2832 | } |
2822 | 2833 | ||