502
技術社區[雲棲]
網絡子係統62_路由子係統處理設備事件
// 監聽設備事件
// 在ip_rt_init->devinet_init中注冊
1.1 static struct notifier_block ip_netdev_notifier = {
.notifier_call =inetdev_event,
};
// 路由子係統對網絡設備事件的處理
// 與事件相關的設備需要有inet配置信息
// 函數主要任務:
// 1.開啟設備,加入多播組,為回環設備配置ip地址
// 2.關閉設備,設備退出多播組
// 3.設備注銷,刪除該設備的配置信息
// 4.設備更名,更新設備的配置信息
// 注:路由子係統不處理設備注冊事件,因為設備注冊時,還沒有inet配置信息。
1.2 static int inetdev_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
struct in_device *in_dev = __in_dev_get(dev);
//隻處理有inet配置信息的網絡設備
if (!in_dev)
goto out;
switch (event) {
//設備注冊,說明有bug,因為設備注冊時,不會有inet配置信息,已經返回
case NETDEV_REGISTER:
dev->ip_ptr = NULL;
break;
//設備開啟
case NETDEV_UP:
//ip要求mtu至少68
if (dev->mtu < 68)
break;
//由路由子係統處理回環設備的inet配置信息
if (dev == &loopback_dev) {
struct in_ifaddr *ifa;
//分配ip地址描述符
if ((ifa = inet_alloc_ifa()) != NULL) {
//初始化ip地址,掩碼
ifa->ifa_local =
ifa->ifa_address = htonl(INADDR_LOOPBACK);
ifa->ifa_prefixlen = 8;
ifa->ifa_mask = inet_make_mask(8);
in_dev_hold(in_dev);
ifa->ifa_dev = in_dev;
//ip地址的scope為host,表示此ip隻在本機內部有效
ifa->ifa_scope = RT_SCOPE_HOST;
memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
//將ifa插入到in_dev->ifa_list
inet_insert_ifa(ifa);
}
in_dev->cnf.no_xfrm = 1;
in_dev->cnf.no_policy = 1;
}
//加入多播組
ip_mc_up(in_dev);
break;
case NETDEV_DOWN:
//離開多播組
ip_mc_down(in_dev);
break;
case NETDEV_CHANGEMTU:
if (dev->mtu >= 68)
break;
case NETDEV_UNREGISTER:
inetdev_destroy(in_dev);
break;
case NETDEV_CHANGENAME:
inetdev_changename(dev, in_dev);
break;
}
out:
return NOTIFY_DONE;
}
// 刪除設備的配置信息
// 函數主要任務:
// 1.刪除設備配置每個ip地址
// 2.刪除設備調整鄰居協議的參數
// 3.通過鄰居協議設備配置信息不再使用
1.3 static void inetdev_destroy(struct in_device *in_dev)
{
struct in_ifaddr *ifa;
struct net_device *dev;
//表示配置信息不再被使用
in_dev->dead = 1;
//遍曆設備配置的地址
while ((ifa = in_dev->ifa_list) != NULL) {
//配置信息中刪除該地址
inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
inet_free_ifa(ifa);
}
dev = in_dev->dev;
dev->ip_ptr = NULL;
//每個設備用於調整鄰居協議的參數,通過table->params鏈接在一起
neigh_parms_release(&arp_tbl, in_dev->arp_parms);
//通知鄰居協議與此設備相關的鄰居項失效
arp_ifdown(dev);
call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
}
最後更新:2017-04-03 14:53:45