????????????????????????????????£?
????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????????????.next???????趨??
???????????????o???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;
}