diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 11 | ||||
-rw-r--r-- | net/8021q/vlan_core.c | 2 | ||||
-rw-r--r-- | net/core/dev.c | 20 |
3 files changed, 30 insertions, 3 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3f0071cfe56b..6a42a1453afa 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2615,6 +2615,17 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack | |||
2615 | unsigned char *arp_ptr; | 2615 | unsigned char *arp_ptr; |
2616 | __be32 sip, tip; | 2616 | __be32 sip, tip; |
2617 | 2617 | ||
2618 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | ||
2619 | /* | ||
2620 | * When using VLANS and bonding, dev and oriv_dev may be | ||
2621 | * incorrect if the physical interface supports VLAN | ||
2622 | * acceleration. With this change ARP validation now | ||
2623 | * works for hosts only reachable on the VLAN interface. | ||
2624 | */ | ||
2625 | dev = vlan_dev_real_dev(dev); | ||
2626 | orig_dev = dev_get_by_index_rcu(dev_net(skb->dev),skb->skb_iif); | ||
2627 | } | ||
2628 | |||
2618 | if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) | 2629 | if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) |
2619 | goto out; | 2630 | goto out; |
2620 | 2631 | ||
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index e75a2f3b10af..c0316e0ca6e8 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -14,6 +14,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
14 | if (skb_bond_should_drop(skb)) | 14 | if (skb_bond_should_drop(skb)) |
15 | goto drop; | 15 | goto drop; |
16 | 16 | ||
17 | skb->skb_iif = skb->dev->ifindex; | ||
17 | __vlan_hwaccel_put_tag(skb, vlan_tci); | 18 | __vlan_hwaccel_put_tag(skb, vlan_tci); |
18 | skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); | 19 | skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); |
19 | 20 | ||
@@ -85,6 +86,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, | |||
85 | if (skb_bond_should_drop(skb)) | 86 | if (skb_bond_should_drop(skb)) |
86 | goto drop; | 87 | goto drop; |
87 | 88 | ||
89 | skb->skb_iif = skb->dev->ifindex; | ||
88 | __vlan_hwaccel_put_tag(skb, vlan_tci); | 90 | __vlan_hwaccel_put_tag(skb, vlan_tci); |
89 | skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); | 91 | skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); |
90 | 92 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index a8d68cdedbbe..f9aa699ab6cb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2495,12 +2495,26 @@ ncls: | |||
2495 | if (!skb) | 2495 | if (!skb) |
2496 | goto out; | 2496 | goto out; |
2497 | 2497 | ||
2498 | /* | ||
2499 | * Make sure frames received on VLAN interfaces stacked on | ||
2500 | * bonding interfaces still make their way to any base bonding | ||
2501 | * device that may have registered for a specific ptype. The | ||
2502 | * handler may have to adjust skb->dev and orig_dev. | ||
2503 | * | ||
2504 | * null_or_orig can be overloaded since it will not be set when | ||
2505 | * using VLANs on top of bonding. Putting it here prevents | ||
2506 | * disturbing the ptype_all handlers above. | ||
2507 | */ | ||
2508 | if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) && | ||
2509 | (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) { | ||
2510 | null_or_orig = vlan_dev_real_dev(skb->dev); | ||
2511 | } | ||
2512 | |||
2498 | type = skb->protocol; | 2513 | type = skb->protocol; |
2499 | list_for_each_entry_rcu(ptype, | 2514 | list_for_each_entry_rcu(ptype, |
2500 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { | 2515 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { |
2501 | if (ptype->type == type && | 2516 | if (ptype->type == type && (ptype->dev == null_or_orig || |
2502 | (ptype->dev == null_or_orig || ptype->dev == skb->dev || | 2517 | ptype->dev == skb->dev || ptype->dev == orig_dev)) { |
2503 | ptype->dev == orig_dev)) { | ||
2504 | if (pt_prev) | 2518 | if (pt_prev) |
2505 | ret = deliver_skb(skb, pt_prev, orig_dev); | 2519 | ret = deliver_skb(skb, pt_prev, orig_dev); |
2506 | pt_prev = ptype; | 2520 | pt_prev = ptype; |