X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fbonding%2Fbond_main.c;h=bcf9f17daf0d36944d5ec362de405e7be718ab08;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=8171cae066888c23d0ec22d0019bdda9353c840f;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8171cae06..bcf9f17da 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -131,7 +131,7 @@ MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); /*----------------------------- Global variables ----------------------------*/ -static const char * const version = +static const char *version = DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; LIST_HEAD(bond_dev_list); @@ -558,42 +558,6 @@ out: /*------------------------------- Link status -------------------------------*/ -/* - * Set the carrier state for the master according to the state of its - * slaves. If any slaves are up, the master is up. In 802.3ad mode, - * do special 802.3ad magic. - * - * Returns zero if carrier state does not change, nonzero if it does. - */ -static int bond_set_carrier(struct bonding *bond) -{ - struct slave *slave; - int i; - - if (bond->slave_cnt == 0) - goto down; - - if (bond->params.mode == BOND_MODE_8023AD) - return bond_3ad_set_carrier(bond); - - bond_for_each_slave(bond, slave, i) { - if (slave->link == BOND_LINK_UP) { - if (!netif_carrier_ok(bond->dev)) { - netif_carrier_on(bond->dev); - return 1; - } - return 0; - } - } - -down: - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); - return 1; - } - return 0; -} - /* * Get link speed and duplex from the slave's base driver * using ethtool. If for some reason the call fails or the @@ -1076,10 +1040,6 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) if ((bond->params.mode == BOND_MODE_TLB) || (bond->params.mode == BOND_MODE_ALB)) { bond_alb_handle_active_change(bond, new_active); - if (old_active) - bond_set_slave_inactive_flags(old_active); - if (new_active) - bond_set_slave_active_flags(new_active); } else { bond->curr_active_slave = new_active; } @@ -1110,24 +1070,10 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) void bond_select_active_slave(struct bonding *bond) { struct slave *best_slave; - int rv; best_slave = bond_find_best_slave(bond); if (best_slave != bond->curr_active_slave) { bond_change_active_slave(bond, best_slave); - rv = bond_set_carrier(bond); - if (!rv) - return; - - if (netif_carrier_ok(bond->dev)) { - printk(KERN_INFO DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); - } else { - printk(KERN_INFO DRV_NAME ": %s: " - "now running without any active interface !\n", - bond->dev->name); - } } } @@ -1199,7 +1145,8 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) } #define BOND_INTERSECT_FEATURES \ - (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) + (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ + NETIF_F_TSO|NETIF_F_UFO) /* * Compute the common dev->feature set available to all slaves. Some @@ -1217,7 +1164,9 @@ static int bond_compute_features(struct bonding *bond) features &= (slave->dev->features & BOND_INTERSECT_FEATURES); if ((features & NETIF_F_SG) && - !(features & NETIF_F_ALL_CSUM)) + !(features & (NETIF_F_IP_CSUM | + NETIF_F_NO_CSUM | + NETIF_F_HW_CSUM))) features &= ~NETIF_F_SG; /* @@ -1494,25 +1443,20 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) switch (bond->params.mode) { case BOND_MODE_ACTIVEBACKUP: - /* if we're in active-backup mode, we need one and - * only one active interface. The backup interfaces - * will have their SLAVE_INACTIVE flag set because we - * need them to be drop all packets. Thus, since we - * guarantee that curr_active_slave always point to - * the last usable interface, we just have to verify - * this interface's flag. + /* if we're in active-backup mode, we need one and only one active + * interface. The backup interfaces will have their NOARP flag set + * because we need them to be completely deaf and not to respond to + * any ARP request on the network to avoid fooling a switch. Thus, + * since we guarantee that curr_active_slave always point to the last + * usable interface, we just have to verify this interface's flag. */ if (((!bond->curr_active_slave) || - (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && + (bond->curr_active_slave->dev->flags & IFF_NOARP)) && (new_slave->link != BOND_LINK_DOWN)) { + dprintk("This is the first active slave\n"); /* first slave or no active slave yet, and this link is OK, so make this interface the active one */ bond_change_active_slave(bond, new_slave); - printk(KERN_INFO DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); - netif_carrier_on(bond->dev); - } else { dprintk("This is just a backup slave\n"); bond_set_slave_inactive_flags(new_slave); @@ -1548,8 +1492,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) * is OK, so make this interface the active one */ bond_change_active_slave(bond, new_slave); - } else { - bond_set_slave_inactive_flags(new_slave); } break; default: @@ -1568,8 +1510,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) break; } /* switch(bond_mode) */ - bond_set_carrier(bond); - write_unlock_bh(&bond->lock); res = bond_create_slave_symlinks(bond_dev, slave_dev); @@ -1709,12 +1649,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) bond_alb_deinit_slave(bond, slave); } - if (oldcurrent == slave) + if (oldcurrent == slave) { bond_select_active_slave(bond); - if (bond->slave_cnt == 0) { - bond_set_carrier(bond); + if (!bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + } + if (bond->slave_cnt == 0) { /* if the last slave was removed, zero the mac address * of the master so it will be set by the application * to the mac address of the first slave @@ -1778,8 +1724,13 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) addr.sa_family = slave_dev->type; dev_set_mac_address(slave_dev, &addr); - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE); + /* restore the original state of the + * IFF_NOARP flag that might have been + * set by bond_set_slave_inactive_flags() + */ + if ((slave->original_flags & IFF_NOARP) == 0) { + slave_dev->flags &= ~IFF_NOARP; + } kfree(slave); @@ -1798,8 +1749,6 @@ static int bond_release_all(struct net_device *bond_dev) write_lock_bh(&bond->lock); - netif_carrier_off(bond_dev); - if (bond->slave_cnt == 0) { goto out; } @@ -1867,8 +1816,12 @@ static int bond_release_all(struct net_device *bond_dev) addr.sa_family = slave_dev->type; dev_set_mac_address(slave_dev, &addr); - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE); + /* restore the original state of the IFF_NOARP flag that might have + * been set by bond_set_slave_inactive_flags() + */ + if ((slave->original_flags & IFF_NOARP) == 0) { + slave_dev->flags &= ~IFF_NOARP; + } kfree(slave); @@ -2236,9 +2189,15 @@ void bond_mii_monitor(struct net_device *bond_dev) bond_select_active_slave(bond); + if (oldcurrent && !bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + write_unlock(&bond->curr_slave_lock); - } else - bond_set_carrier(bond); + } re_arm: if (bond->params.miimon) { @@ -2542,6 +2501,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev) bond_select_active_slave(bond); + if (oldcurrent && !bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + write_unlock(&bond->curr_slave_lock); } @@ -2615,15 +2581,12 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) bond->current_arp_slave = NULL; } - bond_set_carrier(bond); - if (slave == bond->curr_active_slave) { printk(KERN_INFO DRV_NAME ": %s: %s is up and now the " "active interface\n", bond_dev->name, slave->dev->name); - netif_carrier_on(bond->dev); } else { printk(KERN_INFO DRV_NAME ": %s: backup interface %s is " @@ -2883,8 +2846,7 @@ static void bond_info_show_master(struct seq_file *seq) (curr) ? curr->dev->name : "None"); } - seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ? - "up" : "down"); + seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down"); seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); seq_printf(seq, "Up Delay (ms): %d\n", bond->params.updelay * bond->params.miimon); @@ -3199,7 +3161,7 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave * bond_netdev_event: handle netdev notifier chain events. * * This function receives events for the netdev chain. The caller (an - * ioctl handler calling blocking_notifier_call_chain) holds the necessary + * ioctl handler calling notifier_call_chain) holds the necessary * locks for us to safely manipulate the slave devices (RTNL lock, * dev_probe_lock). */ @@ -4099,17 +4061,14 @@ void bond_set_mode_ops(struct bonding *bond, int mode) bond_dev->hard_start_xmit = bond_xmit_broadcast; break; case BOND_MODE_8023AD: - bond_set_master_3ad_flags(bond); bond_dev->hard_start_xmit = bond_3ad_xmit_xor; if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) bond->xmit_hash_policy = bond_xmit_hash_policy_l34; else bond->xmit_hash_policy = bond_xmit_hash_policy_l2; break; - case BOND_MODE_ALB: - bond_set_master_alb_flags(bond); - /* FALLTHRU */ case BOND_MODE_TLB: + case BOND_MODE_ALB: bond_dev->hard_start_xmit = bond_alb_xmit; bond_dev->set_mac_address = bond_alb_set_mac_address; break; @@ -4188,7 +4147,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) */ bond_dev->features |= NETIF_F_VLAN_CHALLENGED; - /* don't acquire bond device's netif_tx_lock when + /* don't acquire bond device's xmit_lock when * transmitting */ bond_dev->features |= NETIF_F_LLTX; @@ -4571,8 +4530,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond if (newbond) *newbond = bond_dev->priv; - netif_carrier_off(bond_dev); - rtnl_unlock(); /* allows sysfs registration of net device */ res = bond_create_sysfs_entry(bond_dev->priv); goto done;