忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 977 | 回复: 1

[网络子系统] 我的虚拟接口通过netif_rx传包,上层协议似乎收不到 [复制链接]

论坛徽章:
0
发表于 2017-06-29 15:57 |显示全部楼层
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/device.h>
  4. #include <linux/string.h>
  5. #include <linux/slab.h>
  6. #include <linux/module.h>
  7. #include <linux/netdevice.h>
  8. #include <linux/kernel.h>
  9. #include <linux/etherdevice.h>

  10. struct net_device *virtualNIC;

  11. int virtualNIC_open(struct net_device *dev) {
  12. printk("virtualNIC_open called\n");
  13. return 0;
  14. }

  15. int virtualNIC_release(struct net_device *dev) {
  16. printk("virtualNIC_release called\n");
  17. netif_stop_queue(dev);
  18. return 0;
  19. }

  20. int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
  21. printk("dummy xmit function called...\n");
  22. dev_kfree_skb(skb);
  23. return 0;
  24. }


  25. int virtualNIC_init(struct net_device *dev) {
  26.   printk("virtualNIC device initialized\n");
  27.   return 0;
  28. };
  29. const struct net_device_ops my_netdev_ops = {
  30.      .ndo_init = virtualNIC_init,
  31.      .ndo_open = virtualNIC_open,
  32.      .ndo_stop = virtualNIC_release,
  33.      .ndo_start_xmit = virtualNIC_xmit,
  34. };

  35. //static void ether_setup(struct net_device *dev){
  36. //  dev->netdev_ops = &my_netdev_ops;
  37. //}


  38. int virtualNIC_init_module(void) {
  39. int result;
  40. char mac[6] = {0x12,0x34,0x56,0x78,0x90,0xab};
  41. virtualNIC = alloc_etherdev(0);
  42. if(!virtualNIC){
  43.      return -1;
  44. }
  45. virtualNIC->netdev_ops = &my_netdev_ops;

  46. memcpy(virtualNIC->dev_addr, mac, virtualNIC->addr_len);
  47. if((result = register_netdev(virtualNIC))) {
  48.   printk("virtualNIC: Error %d initalizing card ...", result);
  49.   return result;
  50. }
  51. return 0;
  52. }


  53. static ssize_t vnet_recv(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
  54. {
  55.     struct sk_buff *skb = dev_alloc_skb(_count+2);
  56.     if(!skb){
  57.         printk("Out of mem!\n");
  58.         goto out;
  59.     }
  60.     skb_reserve(skb, 2);
  61.     memcpy(skb_put(skb, _count), _buf, _count);
  62.     skb->dev = virtualNIC;
  63.     skb->protocol = eth_type_trans(skb, virtualNIC);
  64.     skb->ip_summed = CHECKSUM_UNNECESSARY;
  65.     //skb->pkt_type = PACKET_HOST;
  66.    
  67.     printk("%d %d %d\n",skb->pkt_type, ntohs(skb->protocol), netif_rx_ni(skb));
  68. out:   
  69.     return _count;
  70. }

  71. static struct class *vnet_class = NULL;
  72. static CLASS_ATTR(recv, 0220, NULL, vnet_recv);
  73. int __init vnet_init (void)
  74. {
  75.     virtualNIC_init_module();
  76.     vnet_class = class_create(THIS_MODULE, "vnet");
  77.      if (IS_ERR(vnet_class))
  78.     {   
  79.         printk("Create class vnet_class failed.\n");
  80.         return -ENOMEM;
  81.     }
  82.     class_create_file(vnet_class, &class_attr_recv);
  83.     return 0;
  84. }

  85. void __exit
  86. vnet_exit (void)
  87. {
  88.   class_remove_file(vnet_class, &class_attr_recv);
  89.   class_destroy(vnet_class);
  90.   unregister_netdev(virtualNIC);
  91.   free_netdev(virtualNIC);
  92.   vnet_class = NULL;
  93. }

  94. module_init (vnet_init);
  95. module_exit (vnet_exit);


  96. MODULE_AUTHOR("None");
  97. MODULE_LICENSE ("GPL");
复制代码


我注册了个netdev, 以及sys一个入口文件,应用层负责构建完整的以太网帧写到入口文件,然后模块把这个以太网帧传给内核。wireshark抓包看包很正常,各项参数都对,目的mac是我的虚拟接口的,ip checksum,udp checksum都对,但是应用层的udp socket收不到。netif_rx返回0.  求大佬指教哪里有问题。

论坛徽章:
0
发表于 2017-06-29 21:53 |显示全部楼层
用gdb跟踪到问题了,dest ip 不能是127.0.0.1, 否则被丢掉
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP