Browse Source

[PATCH] bonding: Add priv_flag to avoid event mishandling

Add priv_flag to specifically identify bonding-involved devices.  Needed
because IFF_MASTER is an unreliable identifier (vlan interfaces above bonding
will inherit IFF_MASTER).  Misidentification of devices would cause
notifier events for other devices to be erroneously processed by bonding,
causing various havoc.

Bug discovered by Martin Papik <martin.papik@ipsec.info>; this patch is
modified from his original.

Signed-off-by: Martin Papik <martin.papik@ipsec.info>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Jay Vosburgh 19 years ago
parent
commit
0b680e7537
2 changed files with 7 additions and 1 deletions
  1. 6 1
      drivers/net/bonding/bond_main.c
  2. 1 0
      include/linux/if.h

+ 6 - 1
drivers/net/bonding/bond_main.c

@@ -1371,6 +1371,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	}
 	}
 
 
 	new_slave->dev = slave_dev;
 	new_slave->dev = slave_dev;
+	slave_dev->priv_flags |= IFF_BONDING;
 
 
 	if ((bond->params.mode == BOND_MODE_TLB) ||
 	if ((bond->params.mode == BOND_MODE_TLB) ||
 	    (bond->params.mode == BOND_MODE_ALB)) {
 	    (bond->params.mode == BOND_MODE_ALB)) {
@@ -1784,7 +1785,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	dev_set_mac_address(slave_dev, &addr);
 	dev_set_mac_address(slave_dev, &addr);
 
 
 	slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
 	slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
-				   IFF_SLAVE_INACTIVE);
+				   IFF_SLAVE_INACTIVE | IFF_BONDING);
 
 
 	kfree(slave);
 	kfree(slave);
 
 
@@ -3216,6 +3217,9 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v
 		(event_dev ? event_dev->name : "None"),
 		(event_dev ? event_dev->name : "None"),
 		event);
 		event);
 
 
+	if (!(event_dev->priv_flags & IFF_BONDING))
+		return NOTIFY_DONE;
+
 	if (event_dev->flags & IFF_MASTER) {
 	if (event_dev->flags & IFF_MASTER) {
 		dprintk("IFF_MASTER\n");
 		dprintk("IFF_MASTER\n");
 		return bond_master_netdev_event(event, event_dev);
 		return bond_master_netdev_event(event, event_dev);
@@ -4185,6 +4189,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 	/* Initialize the device options */
 	/* Initialize the device options */
 	bond_dev->tx_queue_len = 0;
 	bond_dev->tx_queue_len = 0;
 	bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
 	bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
+	bond_dev->priv_flags |= IFF_BONDING;
 
 
 	/* At first, we block adding VLANs. That's the only way to
 	/* At first, we block adding VLANs. That's the only way to
 	 * prevent problems that occur when adding VLANs over an
 	 * prevent problems that occur when adding VLANs over an

+ 1 - 0
include/linux/if.h

@@ -59,6 +59,7 @@
 #define IFF_SLAVE_INACTIVE	0x4	/* bonding slave not the curr. active */
 #define IFF_SLAVE_INACTIVE	0x4	/* bonding slave not the curr. active */
 #define IFF_MASTER_8023AD	0x8	/* bonding master, 802.3ad. 	*/
 #define IFF_MASTER_8023AD	0x8	/* bonding master, 802.3ad. 	*/
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
+#define IFF_BONDING	0x20		/* bonding master or slave	*/
 
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
 #define IF_GET_PROTO	0x0002