diff options
author | Jay Vosburgh <fubar@us.ibm.com> | 2006-09-23 00:53:39 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-25 20:08:09 -0400 |
commit | 54ef313714070b397d3857289f0fd099b7643631 (patch) | |
tree | 33e0c4ae228ad52a5f5dc9c4389412c436d22d0f /drivers | |
parent | a50d8de2cc872818b61e60c20c75be3f19aa6887 (diff) |
[PATCH] bonding: Handle large hard_header_len
The bonding driver fails to adjust its hard_header_len when enslaving
interfaces. Whenever an interface with a hard_header_len greater than the
ETH_HLEN default is enslaved, the potential for an oops exists, and if the
oops happens while responding to an arp request, for example, the system
panics. GIANFAR devices may use an extended hard_header for VLAN or
hardware checksumming. Enslaving such a device and then transmitting over
it causes a kernel panic.
Patch modified from submitter's original, but submitter agreed with this
patch in private email.
Signed-off-by: Mark Huth <mhuth@mvista.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3d7693d1c512..d2f460b0dbab 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1211,10 +1211,14 @@ static int bond_compute_features(struct bonding *bond) | |||
1211 | unsigned long features = BOND_INTERSECT_FEATURES; | 1211 | unsigned long features = BOND_INTERSECT_FEATURES; |
1212 | struct slave *slave; | 1212 | struct slave *slave; |
1213 | struct net_device *bond_dev = bond->dev; | 1213 | struct net_device *bond_dev = bond->dev; |
1214 | unsigned short max_hard_header_len = ETH_HLEN; | ||
1214 | int i; | 1215 | int i; |
1215 | 1216 | ||
1216 | bond_for_each_slave(bond, slave, i) | 1217 | bond_for_each_slave(bond, slave, i) { |
1217 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); | 1218 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); |
1219 | if (slave->dev->hard_header_len > max_hard_header_len) | ||
1220 | max_hard_header_len = slave->dev->hard_header_len; | ||
1221 | } | ||
1218 | 1222 | ||
1219 | if ((features & NETIF_F_SG) && | 1223 | if ((features & NETIF_F_SG) && |
1220 | !(features & NETIF_F_ALL_CSUM)) | 1224 | !(features & NETIF_F_ALL_CSUM)) |
@@ -1232,6 +1236,7 @@ static int bond_compute_features(struct bonding *bond) | |||
1232 | 1236 | ||
1233 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); | 1237 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); |
1234 | bond_dev->features = features; | 1238 | bond_dev->features = features; |
1239 | bond_dev->hard_header_len = max_hard_header_len; | ||
1235 | 1240 | ||
1236 | return 0; | 1241 | return 0; |
1237 | } | 1242 | } |