Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/nd6_rtr.c
Show First 20 Lines • Show All 1,888 Lines • ▼ Show 20 Lines | restart: | ||||
IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); | IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); | ||||
ND6_RUNLOCK(); | ND6_RUNLOCK(); | ||||
ND6_ONLINK_UNLOCK(); | ND6_ONLINK_UNLOCK(); | ||||
} | } | ||||
static int | static int | ||||
nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa) | nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa) | ||||
{ | { | ||||
static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; | struct sockaddr_dl sdl; | ||||
struct rib_head *rnh; | |||||
struct rtentry *rt; | struct rtentry *rt; | ||||
struct sockaddr_in6 mask6; | struct sockaddr_in6 mask6; | ||||
u_long rtflags; | u_long rtflags; | ||||
int error, a_failure, fibnum, maxfib; | int error, a_failure, fibnum, maxfib; | ||||
/* | /* | ||||
* in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. | * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. | ||||
* ifa->ifa_rtrequest = nd6_rtrequest; | * ifa->ifa_rtrequest = nd6_rtrequest; | ||||
*/ | */ | ||||
bzero(&mask6, sizeof(mask6)); | bzero(&mask6, sizeof(mask6)); | ||||
mask6.sin6_len = sizeof(mask6); | mask6.sin6_len = sizeof(mask6); | ||||
mask6.sin6_addr = pr->ndpr_mask; | mask6.sin6_addr = pr->ndpr_mask; | ||||
rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP; | rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP; | ||||
bzero(&sdl, sizeof(struct sockaddr_dl)); | |||||
sdl.sdl_len = sizeof(struct sockaddr_dl); | |||||
sdl.sdl_family = AF_LINK; | |||||
sdl.sdl_type = ifa->ifa_ifp->if_type; | |||||
sdl.sdl_index = ifa->ifa_ifp->if_index; | |||||
if(V_rt_add_addr_allfibs) { | if(V_rt_add_addr_allfibs) { | ||||
fibnum = 0; | fibnum = 0; | ||||
maxfib = rt_numfibs; | maxfib = rt_numfibs; | ||||
} else { | } else { | ||||
fibnum = ifa->ifa_ifp->if_fib; | fibnum = ifa->ifa_ifp->if_fib; | ||||
maxfib = fibnum + 1; | maxfib = fibnum + 1; | ||||
} | } | ||||
a_failure = 0; | a_failure = 0; | ||||
for (; fibnum < maxfib; fibnum++) { | for (; fibnum < maxfib; fibnum++) { | ||||
rt = NULL; | rt = NULL; | ||||
error = in6_rtrequest(RTM_ADD, | error = in6_rtrequest(RTM_ADD, | ||||
(struct sockaddr *)&pr->ndpr_prefix, ifa->ifa_addr, | (struct sockaddr *)&pr->ndpr_prefix, (struct sockaddr *)&sdl, | ||||
(struct sockaddr *)&mask6, rtflags, &rt, fibnum); | (struct sockaddr *)&mask6, rtflags, &rt, fibnum); | ||||
if (error == 0) { | if (error == 0) { | ||||
KASSERT(rt != NULL, ("%s: in6_rtrequest return no " | KASSERT(rt != NULL, ("%s: in6_rtrequest return no " | ||||
"error(%d) but rt is NULL, pr=%p, ifa=%p", __func__, | "error(%d) but rt is NULL, pr=%p, ifa=%p", __func__, | ||||
error, pr, ifa)); | error, pr, ifa)); | ||||
rnh = rt_tables_get_rnh(rt->rt_fibnum, AF_INET6); | |||||
/* XXX what if rhn == NULL? */ | |||||
RIB_WLOCK(rnh); | |||||
RT_LOCK(rt); | RT_LOCK(rt); | ||||
if (rt_setgate(rt, rt_key(rt), | |||||
(struct sockaddr *)&null_sdl) == 0) { | |||||
struct sockaddr_dl *dl; | |||||
dl = (struct sockaddr_dl *)rt->rt_gateway; | |||||
dl->sdl_type = rt->rt_ifp->if_type; | |||||
dl->sdl_index = rt->rt_ifp->if_index; | |||||
} | |||||
RIB_WUNLOCK(rnh); | |||||
nd6_rtmsg(RTM_ADD, rt); | nd6_rtmsg(RTM_ADD, rt); | ||||
RT_UNLOCK(rt); | RT_UNLOCK(rt); | ||||
pr->ndpr_stateflags |= NDPRF_ONLINK; | pr->ndpr_stateflags |= NDPRF_ONLINK; | ||||
} else { | } else { | ||||
char ip6buf[INET6_ADDRSTRLEN]; | char ip6buf[INET6_ADDRSTRLEN]; | ||||
char ip6bufg[INET6_ADDRSTRLEN]; | char ip6bufg[INET6_ADDRSTRLEN]; | ||||
char ip6bufm[INET6_ADDRSTRLEN]; | char ip6bufm[INET6_ADDRSTRLEN]; | ||||
struct sockaddr_in6 *sin6; | struct sockaddr_in6 *sin6; | ||||
▲ Show 20 Lines • Show All 578 Lines • Show Last 20 Lines |