📄 vnet.c
字号:
if (gif->pollPtr) { *gif->pollPtr |= gif->pollMask; if (skb_queue_len(&gif->packetQueue) >= gif->clusterCount) { Atomic_Or(gif->actPtr, gif->actMask); } } */ //chy: ???? /*#ifndef KERNEL_2_1 end_bh_atomic();#endif*/ wake_up(&gif->waitQueue); return; drop_packet: dev_kfree_skb(skb); }//int vnet_guestif_read(struct vnet_guestif *gif,struct file *filp, char *buf, size_t count)int vnet_guestif_read(struct vnet_bolt *bolt,struct file *filp, char *buf, size_t count){ struct vnet_guestif *gif=(struct vnet_guestif *)bolt->nut.private; struct sk_buff *skb; int ret; DECLARE_WAITQUEUE(wait, current); //struct wait_queue wait = {current, NULL, } DBG(KERN_INFO "vnet: vnet_guestif_read begin\n"); add_wait_queue(&gif->waitQueue, &wait); for (;;) { current->state = TASK_INTERRUPTIBLE; mb(); skb = skb_peek(&gif->packetQueue); if (skb && (skb->len > count)) { skb = NULL; ret = -EMSGSIZE; break; } ret = -EAGAIN; skb = skb_dequeue(&gif->packetQueue); //chy:???? /* if (gif->pollPtr && skb_queue_empty(&gif->packetQueue)) { *gif->pollPtr &= ~gif->pollMask; } */ if (skb != NULL || filp->f_flags & O_NONBLOCK) { break; } ret = -EINTR; if (signal_pending(current)) { break; } schedule(); } current->state = TASK_RUNNING; remove_wait_queue(&gif->waitQueue, &wait); if (! skb) { return ret; } gif->stats.read++; count = (count < skb->len) ? count : skb->len; copy_to_user(buf, skb->data, count); dev_kfree_skb(skb); DBG(KERN_INFO "vnet: vnet_guestif_read end\n"); return count;}//int vnet_guestif_write(struct vnet_guestif *gif,struct file *filp, const char *buf, size_t count)int vnet_guestif_write(struct vnet_bolt *bolt,struct file *filp, const char *buf, size_t count){ struct vnet_guestif *gif=(struct vnet_guestif *)bolt->nut.private; struct sk_buff *skb; //struct vnet_hub *hub; struct vnet_nut *peer; DBG(KERN_INFO "vnet: vnet_guestif_write begin\n"); /* * Check size */ if (count < sizeof (struct ethhdr)) { return -EINVAL; } /* * Allocate an sk_buff. */ skb = dev_alloc_skb(count + 7); if (skb == NULL) { // XXX obey O_NONBLOCK? return -ENOBUFS; } //chy: ????? /*#ifndef KERNEL_2_1 skb->free = 1;#endif */ skb_reserve(skb, 2); /* * Copy the data and send it. */ gif->stats.written++; if (copy_from_user(skb_put(skb, count), buf, count)) { return -EFAULT; } peer=gif->bolt.nut.peer; if(!peer||!peer->rcv){ printk("vnet: vnet_guestif_write gif->bolt.nut.peer or peer->rcv is NULL!!!\n"); return -EFAULT; } /* hub=(struct hub *)peer->private; if(!hub){ printk("vnet: vnet_guestif_write peer->private is NULL!!!\n"); return -EFAULT; } */ peer->rcv(peer, skb); DBG(KERN_INFO "vnet: vnet_guestif_write end\n"); return count;}void vnet_nut_recv(struct vnet_nut *nut, struct sk_buff *skb){ if (nut && nut->rcv &&nut->peer) { nut->rcv(nut->peer, skb); } else { dev_kfree_skb(skb); }}//int vnet_guestif_ioctl(struct vnet_guestif *gif,int vnet_guestif_ioctl(struct vnet_bolt *bolt, struct file *filp, unsigned int iocmd, unsigned long ioarg){ printk(KERN_INFO "vnet_guestif_ioctl isn't realized yet!!!\n"); return -EFAULT; }//int vnet_guestif_poll(struct vnet_guestif *gif,int vnet_guestif_poll(struct vnet_bolt *bolt, struct file *filp, poll_table *wait){ struct vnet_guestif *gif=(struct vnet_guestif *)bolt->nut.private; poll_wait(filp, &gif->waitQueue, wait); if (!skb_queue_empty(&gif->packetQueue)) { return POLLIN; } return 0;}int vnet_guestif_procread(char *page, // IN/OUT: buffer to write into char **start, // OUT: 0 if file < 4k, else offset into page off_t off, // IN: offset of read into the file int count, // IN: maximum number of bytes to read int *eof, // OUT: TRUE if there is nothing more to read void *data) // IN: client data - not used{ struct vnet_guestif *gif = (struct vnet_guestif *)data; int len = 0; //chy: ??? /* if (!gif|| !VNetGrabJacks(&gif->bolt.nut)) { return len; } */ if(!gif){ printk("vnet: vnet_guestif_procread gif is NULL!!!\n"); return 0; } len += vnet_bolt_print(&gif->bolt, page+len); //chy: ??? //VNetReleaseJacks(&gif->bolt.nut); len += sprintf(page+len, "read %u written %u queued %u ", gif->stats.read, gif->stats.written, gif->stats.queued); len += sprintf(page+len, "dropped.down %u dropped.mismatch %u dropped.overflow %u ", gif->stats.droppedDown, gif->stats.droppedMismatch, gif->stats.droppedOverflow); len += sprintf(page+len, "\n"); *start = 0; *eof = 1; return len;}int vnet_guestif_create(struct vnet_bolt **ret){ struct vnet_guestif *gif = NULL; static unsigned id = 0; int retval; DBG(KERN_INFO "vnet: vnet_guestif_create begin\n"); gif = (struct vnet_guestif *)kmalloc(sizeof(struct vnet_guestif), GFP_KERNEL); if (!gif) { return -ENOMEM; } /* * Initialize fields. */ gif->bolt.nut.type=VNET_GUESTIF_NUT; gif->bolt.id = id++; gif->bolt.nut.peer = NULL; gif->bolt.nut.numbolts = 1; sprintf(gif->bolt.nut.name, "gif%d", gif->bolt.id); gif->bolt.nut.private = gif; gif->bolt.nut.refCount = 0; gif->bolt.nut.connected = FALSE; gif->bolt.nut.index = 0; gif->bolt.nut.procEntry = NULL; gif->bolt.nut.free = vnet_gusetif_free; init_waitqueue_head(&gif->bolt.nut.waitQueue); gif->bolt.nut.rcv = vnet_guestif_recv; gif->bolt.nut.cycleDetect = NULL; gif->bolt.nut.boltsChanged = NULL; gif->bolt.nut.isBridged = NULL; gif->pollPtr = NULL; gif->clusterCount = 0; gif->pollMask = 0; /* * Make proc entry for this nut. */ retval = vnet_procfs_makeentry(NULL, gif->bolt.nut.name, S_IFREG, &gif->bolt.nut.procEntry); if (retval) { kfree(gif); return retval; } else { gif->bolt.nut.procEntry->read_proc = vnet_guestif_procread; gif->bolt.nut.procEntry->data = gif; } /* * Rest of fields. */ gif->bolt.flags = IFF_RUNNING; //chy: the padr is not allocated now memset(gif->bolt.paddr, 0, sizeof gif->bolt.paddr); memset(gif->bolt.ladrf, 0, sizeof gif->bolt.ladrf); gif->bolt.fileOpRead = vnet_guestif_read; gif->bolt.fileOpWrite = vnet_guestif_write; gif->bolt.fileOpIoctl = vnet_guestif_ioctl; gif->bolt.fileOpSelect = vnet_guestif_poll; skb_queue_head_init(&(gif->packetQueue)); init_waitqueue_head(&gif->waitQueue); memset(&gif->stats, 0, sizeof(struct vnet_guestif_stats)); *ret = (struct vnet_bolt*)gif; DBG(KERN_INFO "vnet: vnet_guestif_create end\n"); return 0;}/* *---------------------------------------------------------------------- * * VNetgifFree -- * * Free the user interface port. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */void vnet_guestif_free(struct vnet_guestif *gif){ struct sk_buff *skb; DBG(KERN_INFO "vnet: vnet_guestif_free begin\n"); for (;;) { skb = skb_dequeue(&gif->packetQueue); if (skb == NULL) { break; } dev_kfree_skb(skb); }//chy: do it in future/* if (gif->pollPtr) { VNetgifUnmapPollPtr(gif); gif->clusterCount = 0; }*/ if (gif->bolt.nut.procEntry) { vnet_procfs_removeentry(gif->bolt.nut.procEntry, NULL); } kfree(gif); DBG(KERN_INFO "vnet: vnet_guestif_free end\n");}static void vnet_nut_release(struct vnet_nut *nut){ spin_lock_bh(&vnet_nutLock); nut->refCount--; nut->peer->refCount--; if (nut->refCount == 0) { wake_up(&nut->waitQueue); } if (nut->peer->refCount == 0) { wake_up(&nut->peer->waitQueue); } spin_unlock_bh(&vnet_nutLock);}static void vnet_bolt_addtolist(struct vnet_bolt *bolt){ spin_lock(&vnet_boltLock); bolt->next = vnet_bolthead; vnet_bolthead = bolt; spin_unlock(&vnet_boltLock);}static void vnet_bolt_removefromlist(struct vnet_bolt *bolt){ struct vnet_bolt **p; spin_lock(&vnet_boltLock); for (p = &vnet_bolthead; *p; p = &(*p)->next) { if (*p == bolt) { *p = bolt->next; break; } } spin_unlock(&vnet_boltLock);}static inline void vnet_bolt_free(struct vnet_bolt *this){ DBG(KERN_INFO "vnet: vnet_bolt_free begin, no use\n"); /* if(!this){ kfree(this); } */}int vnet_nut_print(struct vnet_nut *nut, char * buf){ int len = 0; if (!nut->peer) { len += sprintf(buf+len, "connected not "); } else { len += sprintf(buf+len, "connected %s ", nut->peer->name); } return len;}static int vnet_bolt_print(struct vnet_bolt *bolt, char * buf){ int len = 0; len += vnet_nut_print(&bolt->nut, buf+len); //chy:maybe do in future //len += VNetPrintPIDs(bolt, buf+len); len += sprintf(buf+len, "mac %02x:%02x:%02x:%02x:%02x:%02x ", bolt->paddr[0], bolt->paddr[1], bolt->paddr[2], bolt->paddr[3], bolt->paddr[4], bolt->paddr[5]); len += sprintf(buf+len, "ladrf %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", bolt->ladrf[0], bolt->ladrf[1], bolt->ladrf[2], bolt->ladrf[3], bolt->ladrf[4], bolt->ladrf[5], bolt->ladrf[6], bolt->ladrf[7]); len += sprintf(buf+len, "flags IFF_RUNNING"); if (bolt->flags & IFF_UP) { len += sprintf(buf+len, ",IFF_UP"); } if (bolt->flags & IFF_BROADCAST) { len += sprintf(buf+len, ",IFF_BROADCAST"); } if (bolt->flags & IFF_DEBUG) { len += sprintf(buf+len, ",IFF_DEBUG"); } if (bolt->flags & IFF_PROMISC) { len += sprintf(buf+len, ",IFF_PROMISC"); } if (bolt->flags & IFF_MULTICAST) { len += sprintf(buf+len, ",IFF_MULTICAST"); } if (bolt->flags & IFF_ALLMULTI) { len += sprintf(buf+len, ",IFF_ALLMULTI"); } len += sprintf(buf+len, " "); return len;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -