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

📄 bonding.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* 	 * queue to the end of the slaves list, make the first element its	 * successor, the last one its predecessor, and make it the bond's	 * predecessor. 	 */	new_slave->prev       = bond->prev;	new_slave->prev->next = new_slave;	bond->prev            = new_slave;	new_slave->next       = bond->next;	new_slave->delay = 0;	new_slave->link_failure_count = 0;	/* check for initial state */	if ((miimon <= 0) || ((bond_check_dev_link(slave_dev) & MII_LINK_READY)		 == MII_LINK_READY)) {#ifdef BONDING_DEBUG		printk(KERN_CRIT "Initial state of slave_dev is BOND_LINK_UP\n");#endif		new_slave->link  = BOND_LINK_UP;	}	else {#ifdef BONDING_DEBUG		printk(KERN_CRIT "Initial state of slave_dev is BOND_LINK_DOWN\n");#endif		new_slave->link  = BOND_LINK_DOWN;	}	/* 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 current_slave always point to the last	 * usable interface, we just have to verify this interface's flag.	 */	if (mode == BOND_MODE_ACTIVEBACKUP) {		if (((bond->current_slave == NULL)			|| (bond->current_slave->dev->flags & IFF_NOARP))			&& (new_slave->link == BOND_LINK_UP)) {#ifdef BONDING_DEBUG			printk(KERN_CRIT "This is the first active slave\n");#endif			/* first slave or no active slave yet, and this link			   is OK, so make this interface the active one */			bond->current_slave = new_slave;			bond_set_slave_active_flags(new_slave);		}		else {#ifdef BONDING_DEBUG			printk(KERN_CRIT "This is just a backup slave\n");#endif			bond_set_slave_inactive_flags(new_slave);		}	} else {#ifdef BONDING_DEBUG		printk(KERN_CRIT "This slave is always active in trunk mode\n");#endif		/* always active in trunk mode */		new_slave->state = BOND_STATE_ACTIVE;		if (bond->current_slave == NULL) {			bond->current_slave = new_slave;		}	}	update_slave_cnt(bond);	write_unlock_irqrestore(&bond->lock, flags);	/*	 * !!! 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.	 */	for (ndx = 0; ndx < slave_dev->addr_len; ndx++) {#ifdef BONDING_DEBUG		printk(KERN_CRIT "Checking ndx=%d of master_dev->dev_addr\n",		       ndx);#endif		if (master_dev->dev_addr[ndx] != 0) {#ifdef BONDING_DEBUG		printk(KERN_CRIT "Found non-zero byte at ndx=%d\n",		       ndx);#endif			break;		}	}	if (ndx == slave_dev->addr_len) {		/*		 * We got all the way through the address and it was		 * all 0's.		 */#ifdef BONDING_DEBUG		printk(KERN_CRIT "%s doesn't have a MAC address yet.  ",		       master_dev->name);		printk(KERN_CRIT "Going to give assign it from %s.\n",		       slave_dev->name);#endif		bond_sethwaddr(master_dev, slave_dev);	}	printk (KERN_INFO "%s: enslaving %s as a%s interface with a%s link.\n",		master_dev->name, slave_dev->name,		new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",		new_slave->link == BOND_LINK_UP ? "n up" : " down");	return 0;}/*  * This function changes the active slave to slave <slave_dev>. * It returns -EINVAL in the following cases. *  - <slave_dev> is not found in the list. *  - There is not active slave now. *  - <slave_dev> is already active. *  - The link state of <slave_dev> is not BOND_LINK_UP. *  - <slave_dev> is not running. * In these cases, this fuction does nothing. * In the other cases, currnt_slave pointer is changed and 0 is returned. */static int bond_change_active(struct net_device *master_dev, struct net_device *slave_dev){	bonding_t *bond;	slave_t *slave;	slave_t *oldactive = NULL;	slave_t *newactive = NULL;	unsigned long flags;	int ret = 0;	if (master_dev == NULL || slave_dev == NULL) {		return -ENODEV;	}	bond = (struct bonding *) master_dev->priv;	write_lock_irqsave(&bond->lock, flags);	slave = (slave_t *)bond;	oldactive = bond->current_slave;	while ((slave = slave->prev) != (slave_t *)bond) {		if(slave_dev == slave->dev) {			newactive = slave;			break;		}	}	if ((newactive != NULL)&&	    (oldactive != NULL)&&	    (newactive != oldactive)&&	    (newactive->link == BOND_LINK_UP)&&	    IS_UP(newactive->dev)) {		bond_set_slave_inactive_flags(oldactive);		bond_set_slave_active_flags(newactive);		bond->current_slave = newactive;		printk("%s : activate %s(old : %s)\n",			master_dev->name, newactive->dev->name, 			oldactive->dev->name);	}	else {		ret = -EINVAL;	}	write_unlock_irqrestore(&bond->lock, flags);	return ret;}/* Choose a new valid interface from the pool, set it active * and make it the current slave. If no valid interface is * found, the oldest slave in BACK state is choosen and * activated. If none is found, it's considered as no * interfaces left so the current slave is set to NULL. * The result is a pointer to the current slave. * * Since this function sends messages tails through printk, the caller * must have started something like `printk(KERN_INFO "xxxx ");'. * * Warning: must put locks around the call to this function if needed. */slave_t *change_active_interface(bonding_t *bond){	slave_t *newslave, *oldslave;	slave_t *bestslave = NULL;	int mintime;	read_lock(&bond->ptrlock);	newslave = oldslave = bond->current_slave;	read_unlock(&bond->ptrlock);	if (newslave == NULL) { /* there were no active slaves left */		if (bond->next != (slave_t *)bond) {  /* found one slave */			write_lock(&bond->ptrlock);			newslave = bond->current_slave = bond->next;			write_unlock(&bond->ptrlock);		} else {			printk (" but could not find any %s interface.\n",				(mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other");			write_lock(&bond->ptrlock);			bond->current_slave = (slave_t *)NULL;			write_unlock(&bond->ptrlock);			return NULL; /* still no slave, return NULL */		}	}	mintime = updelay;	do {		if (IS_UP(newslave->dev)) {			if (newslave->link == BOND_LINK_UP) {				/* this one is immediately usable */				if (mode == BOND_MODE_ACTIVEBACKUP) {					bond_set_slave_active_flags(newslave);					printk (" and making interface %s the active one.\n",						newslave->dev->name);				}				else {					printk (" and setting pointer to interface %s.\n",						newslave->dev->name);				}				write_lock(&bond->ptrlock);				bond->current_slave = newslave;				write_unlock(&bond->ptrlock);				return newslave;			}			else if (newslave->link == BOND_LINK_BACK) {				/* link up, but waiting for stabilization */				if (newslave->delay < mintime) {					mintime = newslave->delay;					bestslave = newslave;				}			}		}	} while ((newslave = newslave->next) != oldslave);	/* no usable backup found, we'll see if we at least got a link that was	   coming back for a long time, and could possibly already be usable.	*/	if (bestslave != NULL) {		/* early take-over. */		printk (" and making interface %s the active one %d ms earlier.\n",			bestslave->dev->name,			(updelay - bestslave->delay)*miimon);		bestslave->delay = 0;		bestslave->link = BOND_LINK_UP;		bond_set_slave_active_flags(bestslave);		write_lock(&bond->ptrlock);		bond->current_slave = bestslave;		write_unlock(&bond->ptrlock);		return bestslave;	}	printk (" but could not find any %s interface.\n",		(mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other");		/* absolutely nothing found. let's return NULL */	write_lock(&bond->ptrlock);	bond->current_slave = (slave_t *)NULL;	write_unlock(&bond->ptrlock);	return NULL;}/* * Try to release the slave device <slave> from the bond device <master> * It is legal to access current_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 *master, struct net_device *slave){	bonding_t *bond;	slave_t *our_slave, *old_current;	unsigned long flags;		if (master == NULL || slave == NULL)  {		return -ENODEV;	}	bond = (struct bonding *) master->priv;	write_lock_irqsave(&bond->lock, flags);	/* master already enslaved, or slave not enslaved,	   or no slave for this master */	if ((master->flags & IFF_SLAVE) || !(slave->flags & IFF_SLAVE)) {		printk (KERN_DEBUG "%s: cannot release %s.\n", master->name, slave->name);		write_unlock_irqrestore(&bond->lock, flags);		return -EINVAL;	}	our_slave = (slave_t *)bond;	old_current = bond->current_slave;	while ((our_slave = our_slave->prev) != (slave_t *)bond) {		if (our_slave->dev == slave) {			bond_detach_slave(bond, our_slave);			printk (KERN_INFO "%s: releasing %s interface %s",				master->name,				(our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",				slave->name);			if (our_slave == old_current) {				/* find a new interface and be verbose */				change_active_interface(bond); 			} else {				printk(".\n");			}			kfree(our_slave);			/* release the slave from its bond */			 			netdev_set_master(slave, NULL);			/* only restore its RUNNING flag if monitoring set it down */			if (slave->flags & IFF_UP) {				slave->flags |= IFF_RUNNING;			}			if (slave->flags & IFF_NOARP || 				bond->current_slave != NULL) {					dev_close(slave);			}			if (bond->current_slave == NULL) {				printk(KERN_INFO					"%s: now running without any active interface !\n",					master->name);			}			update_slave_cnt(bond);			write_unlock_irqrestore(&bond->lock, flags);			return 0;  /* deletion OK */		}	}	/* if we get here, it's because the device was not found */	write_unlock_irqrestore(&bond->lock, flags);	printk (KERN_INFO "%s: %s not enslaved\n", master->name, slave->name);	return -EINVAL;}/*  * This function releases all slaves. * Warning: must put write-locks around the call to this function. */static int bond_release_all(struct net_device *master){	bonding_t *bond;	slave_t *our_slave;	struct net_device *slave_dev;	if (master == NULL)  {		return -ENODEV;	}	if (master->flags & IFF_SLAVE) {		return -EINVAL;	}	bond = (struct bonding *) master->priv;	bond->current_slave = NULL;	while ((our_slave = bond->prev) != (slave_t *)bond) {		slave_dev = our_slave->dev;		bond->prev = our_slave->prev;		kfree(our_slave);		netdev_set_master(slave_dev, NULL);		/* only restore its RUNNING flag if monitoring set it down */		if (slave_dev->flags & IFF_UP)			slave_dev->flags |= IFF_RUNNING;		if (slave_dev->flags & IFF_NOARP)			dev_close(slave_dev);	}	bond->next = (slave_t *)bond;	bond->slave_cnt = 0;	printk (KERN_INFO "%s: releases all slaves\n", master->name);	return 0;}/* this function is called regularly to monitor each slave's link. */static void bond_mii_monitor(struct net_device *master){	bonding_t *bond = (struct bonding *) master->priv;	slave_t *slave, *bestslave, *oldcurrent;	unsigned long flags;	int slave_died = 0;	read_lock_irqsave(&bond->lock, flags);	/* we will try to read the link status of each of our slaves, and	 * set their IFF_RUNNING flag appropriately. For each slave not	 * supporting MII status, we won't do anything so that a user-space	 * program could monitor the link itself if needed.	 */	bestslave = NULL;	slave = (slave_t *)bond;	read_lock(&bond->ptrlock);	oldcurrent = bond->current_slave;	read_unlock(&bond->ptrlock);	while ((slave = slave->prev) != (slave_t *)bond) {		/* use updelay+1 to match an UP slave even when updelay is 0 */		int mindelay = updelay + 1;		struct net_device *dev = slave->dev;		u16 link_state;				link_state = bond_check_dev_link(dev);		switch (slave->link) {		case BOND_LINK_UP:	/* the link was up */			if ((link_state & MII_LINK_UP) == MII_LINK_UP) {				/* link stays up, tell that this one				   is immediately available */				if (IS_UP(dev) && (mindelay > -2)) {					/* -2 is the best case :					   this slave was already up */					mindelay = -2;					bestslave = slave;				}				break;			}			else { /* link going down */				slave->link  = BOND_LINK_FAIL;				slave->delay = downdelay;				if (slave->link_failure_count < UINT_MAX) {					slave->link_failure_count++;				}				if (downdelay > 0) {					printk (KERN_INFO						"%s: link status down for %sinterface "						"%s, disabling it in %d ms.\n",						master->name,						IS_UP(dev)						? ((mode == BOND_MODE_ACTIVEBACKUP)						   ? ((slave == oldcurrent)						      ? "active " : "backup ")						   : "")						: "idle ",						dev->name,						downdelay * miimon);					}			}			/* no break ! fall through the BOND_LINK_FAIL test to			   ensure proper action to be taken			*/		case BOND_LINK_FAIL:	/* the link has just gone down */			if ((link_state & MII_LINK_UP) == 0) {				/* link stays down */				if (slave->delay <= 0) {					/* link down for too long time */					slave->link = BOND_LINK_DOWN;					/* in active/backup mode, we must					   completely disable this interface */					if (mode == BOND_MODE_ACTIVEBACKUP) {						bond_set_slave_inactive_flags(slave);					}					printk(KERN_INFO						"%s: link status definitely down "						"for interface %s, disabling it",						master->name,						dev->name);					read_lock(&bond->ptrlock);					if (slave == bond->current_slave) {						read_unlock(&bond->ptrlock);						/* find a new interface and be verbose */						change_active_interface(bond);					} else {						read_unlock(&bond->ptrlock);						printk(".\n");					}					slave_died = 1;				} else {					slave->delay--;				}			} else if ((link_state & MII_LINK_READY) == MII_LINK_READY) {				/* link up again */				slave->link  = BOND_LINK_UP;				printk(KERN_INFO					"%s: link status up again after %d ms "					"for interface %s.\n",					master->name,					(downdelay - slave->delay) * miimon,					dev->name);				if (IS_UP(dev) && (mindelay > -1)) {					/* -1 is a good case : this slave went					   down only for a short time */					mindelay = -1;					bestslave = slave;				}			}			break;		case BOND_LINK_DOWN:	/* the link was down */			if ((link_state & MII_LINK_READY) != MII_LINK_READY) {				/* the link stays down, nothing more to do */				break;			} else {	/* link going up */				slave->link  = BOND_LINK_BACK;				slave->delay = updelay;								if (updelay > 0) {					/* if updelay == 0, no need to					   advertise about a 0 ms delay */					printk (KERN_INFO						"%s: link status up for interface"						" %s, enabling it in %d ms.\n",						master->name,						dev->name,						updelay * miimon);				}			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -