网络子系统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_ifa1.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小于等于主地址的scopelast_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_ifa1.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_chainrtmsg_ifa(RTM_DELADDR, ifa);notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);//释放ifainet_free_ifa(ifa);}}//将地址从地址列表删除*ifap = ifa1->ifa_next;//通知netlink,inetaddr_chain,地址删除rtmsg_ifa(RTM_DELADDR, ifa1);notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);//释放ifaif (destroy) {inet_free_ifa(ifa1);//如果没有配置的地址信息,释放配置信息控制块if (!in_dev->ifa_list)inetdev_destroy(in_dev);}}