99
技術社區[雲棲]
網絡子係統64_設備ip地址配置
// 相同子網: // 掩碼相同,網絡地址相同 // 為設備配置ip地址 // 函數主要任務: // 1.合理性檢查; // 1.1 相同子網內該地址沒有被添加過 // 1.2 相同子網內的地址scope應該相同 // 2.將ifa插入到in_device->ifa_list中 // 3.通知netlink,inetaddr_chain 新地址的加入 // 注:地址在in_device->ifa_list中的排列: // 1.主地址:插入的如果為主地址,則按照scope從大到小的順序排列 // 2.輔地址: 總是插入到列表的最尾端 // 調用路徑:inet_rtm_newaddr->inet_insert_ifa 1.1 static int inet_insert_ifa(struct in_ifaddr *ifa) { struct in_device *in_dev = ifa->ifa_dev; struct in_ifaddr *ifa1, **ifap, **last_primary; //輔地址標誌 ifa->ifa_flags &= ~IFA_F_SECONDARY; //主地址列表 last_primary = &in_dev->ifa_list; //遍曆主地址列表 for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL; ifap = &ifa1->ifa_next) { if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&//主地址 ifa->ifa_scope <= ifa1->ifa_scope)//ifa的scope小於等於主地址的scope last_primary = &ifa1->ifa_next; //相同子網: // 子網掩碼長度相同的情況,網絡地址相同 if (ifa1->ifa_mask == ifa->ifa_mask && inet_ifa_match(ifa1->ifa_address, ifa)) {//網絡地址有重疊 if (ifa1->ifa_local == ifa->ifa_local) {//本地地址相同 inet_free_ifa(ifa);//重複添加 return -EEXIST; } if (ifa1->ifa_scope != ifa->ifa_scope) { inet_free_ifa(ifa); return -EINVAL; } //子網掩碼長度相同,網絡地址有重疊,設置為輔地址 ifa->ifa_flags |= IFA_F_SECONDARY; } } //加入新子網 // 子網掩碼或網絡地址沒有重疊 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) { net_srandom(ifa->ifa_local); ifap = last_primary; } //上一個scope大於本ip地址的主地址 ifa->ifa_next = *ifap; *ifap = ifa; //向netlink發送消息,新添加了ip地址 rtmsg_ifa(RTM_NEWADDR, ifa); //通知inetaddr_chain,ip地址加入到設備 notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); return 0; } // 刪除設備的ip地址 // 函數主要任務: // 1.如果為主地址,則刪除同一子網內的所有輔地址 // 2.刪除該地址 // 3.通知netlink,inetaddr_chain // 調用路徑:inet_rtm_deladdr->inet_del_ifa 1.2 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy) { struct in_ifaddr *ifa1 = *ifap; //1.刪除主地址,同一子網內所有輔助地址都被刪除 if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { struct in_ifaddr *ifa; struct in_ifaddr **ifap1 = &ifa1->ifa_next; while ((ifa = *ifap1) != NULL) { if (!(ifa->ifa_flags & IFA_F_SECONDARY) || ifa1->ifa_mask != ifa->ifa_mask || !inet_ifa_match(ifa1->ifa_address, ifa)) { ifap1 = &ifa->ifa_next; continue; } //同一子網內的輔助地址 *ifap1 = ifa->ifa_next; //通知netlink,inetaddr_chain rtmsg_ifa(RTM_DELADDR, ifa); notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); //釋放ifa inet_free_ifa(ifa); } } //將地址從地址列表刪除 *ifap = ifa1->ifa_next; //通知netlink,inetaddr_chain,地址刪除 rtmsg_ifa(RTM_DELADDR, ifa1); notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); //釋放ifa if (destroy) { inet_free_ifa(ifa1); //如果沒有配置的地址信息,釋放配置信息控製塊 if (!in_dev->ifa_list) inetdev_destroy(in_dev); } }
最後更新:2017-04-03 14:53:48