aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_main.c11
-rw-r--r--net/8021q/vlan_core.c2
-rw-r--r--net/core/dev.c20
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;