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