这个函数看似复杂,其实主要作两件事:
  1) 把参数struct notifier_block *nb 注册到netdev_chain通知链上去
  2) 系统中所有已经被注册过或激活的网络设备的事件都要被新增的这个通知的回调函数重新调用一遍,这样让设备更新到一个完整的状态。
  一个例子
  在 路由子系统初始化时,系统会调用ip_fib_init() 函数,ip_fib_init() 中会注册一个回调函数到netdev_chain通知链,这样当别的子系统通知netdev_chain上有特定的事件类型发生时,路由子系统的相应回调 函数可以作一些反应。
  void __init ip_fib_init(void)
  {
  ... ...
  register_netdevice_notifier(&fib_netdev_notifier);
  ... ...
  }
  看一下fib_netdev_notifier的定义:
  static struct notifier_block fib_netdev_notifier = {
  .notifier_call =fib_netdev_event,
  };
  fib_netdev_notifier是一个struct notifier_block,其中.priority默认初始化为0,.next由注册时设定。
  再来大致看一下函数fib_netdev_event()做一些什么
static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
struct in_device *in_dev = __in_dev_get_rtnl(dev);
if (event == NETDEV_UNREGISTER) {
fib_disable_ip(dev, 2);
return NOTIFY_DONE;
}
if (!in_dev)
return NOTIFY_DONE;
switch (event) {
case NETDEV_UP:
for_ifa(in_dev) {
fib_add_ifaddr(ifa);
} endfor_ifa(in_dev);
#ifdef CONFIG_IP_ROUTE_MULTIPATH
fib_sync_up(dev);
#endif
rt_cache_flush(-1);
break;
case NETDEV_DOWN:
fib_disable_ip(dev, 0);
break;
case NETDEV_CHANGEMTU:
case NETDEV_CHANGE:
rt_cache_flush(0);
break;
}
return NOTIFY_DONE;
}