⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bond_main.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
			       ": 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 + -