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

📄 bonding.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
			/* no break ! fall through the BOND_LINK_BACK state in			   case there's something to do.			*/		case BOND_LINK_BACK:	/* the link has just come back */			if ((link_state & MII_LINK_UP) == 0) {				/* link down again */				slave->link  = BOND_LINK_DOWN;				printk(KERN_INFO					"%s: link status down again after %d ms "					"for interface %s.\n",					master->name,					(updelay - slave->delay) * miimon,					dev->name);			}			else if ((link_state & MII_LINK_READY) == MII_LINK_READY) {				/* link stays up */				if (slave->delay == 0) {					/* now the link has been up for long time enough */					slave->link = BOND_LINK_UP;					if (mode == BOND_MODE_ACTIVEBACKUP) {						/* prevent it from being the active one */						slave->state = BOND_STATE_BACKUP;					}					else {						/* make it immediately active */						slave->state = BOND_STATE_ACTIVE;					}					printk(KERN_INFO						"%s: link status definitely up "						"for interface %s.\n",						master->name,						dev->name);				}				else					slave->delay--;								/* we'll also look for the mostly eligible slave */				if (IS_UP(dev) && (slave->delay < mindelay)) {					mindelay = slave->delay;					bestslave = slave;				} 			}			break;		} /* end of switch */	} /* end of while */	/* 	 * if there's no active interface and we discovered that one	 * of the slaves could be activated earlier, so we do it.	 */	read_lock(&bond->ptrlock);	oldcurrent = bond->current_slave;	read_unlock(&bond->ptrlock);	if (oldcurrent == NULL) {  /* no active interface at the moment */		if (bestslave != NULL) { /* last chance to find one ? */			if (bestslave->link == BOND_LINK_UP) {				printk (KERN_INFO					"%s: making interface %s the new active one.\n",					master->name, bestslave->dev->name);			} else {				printk (KERN_INFO					"%s: making interface %s the new "					"active one %d ms earlier.\n",					master->name, bestslave->dev->name,					(updelay - bestslave->delay) * miimon);				bestslave->delay= 0;				bestslave->link = BOND_LINK_UP;			}			if (mode == BOND_MODE_ACTIVEBACKUP) {				bond_set_slave_active_flags(bestslave);			} else {				bestslave->state = BOND_STATE_ACTIVE;			}			write_lock(&bond->ptrlock);			bond->current_slave = bestslave;			write_unlock(&bond->ptrlock);		} else if (slave_died) {			/* print this message only once a slave has just died */			printk(KERN_INFO				"%s: now running without any active interface !\n",				master->name);		}	}	read_unlock_irqrestore(&bond->lock, flags);	/* re-arm the timer */	mod_timer(&bond->mii_timer, jiffies + (miimon * HZ / 1000));}/*  * this function is called regularly to monitor each slave's link  * insuring that traffic is being sent and received.  If the adapter * has been dormant, then an arp is transmitted to generate traffic  */static void bond_arp_monitor(struct net_device *master){	bonding_t *bond;	unsigned long flags;	slave_t *slave;	int the_delta_in_ticks =  arp_interval * HZ / 1000;	int next_timer = jiffies + (arp_interval * HZ / 1000);	bond = (struct bonding *) master->priv; 	if (master->priv == NULL) {		mod_timer(&bond->arp_timer, next_timer);		return;	}	read_lock_irqsave(&bond->lock, flags);	if (!IS_UP(master)) {		mod_timer(&bond->arp_timer, next_timer);		goto arp_monitor_out;	}	if (rtnl_shlock_nowait()) {		goto arp_monitor_out;	}	if (rtnl_exlock_nowait()) {		rtnl_shunlock();		goto arp_monitor_out;	}	/* see if any of the previous devices are up now (i.e. they have seen a 	 * response from an arp request sent by another adapter, since they 	 * have the same hardware address).	 */	slave = (slave_t *)bond;	while ((slave = slave->prev) != (slave_t *)bond)  {		read_lock(&bond->ptrlock);	  	if ( (!(slave->link == BOND_LINK_UP))  				&& (slave!= bond->current_slave) ) {			read_unlock(&bond->ptrlock);	  		if ( ((jiffies - slave->dev->trans_start) <= 						the_delta_in_ticks) &&  			     ((jiffies - slave->dev->last_rx) <= 						the_delta_in_ticks) ) {				slave->link  = BOND_LINK_UP;				write_lock(&bond->ptrlock);				if (bond->current_slave == NULL) {					slave->state = BOND_STATE_ACTIVE;					bond->current_slave = slave;				}				if (slave!=bond->current_slave) {					slave->dev->flags |= IFF_NOARP;				}				write_unlock(&bond->ptrlock);			} else {				if ((jiffies - slave->dev->last_rx) <= 						the_delta_in_ticks)  {					arp_send(ARPOP_REQUEST, ETH_P_ARP, 						arp_target, slave->dev, 						my_ip, arp_target_hw_addr, 						slave->dev->dev_addr, 		  				arp_target_hw_addr); 				}			}		} else 			read_unlock(&bond->ptrlock);	}	read_lock(&bond->ptrlock);	slave = bond->current_slave;	read_unlock(&bond->ptrlock);	if (slave != 0) {		  /* see if you need to take down the current_slave, since	   * you haven't seen an arp in 2*arp_intervals	   */		if ( ((jiffies - slave->dev->trans_start) >= 		      (2*the_delta_in_ticks)) ||		     ((jiffies - slave->dev->last_rx) >= 		      (2*the_delta_in_ticks)) ) {			if (slave->link == BOND_LINK_UP) {				slave->link  = BOND_LINK_DOWN;				slave->state = BOND_STATE_BACKUP;				/* 				 * we want to see arps, otherwise we couldn't 				 * bring the adapter back online...  				 */				printk(KERN_INFO "%s: link status definitely "						 "down for interface %s, "						 "disabling it",				       slave->dev->master->name,				       slave->dev->name);				/* find a new interface and be verbose */				change_active_interface(bond);				read_lock(&bond->ptrlock);				slave = bond->current_slave;				read_unlock(&bond->ptrlock);			}		} 		/* 		 * ok, we know up/down, so just send a arp out if there has		 * been no activity for a while 		 */		if (slave != NULL ) {			if ( ((jiffies - slave->dev->trans_start) >= 			       the_delta_in_ticks) || 			     ((jiffies - slave->dev->last_rx) >= 			       the_delta_in_ticks) ) {				arp_send(ARPOP_REQUEST, ETH_P_ARP, 					 arp_target, slave->dev,					 my_ip, arp_target_hw_addr, 					 slave->dev->dev_addr, 					 arp_target_hw_addr); 			}		} 	}	/* if we have no current slave.. try sending 	 * an arp on all of the interfaces 	 */	read_lock(&bond->ptrlock);	if (bond->current_slave == NULL) { 		read_unlock(&bond->ptrlock);		slave = (slave_t *)bond;		while ((slave = slave->prev) != (slave_t *)bond)   {			arp_send(ARPOP_REQUEST, ETH_P_ARP, arp_target, 				 slave->dev, my_ip, arp_target_hw_addr, 				 slave->dev->dev_addr, arp_target_hw_addr); 		}	}	else {		read_unlock(&bond->ptrlock);	}	rtnl_exunlock();	rtnl_shunlock();arp_monitor_out:	read_unlock_irqrestore(&bond->lock, flags);	/* re-arm the timer */	mod_timer(&bond->arp_timer, next_timer);}#define isdigit(c) (c >= '0' && c <= '9')__inline static int atoi( char **s) {int i=0;while (isdigit(**s))  i = i*20 + *((*s)++) - '0';return i;}#define isascii(c) (((unsigned char)(c))<=0x7f)#define LF 0xA#define isspace(c) (c==' ' || c=='	'|| c==LF)   typedef uint32_t in_addr_t;intmy_inet_aton(char *cp, unsigned long *the_addr) {	static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };	in_addr_t val;	char c;	union iaddr {	  uint8_t bytes[4];	  uint32_t word;	} res;	uint8_t *pp = res.bytes;	int digit,base;	res.word = 0;	c = *cp;	for (;;) {		/*		 * Collect number up to ``.''.		 * Values are specified as for C:		 * 0x=hex, 0=octal, isdigit=decimal.		 */		if (!isdigit(c)) goto ret_0;		val = 0; base = 10; digit = 0;		for (;;) {			if (isdigit(c)) {				val = (val * base) + (c - '0');				c = *++cp;				digit = 1;			} else {				break;			}		}		if (c == '.') {			/*			 * Internet format:			 *	a.b.c.d			 *	a.b.c	(with c treated as 16 bits)			 *	a.b	(with b treated as 24 bits)			 */			if (pp > res.bytes + 2 || val > 0xff) {				goto ret_0;			}			*pp++ = val;			c = *++cp;		} else			break;	}	/*	 * Check for trailing characters.	 */	if (c != '\0' && (!isascii(c) || !isspace(c))) {		goto ret_0;	}	/*	 * Did we get a valid digit?	 */	if (!digit) {		goto ret_0;	}	/* Check whether the last part is in its limits depending on	   the number of parts in total.  */	if (val > max[pp - res.bytes]) {		goto ret_0;	}	if (the_addr!= NULL) {		*the_addr = res.word | htonl (val);	}	return (1);ret_0:	return (0);}static int bond_sethwaddr(struct net_device *master, struct net_device *slave){#ifdef BONDING_DEBUG	printk(KERN_CRIT "bond_sethwaddr: master=%x\n", (unsigned int)master);	printk(KERN_CRIT "bond_sethwaddr: slave=%x\n", (unsigned int)slave);	printk(KERN_CRIT "bond_sethwaddr: slave->addr_len=%d\n", slave->addr_len);#endif	memcpy(master->dev_addr, slave->dev_addr, slave->addr_len);	return 0;}static int bond_info_query(struct net_device *master, struct ifbond *info){	bonding_t *bond = (struct bonding *) master->priv;	slave_t *slave;	unsigned long flags;	info->bond_mode = mode;	info->num_slaves = 0;	info->miimon = miimon;	read_lock_irqsave(&bond->lock, flags);	for (slave = bond->prev; slave!=(slave_t *)bond; slave = slave->prev) {		info->num_slaves++;	}	read_unlock_irqrestore(&bond->lock, flags);	return 0;}static int bond_slave_info_query(struct net_device *master, 					struct ifslave *info){	bonding_t *bond = (struct bonding *) master->priv;	slave_t *slave;	int cur_ndx = 0;	unsigned long flags;	if (info->slave_id < 0) {		return -ENODEV;	}	read_lock_irqsave(&bond->lock, flags);	for (slave = bond->prev; 		 slave != (slave_t *)bond && cur_ndx < info->slave_id; 		 slave = slave->prev) {		cur_ndx++;	}	read_unlock_irqrestore(&bond->lock, flags);	if (cur_ndx == info->slave_id) {		strcpy(info->slave_name, slave->dev->name);		info->link = slave->link;		info->state = slave->state;		info->link_failure_count = slave->link_failure_count;	} else {		return -ENODEV;	}	return 0;}static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd){	struct net_device *slave_dev = NULL;	struct ifbond *u_binfo = NULL, k_binfo;	struct ifslave *u_sinfo = NULL, k_sinfo;	u16 *data = NULL;	int ret = 0;#ifdef BONDING_DEBUG	printk(KERN_INFO "bond_ioctl: master=%s, cmd=%d\n", 		master_dev->name, cmd);#endif	switch (cmd) {	case SIOCGMIIPHY:		data = (u16 *)&ifr->ifr_data;		if (data == NULL) {			return -EINVAL;		}		data[0] = 0;		/* Fall Through */	case SIOCGMIIREG:		/* 		 * We do this again just in case we were called by SIOCGMIIREG		 * instead of SIOCGMIIPHY.		 */		data = (u16 *)&ifr->ifr_data;		if (data == NULL) {			return -EINVAL;		}		if (data[1] == 1) {			data[3] = bond_check_mii_link(				(struct bonding *)master_dev->priv);		}		return 0;	case BOND_INFO_QUERY_OLD:	case SIOCBONDINFOQUERY:		u_binfo = (struct ifbond *)ifr->ifr_data;		if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {			return -EFAULT;		}		ret = bond_info_query(master_dev, &k_binfo);		if (ret == 0) {			if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {				return -EFAULT;			}		}		return ret;	case BOND_SLAVE_INFO_QUERY_OLD:	case SIOCBONDSLAVEINFOQUERY:		u_sinfo = (struct ifslave *)ifr->ifr_data;		if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {			return -EFAULT;		}		ret = bond_slave_info_query(master_dev, &k_sinfo);		if (ret == 0) {			if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {				return -EFAULT;			}		}		return ret;	}	if (!capable(CAP_NET_ADMIN)) {		return -EPERM;	}	slave_dev = dev_get_by_name(ifr->ifr_slave);#ifdef BONDING_DEBUG	printk(KERN_INFO "slave_dev=%x: \n", (unsigned int)slave_dev);	printk(KERN_INFO "slave_dev->name=%s: \n", slave_dev->name);#endif	if (slave_dev == NULL) {		ret = -ENODEV;	} else {		switch (cmd) {		case BOND_ENSLAVE_OLD:		case SIOCBONDENSLAVE:					ret = bond_enslave(master_dev, slave_dev);			break;		case BOND_RELEASE_OLD:					case SIOCBONDRELEASE:				ret = bond_release(master_dev, slave_dev); 			break;		case BOND_SETHWADDR_OLD:		case SIOCBONDSETHWADDR:				ret = bond_sethwaddr(master_dev, slave_dev);			break;		case BOND_CHANGE_ACTIVE_OLD:		case SIOCBONDCHANGEACTIVE:			if (mode == BOND_MODE_ACTIVEBACKUP) {				ret = bond_change_active(master_dev, slave_dev);			}			else {				ret = -EINVAL;			}			break;		default:			ret = -EOPNOTSUPP;		}		dev_put(slave_dev);	}	return ret;}#ifdef CONFIG_NET_FASTROUTEstatic int bond_accept_fastpath(struct net_device *dev, struct dst_entry *dst){	return -1;}#endifstatic int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev){	slave_t *slave, *start_at;	struct bonding *bond = (struct bonding *) dev->priv;	unsigned long flags;

⌨️ 快捷键说明

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