* If there is no other address in the system that can serve a route to the * same prefix, remove the route. Hand over the route to the new address * otherwise. */
| 999 | * otherwise. |
| 1000 | */ |
| 1001 | int |
| 1002 | in_scrubprefix(struct in_ifaddr *target, u_int flags) |
| 1003 | { |
| 1004 | struct rm_priotracker in_ifa_tracker; |
| 1005 | struct in_ifaddr *ia; |
| 1006 | struct in_addr prefix, mask, p, m; |
| 1007 | int error = 0; |
| 1008 | |
| 1009 | /* |
| 1010 | * Remove the loopback route to the interface address. |
| 1011 | */ |
| 1012 | if (ia_need_loopback_route(target) && (flags & LLE_STATIC)) { |
| 1013 | struct in_ifaddr *eia; |
| 1014 | |
| 1015 | eia = in_localip_more(target); |
| 1016 | |
| 1017 | if (eia != NULL) { |
| 1018 | error = ifa_switch_loopback_route((struct ifaddr *)eia, |
| 1019 | (struct sockaddr *)&target->ia_addr); |
| 1020 | ifa_free(&eia->ia_ifa); |
| 1021 | } else { |
| 1022 | error = ifa_del_loopback_route((struct ifaddr *)target, |
| 1023 | (struct sockaddr *)&target->ia_addr); |
| 1024 | } |
| 1025 | } |
| 1026 | |
| 1027 | ia_getrtprefix(target, &prefix, &mask); |
| 1028 | |
| 1029 | if ((target->ia_flags & IFA_ROUTE) == 0) { |
| 1030 | rt_addrmsg(RTM_DELETE, &target->ia_ifa, target->ia_ifp->if_fib); |
| 1031 | |
| 1032 | /* |
| 1033 | * Removing address from !IFF_UP interface or |
| 1034 | * prefix which exists on other interface (along with route). |
| 1035 | * No entries should exist here except target addr. |
| 1036 | * Given that, delete this entry only. |
| 1037 | */ |
| 1038 | in_scrubprefixlle(target, 0, flags); |
| 1039 | return (0); |
| 1040 | } |
| 1041 | |
| 1042 | IN_IFADDR_RLOCK(&in_ifa_tracker); |
| 1043 | CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { |
| 1044 | ia_getrtprefix(ia, &p, &m); |
| 1045 | |
| 1046 | if (prefix.s_addr != p.s_addr || |
| 1047 | mask.s_addr != m.s_addr) |
| 1048 | continue; |
| 1049 | |
| 1050 | if ((ia->ia_ifp->if_flags & IFF_UP) == 0) |
| 1051 | continue; |
| 1052 | |
| 1053 | /* |
| 1054 | * If we got a matching prefix address, move IFA_ROUTE and |
| 1055 | * the route itself to it. Make sure that routing daemons |
| 1056 | * get a heads-up. |
| 1057 | */ |
| 1058 | if ((ia->ia_flags & IFA_ROUTE) == 0) { |
no test coverage detected