Changeset View
Changeset View
Standalone View
Standalone View
sys/net/route/route_ifaddrs.c
Show First 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | ifa_maintain_loopback_route(int cmd, const char *otype, struct ifaddr *ifa, | ||||
struct sockaddr *ia) | struct sockaddr *ia) | ||||
{ | { | ||||
struct rib_cmd_info rc; | struct rib_cmd_info rc; | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
int error; | int error; | ||||
struct rt_addrinfo info; | struct rt_addrinfo info; | ||||
struct sockaddr_dl null_sdl; | struct sockaddr_dl null_sdl; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
struct ifaddr *rti_ifa = NULL; | |||||
ifp = ifa->ifa_ifp; | ifp = ifa->ifa_ifp; | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
bzero(&info, sizeof(info)); | bzero(&info, sizeof(info)); | ||||
if (cmd != RTM_DELETE) | if (cmd != RTM_DELETE) | ||||
info.rti_ifp = V_loif; | info.rti_ifp = V_loif; | ||||
if (cmd == RTM_ADD) { | if (cmd == RTM_ADD) { | ||||
/* explicitly specify (loopback) ifa */ | /* explicitly specify (loopback) ifa */ | ||||
if (info.rti_ifp != NULL) { | if (info.rti_ifp != NULL) | ||||
rti_ifa = ifaof_ifpforaddr(ifa->ifa_addr, info.rti_ifp); | info.rti_ifa = ifaof_ifpforaddr(ifa->ifa_addr, info.rti_ifp); | ||||
if (rti_ifa != NULL) | |||||
ifa_ref(rti_ifa); | |||||
info.rti_ifa = rti_ifa; | |||||
} | } | ||||
} | |||||
info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC | RTF_PINNED; | info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC | RTF_PINNED; | ||||
info.rti_info[RTAX_DST] = ia; | info.rti_info[RTAX_DST] = ia; | ||||
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; | info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; | ||||
link_init_sdl(ifp, (struct sockaddr *)&null_sdl, ifp->if_type); | link_init_sdl(ifp, (struct sockaddr *)&null_sdl, ifp->if_type); | ||||
error = rib_action(ifp->if_fib, cmd, &info, &rc); | error = rib_action(ifp->if_fib, cmd, &info, &rc); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
if (rti_ifa != NULL) | |||||
ifa_free(rti_ifa); | |||||
if (error == 0 || | if (error == 0 || | ||||
(cmd == RTM_ADD && error == EEXIST) || | (cmd == RTM_ADD && error == EEXIST) || | ||||
(cmd == RTM_DELETE && (error == ENOENT || error == ESRCH))) | (cmd == RTM_DELETE && (error == ENOENT || error == ESRCH))) | ||||
return (error); | return (error); | ||||
log(LOG_DEBUG, "%s: %s failed for interface %s: %u\n", | log(LOG_DEBUG, "%s: %s failed for interface %s: %u\n", | ||||
__func__, otype, if_name(ifp), error); | __func__, otype, if_name(ifp), error); | ||||
Show All 26 Lines |