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

📄 vnet.c

📁 嵌入式系统的网络仿真
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct vnet_bolt *bolt;	if(!gif){	   printk(KERN_INFO "vnet: vnet_chr_write gif is NULL!!!\n");	   return -EBADF;        }	bolt=&(gif->bolt);	return vnet_guestif_write(bolt, file, buf, count);	}/* Put packet to the user space buffer (already verified) */static __inline__ ssize_t vnet_put_user(struct vnet_struct *vnet,				       struct sk_buff *skb,				       struct iovec *iv, int len){	struct vnet_pi pi = { 0, skb->protocol };	ssize_t total = 0;	if (!(vnet->flags & VNET_NO_PI)) {		if ((len -= sizeof(pi)) < 0)			return -EINVAL;		if (len < skb->len) {			/* Packet will be striped */			pi.flags |= VNET_PKT_STRIP;		} 		memcpy_toiovec(iv, (void *) &pi, sizeof(pi));		total += sizeof(pi);	}       	len = MIN(skb->len, len);	skb_copy_datagram_iovec(skb, 0, iv, len);	total += len;	vnet->stats.tx_packets++;	vnet->stats.tx_bytes += len;	return total;}/* Read */static ssize_t vnet_chr_read(struct file * file, char * buf, 			    size_t count, loff_t *pos){	struct vnet_guestif *gif = (struct vnet_guestif *)file->private_data;	struct vnet_bolt *bolt;	if(!gif){	   printk(KERN_INFO "vnet: vnet_chr_read gif is NULL!!!\n");	   return -EBADF;        }	bolt=&(gif->bolt);	return vnet_guestif_read(bolt, file, buf, count);	}void vnet_hostif_free(struct vnet_nut *nut){ 	struct vnet_hostif *hif=(struct vnet_hostif *)nut;	DBG(KERN_INFO "vnet: vnet_hostif_free begin\n");	unregister_netdev(&hif->dev);	if(nut->procEntry) {		vnet_procfs_removeentry(hif->bolt.nut.procEntry,NULL);	}	kfree(hif);	DBG(KERN_INFO "vnet: vnet_hostif_free end\n");}static int vnet_hostif_create(struct inode *inode, struct file *file, struct ifreq *ifr){	struct vnet_guestif *guif = (struct vnet_guestif *)file->private_data;        struct vnet_bolt *bolt;   	struct vnet_nut *peer, *nut;	struct vnet_hostif *hif;	struct net_device *dev;	static unsigned id=0;	int hubnum,err;         	//chy:at first, free already alloced guestif	//not very good, will change ????!!!!        DBG(KERN_INFO "vnet: vnet_hostif_create begin\n");        if(!guif) {   		printk(KERN_DEBUG "vnet:vnet_hostif_create gif is null, bad file pointer on close\n");      		return -EBADF;   	}      	bolt=&(guif->bolt);   	peer = vnet_hub_disconnect(&bolt->nut);   	vnet_bolt_removefromlist(bolt);   	vnet_guestif_free(guif);	bolt=NULL;	peer=nut=NULL;        DBG(KERN_INFO "vnet: vnet_hostif_create: free guestif over\n");		//alloc hif and net_device		dev = __dev_get_by_name(ifr->ifr_name);	if (dev) {		/* Device exist */		hif = dev->priv;		bolt=&(hif->bolt);		/*		if (dev->init != vnet_hostif_init || hif->attached)			return -EBUSY;		*/		/* Check permissions */		/*		if (hif->owner != -1)			if (current->euid != vnet->owner && !capable(CAP_NET_ADMIN))				return -EPERM;		*/	} else {		char *name;		/* Allocate new device */		if (!(hif = kmalloc(sizeof(struct vnet_hostif), GFP_KERNEL)) )			return -ENOMEM;		memset(hif, 0, sizeof(struct vnet_hostif));		/*		skb_queue_head_init(&hif->readq);		init_waitqueue_head(&hif->read_wait);		*/		hif->bolt.nut.type=VNET_HOSTIF_NUT;		hif->bolt.id = id ++;		hif->bolt.nut.peer = NULL;		hif->bolt.nut.numbolts =1;		sprintf(hif->bolt.nut.name,"hif%d",hif->bolt.id);		hif->bolt.nut.private=hif;		hif->bolt.nut.refCount =0;		hif->bolt.nut.connected = FALSE;		hif->bolt.nut.index = 0;   		hif->bolt.nut.procEntry = NULL;   		hif->bolt.nut.free = vnet_hostif_free;   		init_waitqueue_head(&hif->bolt.nut.waitQueue);   		hif->bolt.nut.rcv = vnet_hostif_recv;   		hif->bolt.nut.cycleDetect = NULL;   		hif->bolt.nut.boltsChanged = NULL;   		hif->bolt.nut.isBridged = NULL;		/*   		hif->pollPtr = NULL;   		hif->clusterCount = 0;  		hif->pollMask = 0;		*/   		memset(hif->bolt.paddr, 0, sizeof hif->bolt.paddr);   		memset(hif->bolt.ladrf, 0, sizeof hif->bolt.ladrf);		hif->owner = -1;		hif->dev.init = vnet_hostif_init;		hif->dev.priv = hif;		bolt=&hif->bolt;		err = -EINVAL;		/* Set dev type */		if (ifr->ifr_flags & IFF_VNET) {			/* TUN device */			hif->flags |= VNET_VNET_DEV;			name = "vnet%d";		} else 			goto failed;   		if (*ifr->ifr_name)			name = ifr->ifr_name;		if ((err = dev_alloc_name(&hif->dev, name)) < 0)			goto failed;		if ((err = register_netdevice(&hif->dev)))			goto failed;			//MOD_INC_USE_COUNT;		//hif->devName = hif->dev.name;	}	DBG(KERN_INFO "vnet: vnet_hif_create hostif->name %s\n", hif->dev.name);//chy: different process opens different file for the same dev file.	file->private_data = hif;	hif->attached = 1;	strcpy(ifr->ifr_name, hif->dev.name);		//chy connect to a hut bolt   	hubnum = minor(inode->i_rdev);	hubnum = hubnum-VNET_MINOR;	DBG(KERN_INFO "vnet: vnet_hif_create hubnum is %d\n",hubnum);	   	if ((hubnum < 0) || (hubnum >= VNET_NUM_HUBS)) {      		vnet_hub_free_nut(&bolt->nut);		printk(KERN_ERR "vnet_hif_create: hubnum error\n");      		err= -ENODEV;		goto failed;   	}   	   	nut=vnet_hub_alloc_nut(hubnum);   	if (!nut) {      		vnet_hub_free_nut(&bolt->nut);		printk(KERN_ERR "vnet_hif_create: vnet_hub_alloc_nut error\n");      		err=-EBUSY;		goto failed;   	}	DBG(KERN_INFO "vnet: vnet_hif_create: call vnet_hub_alloc_nut over.\n");   	err = vnet_hub_connect(bolt, nut);   	if (err) {      		vnet_hub_free_nut(&bolt->nut);      		vnet_hub_free_nut(nut);		printk(KERN_ERR "vnet_hif_create: vnet_hub_connect error\n");      		goto failed;   	}	DBG(KERN_INFO "vnet: vnet_chr_open call vnet_hub_connect over.\n");      	vnet_bolt_addtolist(bolt);       	//chy: store bolt in file pointer private field for later use.    	file->private_data = bolt;      	DBG(KERN_INFO "vnet:vnet_hif_create: bolt inserted on hub %d successfully \n", hubnum);		/* make proc entry for this nutl */	err=vnet_procfs_makeentry(NULL,hif->bolt.nut.name, S_IFREG, &hif->bolt.nut.procEntry);	if(err)		goto failed;	else {		hif->bolt.nut.procEntry->read_proc=vnet_hostif_procread;		hif->bolt.nut.procEntry->data=hif;	}			DBG(KERN_ERR "vnet: vnet_hif_create end\n");	return 0;failed:	kfree(hif);	DBG(KERN_ERR "vnet_hif_create error end\n");	return err;}static int vnet_chr_ioctl(struct inode *inode, struct file *file, 			 unsigned int iocmd, unsigned long ioarg){  //chy: file->private_data maybe vnet_guestif or vnet_hif  struct vnet_bolt * bolt = (struct vnet_bolt *)file->private_data;  uint8 paddr[6];  int retval;  struct ifreq ifr;     DBG(KERN_INFO "vnet: vnet_chr_ioctl begin.\n");	  if (!bolt) {      printk(KERN_INFO "vnet: vnet_chr_ioctl bad file pointer\n");      return -EBADF;  }   switch (iocmd) {	case VNETSETIFF:	if(!bolt) return -EBADFD;	if(copy_from_user(&ifr,(void *)ioarg,sizeof(ifr)))		return -EFAULT;	ifr.ifr_name[IFNAMSIZ-1] = '\0';	rtnl_lock();	retval = vnet_hostif_create(inode, file, &ifr);	rtnl_unlock();	if(retval) return retval;	copy_to_user((void *)ioarg, &ifr, sizeof(ifr));		break;		case SIOCGIFADDR:      	retval = verify_area(VERIFY_WRITE, (void*)ioarg, ETH_ALEN);      	if (retval) {         	return retval;      	}      	copy_to_user((void*)ioarg, bolt->paddr, ETH_ALEN);      	break;	case SIOCSIFADDR:      	retval = verify_area(VERIFY_READ, (void*)ioarg, ETH_ALEN);      	if (retval) {         	return retval;      	}      	copy_from_user(paddr, (void*)ioarg, ETH_ALEN);       	memcpy(bolt->paddr, paddr, ETH_ALEN);      	      	break;    case SIOCGIFFLAGS:      	retval = verify_area(VERIFY_WRITE, (void*)ioarg, 4);      	if (retval) {         	return retval;      	}      	put_user(bolt->flags, (uint32*)ioarg);      	break;         case SIOCSIFFLAGS:        get_user(bolt->flags,(uint32*)ioarg);      	bolt->flags = ((bolt->flags                      & (IFF_UP|IFF_BROADCAST|IFF_DEBUG                        |IFF_PROMISC|IFF_MULTICAST|IFF_ALLMULTI))                        | IFF_RUNNING);      break;			default:		printk(KERN_INFO "vnet: vnet_chr_ioctl unknown iocmd!!!\n");		return -EINVAL;	};	return 0;}static int vnet_chr_fasync(int fd, struct file *file, int on){	struct vnet_struct *vnet = (struct vnet_struct *)file->private_data;	int ret;	if (!vnet)		return -EBADFD;	DBG(KERN_INFO "%s: vnet_chr_fasync %d\n", vnet->name, on);	if ((ret = fasync_helper(fd, file, on, &vnet->fasync)) < 0)		return ret;  	if (on) {		vnet->flags |= VNET_FASYNC;		if (!file->f_owner.pid) {			file->f_owner.pid  = current->pid;			file->f_owner.uid  = current->uid;			file->f_owner.euid = current->euid;		}	} else 		vnet->flags &= ~VNET_FASYNC;	return 0;}static int vnet_chr_open(struct inode *inode, struct file * file){	struct vnet_bolt *bolt;	struct vnet_nut  *nut;   	int hubnum;   	int retval;   	DBG(KERN_INFO "vnet: vnet_chr_open by PID %d (%s)\n",current->pid, current->comm);	DBG(KERN_INFO "vnet: vnet_chr_open file addr is %x, file->f_count.counter %d\n", (unsigned int)file, atomic_read(&file->f_count));		file->private_data = NULL;	//chy: allocate bolt	if((retval = vnet_guestif_create(&bolt))) return -retval;		DBG(KERN_INFO "vnet: vnet_chr_open call vnet_guestif_create over.\n");	//chy:connect to a hub   	hubnum = minor(inode->i_rdev);	hubnum=hubnum-VNET_MINOR;	DBG(KERN_INFO "vnet: vnet_chr_open hubnum is %d\n",hubnum);	   	if ((hubnum < 0) || (hubnum >= VNET_NUM_HUBS)) {      		vnet_hub_free_nut(&bolt->nut);      		return -ENODEV;   	}   	   	nut=vnet_hub_alloc_nut(hubnum);   	if (!nut) {      		vnet_hub_free_nut(&bolt->nut);      	return -EBUSY;   	}	DBG(KERN_INFO "vnet: vnet_chr_open call vnet_hub_alloc_nut over.\n");   	retval = vnet_hub_connect(bolt, nut);   	if (retval) {      		vnet_hub_free_nut(&bolt->nut);      		vnet_hub_free_nut(nut);      		return retval;   	}	DBG(KERN_INFO "vnet: vnet_chr_open call vnet_hub_connect over.\n");      	vnet_bolt_addtolist(bolt);       	//chy: store bolt in file pointer private field for later use.    	file->private_data = bolt;      	DBG(KERN_INFO "vnet: bolt inserted on hub %d successfully \n", hubnum);    	return 0;}static int vnet_chr_close(struct inode *inode, struct file *filp){   //struct vnet_guestif *gif = (struct vnet_guestif *)filp->private_data;   struct vnet_nut *nut = (struct vnet_nut *)filp->private_data;   struct vnet_bolt *bolt;   struct vnet_nut *peer;   struct vnet_guestif *gif;   struct vnet_hostif *hif;   DBG(KERN_INFO "vnet: vnet_chr_close begin\n");   if(!nut) {   	printk(KERN_DEBUG "vnet: gif is null, bad file pointer on close\n");      	return -EBADF;   }   if(nut->type==VNET_GUESTIF_NUT){	gif=(struct vnet_guestif *) nut;   	bolt=&(gif->bolt);   	peer = vnet_hub_disconnect(&bolt->nut);   	vnet_bolt_removefromlist(bolt);   	vnet_guestif_free(gif);   	//VNetFree(peer);   }else if(nut->type==VNET_HOSTIF_NUT){	hif=(struct vnet_hostif *) nut;	bolt=&(hif->bolt);	peer=vnet_hub_disconnect(&bolt->nut);	vnet_bolt_removefromlist(bolt);	vnet_hostif_free(nut);   }else{ 	printk("vnet: vnet_chr_close: unkown nut->type !!!!\n");	return -EFAULT;   }		   DBG(KERN_INFO "vnet: vnet_chr_close end\n");   return 0;}void vnet_gusetif_free(struct vnet_nut *this){}void vnet_guestif_recv( struct vnet_nut *nut,struct sk_buff  *skb){   struct vnet_guestif *gif= (struct vnet_guestif *)nut->private;   uint8 *dest =((struct ethhdr *)(((skb)->data)))->h_dest;   uint8 *src=gif->bolt.paddr;      DBG(KERN_INFO "vnet: vnet_guestif_recv begin\n");      if (!VNET_UP_AND_RUNNING(gif->bolt.flags)) {      gif->stats.droppedDown++;      goto drop_packet;   }      if (!vnet_packetmatch(dest,                        gif->bolt.paddr,                        gif->bolt.ladrf,                        gif->bolt.flags)) {      DBG(KERN_INFO "vnet: vnet_guestif_recv mismatch\n");      DBG(KERN_INFO "   dest %x:%x:%x:%x:%x:%x\n",dest[0],dest[1],dest[2],dest[3],dest[4],dest[5]);      DBG(KERN_INFO "   src  %x:%x:%x:%x:%x:%x\n",src[0],src[1],src[2],src[3],src[4],src[5]);      gif->stats.droppedMismatch++;      goto drop_packet;   }      if (skb_queue_len(&gif->packetQueue) >= VNET_MAX_QLEN) {      gif->stats.droppedOverflow++;      goto drop_packet;   }      gif->stats.queued++;//chy: ????/*#ifndef KERNEL_2_1   start_bh_atomic();#endif*/   skb_queue_tail(&gif->packetQueue, skb);   //chy:???   /*

⌨️ 快捷键说明

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