📄 bond_main.c
字号:
": Error: cannot enslave VLAN " "challenged slave %s on VLAN enabled " "bond %s\n", slave_dev->name, bond_dev->name); return -EPERM; } else { printk(KERN_WARNING DRV_NAME ": Warning: enslaved VLAN challenged " "slave %s. Adding VLANs will be blocked as " "long as %s is part of bond %s\n", slave_dev->name, slave_dev->name, bond_dev->name); bond_dev->features |= NETIF_F_VLAN_CHALLENGED; } } else { dprintk("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); if (bond->slave_cnt == 0) { /* First slave, and it is not VLAN challenged, * so remove the block of adding VLANs over the bond. */ bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED; } } if (app_abi_ver >= 1) { /* The application is using an ABI, which requires the * slave interface to be closed. */ if ((slave_dev->flags & IFF_UP)) { printk(KERN_ERR DRV_NAME ": Error: %s is up\n", slave_dev->name); res = -EPERM; goto err_undo_flags; } if (slave_dev->set_mac_address == NULL) { printk(KERN_ERR DRV_NAME ": Error: The slave device you specified does " "not support setting the MAC address.\n"); printk(KERN_ERR "Your kernel likely does not support slave " "devices.\n"); res = -EOPNOTSUPP; goto err_undo_flags; } } else { /* The application is not using an ABI, which requires the * slave interface to be open. */ if (!(slave_dev->flags & IFF_UP)) { printk(KERN_ERR DRV_NAME ": Error: %s is not running\n", slave_dev->name); res = -EINVAL; goto err_undo_flags; } if ((bond->params.mode == BOND_MODE_8023AD) || (bond->params.mode == BOND_MODE_TLB) || (bond->params.mode == BOND_MODE_ALB)) { printk(KERN_ERR DRV_NAME ": Error: to use %s mode, you must upgrade " "ifenslave.\n", bond_mode_name(bond->params.mode)); res = -EOPNOTSUPP; goto err_undo_flags; } } new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); if (!new_slave) { res = -ENOMEM; goto err_undo_flags; } memset(new_slave, 0, sizeof(struct slave)); /* save slave's original flags before calling * netdev_set_master and dev_open */ new_slave->original_flags = slave_dev->flags; if (app_abi_ver >= 1) { /* save slave's original ("permanent") mac address for * modes that needs it, and for restoring it upon release, * and then set it to the master's address */ memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); /* set slave to master's mac address * The application already set the master's * mac address to that of the first slave */ memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); addr.sa_family = slave_dev->type; res = slave_dev->set_mac_address(slave_dev, &addr); if (res) { dprintk("Error %d calling set_mac_address\n", res); goto err_free; } /* open the slave since the application closed it */ res = dev_open(slave_dev); if (res) { dprintk("Openning slave %s failed\n", slave_dev->name); goto err_restore_mac; } } res = netdev_set_master(slave_dev, bond_dev); if (res) { dprintk("Error %d calling netdev_set_master\n", res); if (app_abi_ver < 1) { goto err_free; } else { goto err_close; } } new_slave->dev = slave_dev; if ((bond->params.mode == BOND_MODE_TLB) || (bond->params.mode == BOND_MODE_ALB)) { /* bond_alb_init_slave() must be called before all other stages since * it might fail and we do not want to have to undo everything */ res = bond_alb_init_slave(bond, new_slave); if (res) { goto err_unset_master; } } /* If the mode USES_PRIMARY, then the new slave gets the * master's promisc (and mc) settings only if it becomes the * curr_active_slave, and that is taken care of later when calling * bond_change_active() */ if (!USES_PRIMARY(bond->params.mode)) { /* set promiscuity level to new slave */ if (bond_dev->flags & IFF_PROMISC) { dev_set_promiscuity(slave_dev, 1); } /* set allmulti level to new slave */ if (bond_dev->flags & IFF_ALLMULTI) { dev_set_allmulti(slave_dev, 1); } /* upload master's mc_list to new slave */ for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); } } if (bond->params.mode == BOND_MODE_8023AD) { /* add lacpdu mc addr to mc list */ u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; dev_mc_add(slave_dev, lacpdu_multicast, ETH_ALEN, 0); } bond_add_vlans_on_slave(bond, slave_dev); write_lock_bh(&bond->lock); bond_attach_slave(bond, new_slave); new_slave->delay = 0; new_slave->link_failure_count = 0; if (bond->params.miimon && !bond->params.use_carrier) { link_reporting = bond_check_dev_link(bond, slave_dev, 1); if ((link_reporting == -1) && !bond->params.arp_interval) { /* * miimon is set but a bonded network driver * does not support ETHTOOL/MII and * arp_interval is not set. Note: if * use_carrier is enabled, we will never go * here (because netif_carrier is always * supported); thus, we don't need to change * the messages for netif_carrier. */ printk(KERN_WARNING DRV_NAME ": Warning: MII and ETHTOOL support not " "available for interface %s, and " "arp_interval/arp_ip_target module parameters " "not specified, thus bonding will not detect " "link failures! see bonding.txt for details.\n", slave_dev->name); } else if (link_reporting == -1) { /* unable get link status using mii/ethtool */ printk(KERN_WARNING DRV_NAME ": Warning: can't get link status from " "interface %s; the network driver associated " "with this interface does not support MII or " "ETHTOOL link status reporting, thus miimon " "has no effect on this interface.\n", slave_dev->name); } } /* check for initial state */ if (!bond->params.miimon || (bond_check_dev_link(bond, slave_dev, 0) == BMSR_LSTATUS)) { if (bond->params.updelay) { dprintk("Initial state of slave_dev is " "BOND_LINK_BACK\n"); new_slave->link = BOND_LINK_BACK; new_slave->delay = bond->params.updelay; } else { dprintk("Initial state of slave_dev is " "BOND_LINK_UP\n"); new_slave->link = BOND_LINK_UP; } new_slave->jiffies = jiffies; } else { dprintk("Initial state of slave_dev is " "BOND_LINK_DOWN\n"); new_slave->link = BOND_LINK_DOWN; } if (bond_update_speed_duplex(new_slave) && (new_slave->link != BOND_LINK_DOWN)) { printk(KERN_WARNING DRV_NAME ": Warning: failed to get speed/duplex from %s, speed " "forced to 100Mbps, duplex forced to Full.\n", new_slave->dev->name); if (bond->params.mode == BOND_MODE_8023AD) { printk(KERN_WARNING "Operation of 802.3ad mode requires ETHTOOL " "support in base driver for proper aggregator " "selection.\n"); } } if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { /* if there is a primary slave, remember it */ if (strcmp(bond->params.primary, new_slave->dev->name) == 0) { bond->primary_slave = new_slave; } } 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 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->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); } else { dprintk("This is just a backup slave\n"); bond_set_slave_inactive_flags(new_slave); } break; case BOND_MODE_8023AD: /* in 802.3ad mode, the internal mechanism * will activate the slaves in the selected * aggregator */ bond_set_slave_inactive_flags(new_slave); /* if this is the first slave */ if (bond->slave_cnt == 1) { SLAVE_AD_INFO(new_slave).id = 1; /* Initialize AD with the number of times that the AD timer is called in 1 second * can be called only after the mac address of the bond is set */ bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL, bond->params.lacp_fast); } else { SLAVE_AD_INFO(new_slave).id = SLAVE_AD_INFO(new_slave->prev).id + 1; } bond_3ad_bind_slave(new_slave); break; case BOND_MODE_TLB: case BOND_MODE_ALB: new_slave->state = BOND_STATE_ACTIVE; if ((!bond->curr_active_slave) && (new_slave->link != BOND_LINK_DOWN)) { /* 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); } break; default: dprintk("This slave is always active in trunk mode\n"); /* always active in trunk mode */ new_slave->state = BOND_STATE_ACTIVE; /* In trunking mode there is little meaning to curr_active_slave * anyway (it holds no special properties of the bond device), * so we can change it without calling change_active_interface() */ if (!bond->curr_active_slave) { bond->curr_active_slave = new_slave; } break; } /* switch(bond_mode) */ write_unlock_bh(&bond->lock); if (app_abi_ver < 1) { /* * !!! This is to support old versions of ifenslave. * We can remove this in 2.5 because our ifenslave takes * care of this for us. * We check to see if the master has a mac address yet. * If not, we'll give it the mac address of our slave device. */ int ndx = 0; for (ndx = 0; ndx < bond_dev->addr_len; ndx++) { dprintk("Checking ndx=%d of bond_dev->dev_addr\n", ndx); if (bond_dev->dev_addr[ndx] != 0) { dprintk("Found non-zero byte at ndx=%d\n", ndx); break; } } if (ndx == bond_dev->addr_len) { /* * We got all the way through the address and it was * all 0's. */ dprintk("%s doesn't have a MAC address yet. \n", bond_dev->name); dprintk("Going to give assign it from %s.\n", slave_dev->name); bond_sethwaddr(bond_dev, slave_dev); } } printk(KERN_INFO DRV_NAME ": %s: enslaving %s as a%s interface with a%s link.\n", bond_dev->name, slave_dev->name, new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); /* enslave is successful */ return 0;/* Undo stages on error */err_unset_master: netdev_set_master(slave_dev, NULL);err_close: dev_close(slave_dev);err_restore_mac: memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); addr.sa_family = slave_dev->type; slave_dev->set_mac_address(slave_dev, &addr);err_free: kfree(new_slave);err_undo_flags: bond_dev->features = old_features; return res;}/* * Try to release the slave device <slave> from the bond device <master> * It is legal to access curr_active_slave without a lock because all the function * is write-locked. * * The rules for slave state should be: * for Active/Backup: * Active stays on all backups go down * for Bonded connections: * The first up interface should be left on and all others downed. */static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev){ struct bonding *bond = bond_dev->priv; struct slave *slave, *oldcurrent; struct sockaddr addr; int mac_addr_differ; /* slave is not a slave or master is not master of this slave */ if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev)) { printk(KERN_ERR DRV_NAME ": Error: %s: cannot release %s.\n", bond_dev->name, slave_dev-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -