加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核实践 - 如何添加网络协议[三]:实现

发布时间:2016-09-29 15:43:25 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核版本:2.6.34 接上篇《添加网络协议》。 为了用户方便查看brcm设备的工作状态,使用proc文件系统是很好的方 式。一个网络协议模块可以注册到网络空间中register_pernet_subsys(),这个函数会为子空间分配一个id号,通过id可以在网 络空间中找
副标题[/!--empirenews.page--]

内核版本:2.6.34

接上篇《添加网络协议》。

为了用户方便查看brcm设备的工作状态,使用proc文件系统是很好的方 式。一个网络协议模块可以注册到网络空间中register_pernet_subsys(),这个函数会为子空间分配一个id号,通过id可以在网 络空间中找到分配给该子空间的内存:init_net->gen->ptr[id - 1]。而我们正是利用这块内存去存储proc中的相关信息 :struct brcm_net,它记录了brcm设备在proc文件系统中的位置。

struct brcm_net {     
    /* /proc/net/brcm */ 
    struct proc_dir_entry *proc_brcm_dir;     
    /* /proc/net/brcm/config */ 
    struct proc_dir_entry *proc_brcm_conf;     
};

在加载brcm模块时会注册子空间,brcm_init_net创建在proc中的相关项,并记录路径在brcm_net中; brcm_exit_net删除在proc中的相关项;brcm_net_id记录分配给子空间的id,这样通过init_net->gen->ptr[brcm_net_id - 1]就可以操作brcm_net了。

err = register_pernet_subsys(&brcm_net_ops);     
static struct pernet_operations brcm_net_ops = {     
    .init = brcm_init_net,     
    .exit = brcm_exit_net,     
    .id = &brcm_net_id,     
    .size = sizeof(struct brcm_net),     
};

注意到在brcm_init_net和brcm_exit_net中添加和删除的仅仅是/proc/net/brcm目录和config文件,而在使用中 brcm设备是可以动态创建的,因此这部分代码应该发生在添加和删除brcm设备时,而不是在brcm模块注册和删除时。最简单的是 直接添加在register方法或unregister方法中,但内核提供了更好的机制:事件,将对proc的操作分离出来,因为proc的操作实 际上属于附加的操作而不是必须的操作。下面就来看event机制。

前面几篇已经有描述过event机制,这里的事件都是关于设 备的事件,使用的是register_netdevice_notifier()来,注册notifier到netdev_chain链表上。在加载brcm模块时注册 notifier,brcm_notifier_block包含了brcm设备对所关心的事件作出的反应。

err = register_netdevice_notifier

(&brcm_notifier_block);     
static struct notifier_block brcm_notifier_block __read_mostly = {     
    .notifier_call = brcm_device_event,     
};

设备对哪些事件会感兴趣,首先,brcm设备对注册和注销是感兴趣的,要操作proc文件系统;其次,对于发往brcm 下层设备的事件,要考虑这些事件造成的连带影响(比如eth1被down掉,则其上的brcm设备也应该被down掉),一般是下层设备的 事件对其上的所有brcm设备都进行相应操作。

所以在brcm_device_event有两类进入的设备dev会进行操作,一类是brcm设备 ,它仅仅是操作proc文件系统。判断是否为brcm设备,是的话则由__brcm_device_event() 处理。

if (is_brcm_dev(dev))     
    __brcm_device_event(dev, event);     
         
static void __brcm_device_event(struct net_device *dev, unsigned long event)     
{     
    switch (event) {     
    case NETDEV_CHANGENAME:     
        brcm_proc_rem_dev(dev);     
        if (brcm_proc_add_dev(dev) < 0)     
            pr_warning("BRCM: failed to change proc name for %sn",     
                    dev->name);     
        break;     
    case NETDEV_REGISTER:
        if (brcm_proc_add_dev(dev) < 0)     
            pr_warning("BRCM: failed to add proc entry for %sn",     
                    dev->name);     
        break;     
    case NETDEV_UNREGISTER:     
        brcm_proc_rem_dev(dev);     
        break;     
    }     
}

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读