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

📄 vnet.c

📁 嵌入式系统的网络仿真
💻 C
📖 第 1 页 / 共 4 页
字号:
static Bool vnet_hub_grabnuts(struct vnet_nut  *nut){   Bool retval = TRUE;   spin_lock_bh(&vnet_nutLock);         if (!nut ||        !nut->peer ||       !nut->connected ||        !nut->peer->connected) {     retval = FALSE;     goto done;   }/*     * This check is probably redundant because we set     * connected in VNetConnect which if set means     * we can grab and refCount will be larger that zero.    */   if (nut->refCount == 0 || nut->peer->refCount == 0) {     retval = FALSE;     goto done;   }   nut->refCount++;   nut->peer->refCount++;    done:  spin_unlock_bh(&vnet_nutLock);  return retval;}static int vnet_hub_getattachednuts(struct vnet_nut  *nut){   if (!nut) {      // assert failed      return 0;   }   if (!nut->peer) {      return 0;   }   return nut->peer->numbolts;}static int vnet_hub_isbridged(struct vnet_nut  *nut){  DBG(KERN_INFO "vnet: vnet_hub_isbridged do in future\n");  return -EFAULT;}static int vnet_isbridged(struct vnet_nut  *nut){   if (nut && nut->peer && nut->peer->isBridged) {      return nut->peer->isBridged(nut->peer);   }   return 0;}static  void vnet_hub_boltschanged(struct vnet_nut *nut){  DBG(KERN_INFO "vnet: vnet_hub_boltschanged do in future\n");}//chy: ??? maybe usefulstatic  void vnet_boltschanged(struct vnet_nut *nut){   if (nut && nut->boltsChanged) {      nut->boltsChanged(nut);   }}static void vnet_nut_free(struct vnet_nut *nut){  if (nut && nut->free) {      nut->free(nut);  }}static void vnet_hub_free_nut(struct vnet_nut *nut){   struct vnet_hub *hub = (struct vnet_hub*)nut->private;   DBG(KERN_INFO "vnet: vnet_hub_free_nut begin\n");   if (nut != &hub->nut[nut->index]) {      printk(KERN_DEBUG "vnet: bad free of hub nut\n");      return;   }   //chy: do it in future   /*   if (this->procEntry) {      VNetProc_RemoveEntry(this->procEntry, NULL);      this->procEntry = NULL;   }   */    nut->private = NULL;}static Bool vnet_hub_cycledetect(struct vnet_nut *nut,                int generation){ DBG(KERN_INFO "vnet: vnet_hub_cycledetect do in future\n"); return FALSE;	}//chy: ??? maybe useful/*static Bool vnet_cycledetect(struct vnet_nut *nut,                int generation)  {   if (nut && nut->cycleDetect) {      return nut->cycleDetect(nut, generation);   }   return FALSE;}*/struct vnet_nut* vnet_hub_disconnect(struct vnet_nut *nut){   struct vnet_nut *peer = NULL;   printk(KERN_INFO "vnet: vnet_hub_disconnect begin\n");   spin_lock_bh(&vnet_nutLock);   peer = nut->peer;   /*     * Tell others that we are disconnected to make sure no one grabs    * the nuts and make us wait for ever.    */   nut->connected = FALSE;   peer->connected = FALSE;   nut->refCount--;   peer->refCount--;   /*     * We need to wait for potential users of these nuts to release them    * before we can disconnect the nuts.    */   while (nut->refCount > 0) {      printk(KERN_INFO "vnet: ??? vnet_hub_disconnect nut->refCount >1!!!!\n");	      spin_unlock_bh(&vnet_nutLock);      wait_event(nut->waitQueue, (nut->refCount == 0));      spin_lock_bh(&vnet_nutLock);   }   /* just to make sure that the peer is correctly freed as well */   if (peer->refCount != 0) {      /* Both nuts should always have the same refcount. */      printk(KERN_INFO "vnet:??? vnet_hub_disconnect nut->perr->refCount >1!!!!\n");      peer = NULL;      goto done;   }   nut->peer = NULL;   peer->peer = NULL;    done:   spin_unlock_bh(&vnet_nutLock);   //chy: do in future   /*   if (peer) {      if (peer->numPorts) {	 VNetPortsChanged(nut);      }           if (nut->numPorts) {	 VNetPortsChanged(peer);      }   }   */   printk(KERN_INFO "vnet: vnet_hub_disconnect end\n");   return peer;}int vnet_hub_connect(struct vnet_bolt *bolt, struct vnet_nut *nut){   static int vnetGeneration = 0;   //Bool foundCycle;   int retval = 0;   struct vnet_nut *nut1, *nut2;      DBG(KERN_INFO "vnet: vnet_hub_connect begin, bolt is %x, nut is%x\n",(unsigned int)bolt,(unsigned int)nut);   nut1=&(bolt->nut);   nut2=nut;      spin_lock_bh(&vnet_nutLock);   vnetGeneration++;   if (nut1->refCount != 0 || nut2->refCount != 0) {      retval = -EDEADLK;      goto done;   }   //chy:not very clear ???, leave to future   /*   foundCycle = vnet_hub_cycledetect(nut1, vnetGeneration);   if (foundCycle) {      retval = -EDEADLK;      goto done;   }      foundCycle = vnet_hub_cycledetect(nut2, vnetGeneration);   if (foundCycle) {      retval = -EDEADLK;      goto done;   }   */   /* Connect the nuts */   nut1->peer = nut2;   nut2->peer = nut1;      /* Make the nuts grabbable */   nut1->connected = TRUE;   nut2->connected = TRUE;      nut1->refCount++;   nut2->refCount++;    done:   spin_unlock_bh(&vnet_nutLock);   //chy:not very clear ???, leave to future   /*   if (retval == 0) {     if (nut2->numbolts) {       vnet_hub_boltschanged(nut1);     }          if (nut1->numbolts) {       vnet_hub_boltschanged(nut2);     }   }   */   DBG(KERN_INFO "vnet: vnet_hub_connect end retval  %d\n",retval);   return retval;}void vnet_hub_recv(struct vnet_nut *srcnut, struct sk_buff *skb) {   struct vnet_hub *hub=(struct vnet_hub *)srcnut->private;   struct sk_buff *clone;   struct vnet_nut * nut;      int i;   DBG(KERN_INFO "vnet: vnet_hub_recv begin\n");      hub->stats[srcnut->index]++;      //chy: simualte a switch in the future   for (i=0; i<NUM_NUTS_PER_HUB; i++) {      nut = &hub->nut[i];      if ( nut->private         /* allocated */          && nut->peer         /* and connected */          && (nut != srcnut)) {  /* and not a loop */         clone = skb_clone(skb, GFP_ATOMIC);         if (clone) {            if (nut->peer->rcv) {                 nut->peer->rcv(nut->peer, clone);            }else{                printk("vnet: vnet_hub_recv peer->rcv is NULL!!!");            	dev_kfree_skb(clone);            }         } else{         	printk(KERN_INFO "vnet: vnet_hub_recv skb_clone failed!!!\n");         	         }               }         }   dev_kfree_skb(skb);      DBG(KERN_INFO "vnet: vnet_hub_recv end\n");}struct vnet_nut * vnet_hub_alloc_nut(int hubnum){   struct vnet_hub *hub = vnetHub[hubnum];   struct vnet_nut *nut;   int i;     DBG(KERN_INFO "vnet: vnet_hub_alloc_nut hubnum  %d begin\n", hubnum);    if (!hub) {      DBG(KERN_INFO "vnet: vnet_hub_alloc_nut hub %d does not exist, allocating memory.\n",              hubnum);            hub = (struct vnet_hub *)kmalloc(sizeof(struct vnet_hub), GFP_KERNEL);      if(!hub) { 	printk(KERN_INFO "vnet: vnet_hub_alloc_nut can not malloc hub struct\n");	return NULL;      }      DBG(KERN_INFO "vnet: vnet_hub_alloc_nut init nuts in hub\n");	      for (i=0; i<NUM_NUTS_PER_HUB; i++) {         nut = &hub->nut[i];                  /*          * The private field indicates if this nut is allocated.          * Null means free, otherwise the nut is allocated and it          * should point back to the hub.          */		 nut->type=VNET_HUB_NUT;         nut->peer = NULL;         nut->numbolts = 0;         sprintf(nut->name, "hub%d.%d", hubnum, i);	 nut->refCount = 0;	 nut->connected = FALSE;         nut->private = NULL;         nut->index = i;	 //chy: will do it in the future         //nut->procEntry = NULL;	 init_waitqueue_head(&nut->waitQueue);         nut->free = vnet_hub_free_nut;         nut->rcv = vnet_hub_recv;         nut->cycleDetect = vnet_hub_cycledetect;         nut->boltsChanged = vnet_hub_boltschanged;         nut->isBridged = vnet_hub_isbridged;	          hub->stats[i]=0;      }      hub->num = hubnum;      hub->totalbolts = 0;      hub->mygeneration = 0;            vnetHub[hubnum] = hub;   }   DBG(KERN_INFO "vnet: vnet_hub_alloc begin find a free nut\n");    for (i=0; i<NUM_NUTS_PER_HUB; i++) {      nut = &hub->nut[i];      DBG(KERN_INFO "vnet: vnet_hub_alloc i %d \n",i);	      if (!nut->private) {	 //ASSERT(nut->refCount == 0);         /*          * Make proc entry for this nut.          */         /* chy: do it in the future         retval = VNetProc_MakeEntry(NULL, nut->name, S_IFREG, &nut->procEntry);         if (retval) {            if (retval == -ENXIO) {               nut->procEntry = NULL;            } else {               return NULL;            }         } else {            nut->procEntry = NULL;         }	*/         /*          *  OK, now allocate this nut.          */         nut->numbolts = hub->totalbolts;         nut->private = hub;         nut->peer = NULL;         DBG(KERN_INFO "vnet: vnet_hub_alloc find a free nut and allocate it\n");         return nut;      }   }   printk(KERN_INFO "vnet vnet_hub_alloc can not find a free nut\n");    return NULL;}void vnet_hub_init(void){  DBG(KERN_INFO "vnet: vnet_hub_init begin\n");  int i;  for (i=0; i<VNET_NUM_HUBS; i++) {      vnetHub[i] = NULL;  }  DBG(KERN_INFO "vnet: vnet_hub_init end.\n");}void vnet_hub_free(void){  int i,j;  j=0;  DBG(KERN_INFO "vnet: vnet_hub_free begin\n");  for (i=0; i<VNET_NUM_HUBS; i++) {      if(vnetHub[i]) {      	kfree(vnetHub[i]);        DBG(KERN_INFO "vnet: vnet_hub_free kfree %d hub.\n", i);      	j++;      }  }  DBG(KERN_INFO "vnet: vnet_hub_free end, total free num %d.\n", j);}static struct file_operations vnet_fops = {	owner:	THIS_MODULE,		read:	vnet_chr_read,	write:	vnet_chr_write,	poll:	vnet_chr_poll,	ioctl:	vnet_chr_ioctl,	open:	vnet_chr_open,	release:vnet_chr_close,	fasync:	vnet_chr_fasync		};/* chy: the misc dev 's major num is 10 */static struct miscdevice vnet_miscdev={	VNET_MINOR,	"net/vnet",	&vnet_fops};int __init vnet_init(void){	printk(KERN_INFO "Universal VNET device driver %s " 	       "(C)2003 SkyEye Developer: Chen Yu\n", VNET_VER);	vnet_hub_init();    	spin_lock_init(&vnet_nutLock);	spin_lock_init(&vnet_boltLock);	if(vnet_procfs_init()){		printk(KERN_ERR "vnet: could not register proc fs\n");        return -ENOENT;	}	        DBG(KERN_INFO "vnet: register proc fs over!\n"); 		if (misc_register(&vnet_miscdev)) {		printk(KERN_ERR "vnet: Can't register misc device %d\n", VNET_MINOR);		return -EIO;	}        DBG(KERN_INFO "vnet: register miscdev over!\n");        DBG(KERN_INFO "vnet: vnet_init successfully!\n");	return 0;}void vnet_cleanup(void){        vnet_hub_free();        vnet_procfs_cleanup();	DBG(KERN_INFO "vnet: proc fs cleanup over!\n");	misc_deregister(&vnet_miscdev);  	DBG(KERN_INFO "vnet: miscdev deregister over!\n");	DBG(KERN_INFO "vnet: vnet_cleanup successfully!\n");}module_init(vnet_init);module_exit(vnet_cleanup);#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endif

⌨️ 快捷键说明

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