Chinaunix首页 | 论坛 | 博客
  • 博客访问: 637150
  • 博文数量: 51
  • 博客积分: 773
  • 博客等级: 军士长
  • 技术积分: 2392
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-07 21:32
文章分类
文章存档

2018年(1)

2013年(16)

2012年(34)

分类: LINUX

2013-05-22 20:49:26

         网络设备在系统中注册、注销和关闭、打开等事件都可以通知给相应的内核组件或用户空间应用程序,其中内核组件通过netdev_chain通知链获取消息,而用户空间应用程序则通过注册Netlink RTMGRP_LINK多播群组获取事件消息。

         内核组件关联的netdev_chain通知链

         前面已经介绍过通知链的使用方法,主要是需要了解网络设备事件消息的内核组件通过register_netdevice_notifier和unregister_netdevice_notifier分别对netdev_chain通知链进行注册和注销。在网络设备相应的事件发生时,会调用这个通知链通知这些内核组件,主要的网络设备事件包括:

#define NETDEV_UP    0x0001    /* 网络设备开启,由dev_open函数产生*/
#define NETDEV_DOWN    0x0002 /*网络设备已经关闭,由dev_close函数产生*/
#define NETDEV_REBOOT    0x0003    /* Tell a protocol stack a network interface
                   detected a hardware crash and restarted
                   - we can use this eg to kick tcp sessions
                   once done */
#define NETDEV_CHANGE    0x0004    /* Notify device state change */
#define NETDEV_REGISTER 0x0005 /*设备已注册,由register_netdevice产生*/
#define NETDEV_UNREGISTER    0x0006 /*设备已注销,由unregister_netdevice产生*/
#define NETDEV_CHANGEMTU    0x0007
#define NETDEV_CHANGEADDR    0x0008
#define NETDEV_GOING_DOWN    0x0009
#define NETDEV_CHANGENAME    0x000A
#define NETDEV_FEAT_CHANGE    0x000B
#define NETDEV_BONDING_FAILOVER 0x000C
#define NETDEV_PRE_UP        0x000D
#define NETDEV_PRE_TYPE_CHANGE    0x000E
#define NETDEV_POST_TYPE_CHANGE    0x000F
#define NETDEV_POST_INIT    0x0010
#define NETDEV_UNREGISTER_BATCH 0x0011
#define NETDEV_BONDING_DESLAVE  0x0012
#define NETDEV_NOTIFY_PEERS    0x0013

用户空间应用程序

当网络设备的状态或配置中有改变时,就会调用rtmsg_ifinfo将事件系统传递给Link多播群组RTNLGRP_LINK,通知的信息包括:

  1. netdev_chain通知链接收的事件信息;
  2. 设备状态改变时,如打开关闭的设备,或打开的设备关闭,在netdev_state_change函数中;
  3. net_device->flags中的标记有改变时,如用户配置命令修改标记,在dev_change_flags函数中;

用户空间的netplugd守护进程(net-utils套件)会监测到这些事件,从而根据用户配置文件进行反应。

void netdev_state_change(struct net_device *dev)
{
    if (dev->flags & IFF_UP) {
        call_netdevice_notifiers(NETDEV_CHANGE, dev);
        rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
    }
}

 

int dev_change_flags(struct net_device *dev, unsigned flags)
{
    int ret, changes;
    int old_flags = dev->flags;

    ret = __dev_change_flags(dev, flags);
    if (ret < 0)
        return ret;

    changes = old_flags ^ dev->flags;
    if (changes)
        rtmsg_ifinfo(RTM_NEWLINK, dev, changes);

    __dev_notify_flags(dev, old_flags);
    return ret;
}
EXPORT_SYMBOL(dev_change_flags);

阅读(13524) | 评论(3) | 转发(5) |
给主人留下些什么吧!~~