網絡子係統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