Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2472

kernel-2.6.18-238.el5.src.rpm

From: Andy Gospodarek <gospo@redhat.com>
Date: Mon, 30 Nov 2009 20:22:51 -0500
Subject: [net] bonding: allow arp_ip_targets on separate vlan from bond device
Message-id: <20091130202250.GV3259@gospo.rdu.redhat.com>
Patchwork-id: 21552
O-Subject: [RHEL5.4 PATCH] bonding: allow arp_ip_targets to be on a separate
	vlan from bond device
Bugzilla: 526976

This allows a bond device to specify an arp_ip_target as a host that is
not on the same vlan as the base bond device.  A configuration like
this, now works:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 qlen 1000
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 qlen 1000
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
8: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::213:21ff:febe:33e9/64 scope link
       valid_lft forever preferred_lft forever
9: bond0.100@bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
    inet 10.0.100.2/24 brd 10.0.100.255 scope global bond0.100
    inet6 fe80::213:21ff:febe:33e9/64 scope link
       valid_lft forever preferred_lft forever

Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 0
Up Delay (ms): 0
Down Delay (ms): 0
ARP Polling Interval (ms): 1000
ARP IP target/s (n.n.n.n form): 10.0.100.1

Slave Interface: eth1
MII Status: up
Link Failure Count: 1
Permanent HW addr: 00:40:05:30:ff:30

Slave Interface: eth0
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:13:21:be:33:e9

Just posted upstream:

http://marc.info/?l=linux-netdev&m=125961211011723&w=2

I have tested this backport with both VLAN accelerated devices and
non-accelerated devices and it works well.  The reporting customer has
also verified the fix.

This will resolve RHBZ 526976.


diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 16485ba..f708fd7 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2778,6 +2778,9 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
 	unsigned char *arp_ptr;
 	__be32 sip, tip;
 
+	while (dev->priv_flags & IFF_802_1Q_VLAN)
+		dev = VLAN_DEV_INFO(dev)->real_dev;
+
 	if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
 		goto out;
 
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 2d18f2c..65f954a 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -161,6 +161,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
 		return NET_RX_DROP;
 	}
 
+	skb->input_dev = skb->dev;
 	skb->dev = grp->vlan_devices[vlan_tag & VLAN_VID_MASK];
 	if (skb->dev == NULL) {
 		dev_kfree_skb_any(skb);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 2c7a5f1..158a2ae 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -904,6 +904,7 @@ static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
 	if (skb_bond_should_drop(skb))
 		goto drop;
 
+	skb->input_dev = skb->dev;
 	skb->dev = grp->vlan_devices[vlan_tci & VLAN_VID_MASK];
 
 	if (!skb->dev)
diff --git a/net/core/dev.c b/net/core/dev.c
index adf5434..9f5f1fa 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1886,8 +1886,8 @@ int netif_receive_skb(struct sk_buff *skb)
 		skb->input_dev = skb->dev;
 
 	null_or_orig = NULL;
-	orig_dev = skb->dev;
-	if (orig_dev->master) {
+	orig_dev = skb->input_dev;
+	if (orig_dev->master && !(skb->dev->priv_flags & IFF_802_1Q_VLAN)) {
 		if (skb_bond_should_drop(skb))
 			null_or_orig = orig_dev; /* deliver only exact match */
 		else
@@ -1962,7 +1962,7 @@ ncls:
 	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
 		if (ptype->type == type &&
 		    (ptype->dev == null_or_orig || ptype->dev == skb->dev ||
-		     ptype->dev == orig_dev)) {
+		     ptype->dev == orig_dev || ptype->dev == orig_dev->master)) {
 			if (pt_prev) 
 				ret = deliver_skb(skb, pt_prev, orig_dev);
 			pt_prev = ptype;