Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > d0a35cd31c1125e2132804d68547073d > files > 2059

kernel-2.6.18-194.26.1.el5.src.rpm

From: Andy Gospodarek <gospo@redhat.com>
Date: Thu, 14 Oct 2010 15:43:27 -0400
Subject: [net] bonding: correctly process non-linear skbs
Message-id: <20101014154327.GC9803@gospo.rdu.redhat.com>
Patchwork-id: 28735
O-Subject: Re: [PATCH RHEL5.6][v2] bonding: correctly process non-linear skbs
Bugzilla: 619070
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Neil Horman <nhorman@redhat.com>
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>

It was recently brought to my attention that 802.3ad mode bonds would no
longer form when using some network hardware after a driver update.
After snooping around I realized that the particular hardware was using
page-based skbs and found that skb->data did not contain a valid LACPDU
as it was not stored there.  That explained the inability to form an
802.3ad-based bond.  For balance-alb mode bonds this was also an issue
as ARPs would not be properly processed.

This is a backport of upstream commit:

	commit ab12811c89e88f2e66746790b1fe4469ccb7bdd9
	Author: Andy Gospodarek <andy@greyhouse.net>
	Date:   Fri Sep 10 11:43:20 2010 +0000

	    bonding: correctly process non-linear skbs

Tested by myself and others with good results.

This will resolve RHBZ 619070.

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 378910f..afb458c 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2429,6 +2429,9 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
 	if (!(dev->flags & IFF_MASTER))
 		goto out;
 
+	if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
+		goto out;
+
 	read_lock(&bond->lock);
 	slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
 	if (!slave)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 51c3644..552b760 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -361,6 +361,10 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
 		goto out;
 	}
 
+	if (!pskb_may_pull(skb, sizeof(struct arphdr) +
+				2 * (skb->dev->addr_len + 4)))
+		goto out;
+
 	if (skb->len < sizeof(struct arp_pkt)) {
 		dprintk("Packet is too small to be an ARP\n");
 		goto out;