Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] bonding: fix feature consolidation

This should resolve http://bugzilla.kernel.org/show_bug.cgi?id=5519

The current feature computation loses bits that it doesn't know about,
resulting in an inability to add VLANs and possibly other havoc.
Rewrote function to preserve bits it doesn't know about, remove an
unneeded state variable, and simplify the code.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Jay Vosburgh and committed by
John W. Linville
8e3babcd fd7a516e

+13 -26
+11 -21
drivers/net/bonding/bond_main.c
··· 1604 1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) 1605 1605 1606 1606 /* 1607 - * Compute the features available to the bonding device by 1608 - * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. 1609 - * Call this after attaching or detaching a slave to update the 1610 - * bond's features. 1607 + * Compute the common dev->feature set available to all slaves. Some 1608 + * feature bits are managed elsewhere, so preserve feature bits set on 1609 + * master device that are not part of the examined set. 1611 1610 */ 1612 1611 static int bond_compute_features(struct bonding *bond) 1613 1612 { 1614 - int i; 1613 + unsigned long features = BOND_INTERSECT_FEATURES; 1615 1614 struct slave *slave; 1616 1615 struct net_device *bond_dev = bond->dev; 1617 - int features = bond->bond_features; 1616 + int i; 1618 1617 1619 - bond_for_each_slave(bond, slave, i) { 1620 - struct net_device * slave_dev = slave->dev; 1621 - if (i == 0) { 1622 - features |= BOND_INTERSECT_FEATURES; 1623 - } 1624 - features &= 1625 - ~(~slave_dev->features & BOND_INTERSECT_FEATURES); 1626 - } 1618 + bond_for_each_slave(bond, slave, i) 1619 + features &= (slave->dev->features & BOND_INTERSECT_FEATURES); 1627 1620 1628 - /* turn off NETIF_F_SG if we need a csum and h/w can't do it */ 1629 1621 if ((features & NETIF_F_SG) && 1630 - !(features & (NETIF_F_IP_CSUM | 1631 - NETIF_F_NO_CSUM | 1632 - NETIF_F_HW_CSUM))) { 1622 + !(features & (NETIF_F_IP_CSUM | 1623 + NETIF_F_NO_CSUM | 1624 + NETIF_F_HW_CSUM))) 1633 1625 features &= ~NETIF_F_SG; 1634 - } 1635 1626 1627 + features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); 1636 1628 bond_dev->features = features; 1637 1629 1638 1630 return 0; ··· 4552 4560 bond_dev->features |= (NETIF_F_HW_VLAN_TX | 4553 4561 NETIF_F_HW_VLAN_RX | 4554 4562 NETIF_F_HW_VLAN_FILTER); 4555 - 4556 - bond->bond_features = bond_dev->features; 4557 4563 4558 4564 #ifdef CONFIG_PROC_FS 4559 4565 bond_create_proc_entry(bond);
+2 -5
drivers/net/bonding/bonding.h
··· 40 40 #include "bond_3ad.h" 41 41 #include "bond_alb.h" 42 42 43 - #define DRV_VERSION "2.6.4" 44 - #define DRV_RELDATE "September 26, 2005" 43 + #define DRV_VERSION "2.6.5" 44 + #define DRV_RELDATE "November 4, 2005" 45 45 #define DRV_NAME "bonding" 46 46 #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 47 47 ··· 211 211 struct bond_params params; 212 212 struct list_head vlan_list; 213 213 struct vlan_group *vlgrp; 214 - /* the features the bonding device supports, independently 215 - * of any slaves */ 216 - int bond_features; 217 214 }; 218 215 219 216 /**