当前位置:  技术问答>linux和unix

虚拟网卡驱动实现问题--IP发包时没调用自己写的_start_xmit()函数

    来源: 互联网  发布时间:2017-01-17

    本文导语:  本帖最后由 llhktv1986 于 2011-11-18 09:08:45 编辑 我写了一个简单的虚拟设备驱动,想用来接收IP包,在代码中我只实现了dev这个结构体,并把它注册到系统上去,之后用路由命令让IP层把包发送到该设备上,看看系统是否调用了si...

本帖最后由 llhktv1986 于 2011-11-18 09:08:45 编辑
我写了一个简单的虚拟设备驱动,想用来接收IP包,在代码中我只实现了dev这个结构体,并把它注册到系统上去,之后用路由命令让IP层把包发送到该设备上,看看系统是否调用了sim_dri_start_xmit()这个接收函数.
在编译完该程序,我把该模块加载到系统上,而且在/proc/net/dev中也能查看到该设备,说明设备应该正确注册到系统了.
虚拟网卡驱动实现问题--IP发包时没调用自己写的_start_xmit()函数[图片]
接着我用
    sudo ifconfig sim_dri0 192.168.4.1 netmask 255.255.255.0 up      
配置该设备的IP并激活它,在系统消息中可以看到系统调用了sim_dri_open()这个函数.
虚拟网卡驱动实现问题--IP发包时没调用自己写的_start_xmit()函数[图片]
但当我
    ping 192.168.4.1
时,虽然可以ping得通,但系统并没调用sim_dri_start_xmit()这个接收函数.
而且,当我想指定一条路由到该设备时
    sudo route add 192.168.155.155 dev sim_dri0
它总是提示"SIOCADDRT: Network is down"
虚拟网卡驱动实现问题--IP发包时没调用自己写的_start_xmit()函数[图片]

我想请教下,我在代码里的做法是不是有问题,在做这个dev结构的时候是不是还有些东西没考虑呀,导致系统一直没调用我写的接收函数,谢谢!

环境:VMware+内核版本2.6.32.46



#include 
#include 
#include 
#include 
#include 
#include 


MODULE_LICENSE("Dual BSD/GPL");

static int sim_dri_open (struct net_device *dev);
static int sim_dri_start_xmit (struct sk_buff *skb, struct net_device *dev);
static int sim_dri_close (struct net_device *dev);

static LIST_HEAD(sim_dri_list); 

static int sim_dri_open (struct net_device *dev)
{
printk(KERN_ALERT "sim_dri_open runn");
return 1;
}

static int sim_dri_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
printk(KERN_ALERT "sim_dri_start_xmit runn");
        kfree_skb(skb);
return 1;
}

static int sim_dri_close (struct net_device *dev)
{
printk(KERN_ALERT "sim_dri_close runn");
return 1;
}

//设备私有数据
struct sim_dri_struct{ 
    struct list_head list; //设备链表 
    struct net_device *dev; //net_device 
}; 
//设备操作函数
static const struct net_device_ops sim_dri_netdev_ops = {
.ndo_open = sim_dri_open,
.ndo_stop = sim_dri_close,
.ndo_start_xmit         = sim_dri_start_xmit,
};

//设置设备
void sim_dri_setup(struct net_device *dev){ 

    struct sim_dri_struct *sim_dri = netdev_priv(dev); //获取net_device私有数据    
    ether_setup(dev); //设置设备为以太网设备,定义部分以太网络的参数 
    /* 
        以下为设置网络设备的操作函数 
    */ 
    dev->netdev_ops = &sim_dri_netdev_ops;
    random_ether_addr(dev->dev_addr); //随机源地址

    sim_dri->dev = dev; //设置私有数据的net_device成员 

    list_add(&sim_dri->list, &sim_dri_list); //将新建sim_dri_struct加入到设备链表 



//申请,设置,注册设备
struct net_device *sim_dri_setup_dev(void){ 

    struct net_device *dev; 
//分配net_device,初始化函数sim_dri_setup()
    dev = alloc_netdev(sizeof(struct sim_dri_struct), "sim_dri%d", sim_dri_setup);                        
                                                                                   

    if(dev == NULL){ 
        printk(KERN_ALERT "alloc net device failedn"); 
        return NULL; 
    } 
    if(register_netdev(dev) != 0){ //注册网络设备 
        printk(KERN_ALERT "register net device failedn"); 
        return NULL; 
    } 
    return dev; 


//卸载设备
int sim_dri_shutdown_dev(void){ 

    struct sim_dri_struct *sim_dri;
    struct sim_dri_struct *next; 

    list_for_each_entry_safe(sim_dri, next, &sim_dri_list, list){ //遍历所有sim_dri_struct 

        list_del(&sim_dri->list); //将当前sim_dri_struct从队列中删除 

        unregister_netdev(sim_dri->dev); //注销网络设备 

        free_netdev(sim_dri->dev); //释放网络设备 

    } 

    return 0; 



static int sim_driver_init(void)
{
printk(KERN_ALERT "sim_driver_init runn");

struct net_device *dev;

if((dev = sim_dri_setup_dev()) == NULL){ 

     printk(KERN_ALERT "setup net device failedn"); 

        return -1; 

        }
return 0;

}



static void sim_driver_exit(void)
{
printk(KERN_ALERT"sim_driver_exit runn");

if(sim_dri_shutdown_dev() == -1){ 

     printk(KERN_ALERT "shutdown net device failedn"); 

        }
}

module_init(sim_driver_init);

module_exit(sim_driver_exit);



|
可以参考一下别人的代码
http://lxr.linux.no/linux+v3.1.1/drivers/net/veth.c#L191



你这些sim_dri_open  函数都应该返回0,以表示没有出错,linux一般都是返回0表示没错了。

可能你返回出错了,系统就认为你这个devcie没能起来了。

另外好像都在这个函数里面都 设启动标志的


 921/*
 922 * net_device code
 923 */
 924
 925static int veth_open(struct net_device *dev)
 926{
 927        netif_start_queue(dev);
 928        return 0;
 929}
 930
 931static int veth_close(struct net_device *dev)
 932{
 933        netif_stop_queue(dev);
 934        return 0;
 935}


或者   netif_carrier_on(dev);  
  netif_carrier_off(dev);

好像我记得,系统在传递包之前有先判断一下这个标志的。

在之前的公司有虚拟网卡的代码,具体也没怎么研究过,忘的差不多了。

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3