Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/nd6_rtr.c
Show First 20 Lines • Show All 668 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* Default router list processing sub routines. */ | /* Default router list processing sub routines. */ | ||||
static void | static void | ||||
defrouter_addreq(struct nd_defrouter *new) | defrouter_addreq(struct nd_defrouter *new) | ||||
{ | { | ||||
struct sockaddr_in6 def, mask, gate; | struct sockaddr_in6 def, mask, gate; | ||||
struct rtentry *newrt = NULL; | struct rt_addrinfo info; | ||||
donner: dito | |||||
struct rib_cmd_info rc; | |||||
unsigned int fibnum; | unsigned int fibnum; | ||||
int error; | int error; | ||||
bzero(&def, sizeof(def)); | bzero(&def, sizeof(def)); | ||||
bzero(&mask, sizeof(mask)); | bzero(&mask, sizeof(mask)); | ||||
bzero(&gate, sizeof(gate)); | bzero(&gate, sizeof(gate)); | ||||
def.sin6_len = mask.sin6_len = gate.sin6_len = | def.sin6_len = mask.sin6_len = gate.sin6_len = | ||||
sizeof(struct sockaddr_in6); | sizeof(struct sockaddr_in6); | ||||
def.sin6_family = gate.sin6_family = AF_INET6; | def.sin6_family = gate.sin6_family = AF_INET6; | ||||
gate.sin6_addr = new->rtaddr; | gate.sin6_addr = new->rtaddr; | ||||
fibnum = new->ifp->if_fib; | fibnum = new->ifp->if_fib; | ||||
error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def, | bzero((caddr_t)&info, sizeof(info)); | ||||
(struct sockaddr *)&gate, (struct sockaddr *)&mask, | info.rti_flags = RTF_GATEWAY; | ||||
RTF_GATEWAY, &newrt, fibnum); | info.rti_info[RTAX_DST] = (struct sockaddr *)&def; | ||||
if (newrt != NULL) | info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gate; | ||||
rt_routemsg(RTM_ADD, newrt, new->ifp, 0, fibnum); | info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask; | ||||
NET_EPOCH_ASSERT(); | |||||
error = rib_action(fibnum, RTM_ADD, &info, &rc); | |||||
if (rc.rc_rt != NULL) | |||||
rt_routemsg(RTM_ADD, rc.rc_rt, new->ifp, 0, fibnum); | |||||
if (error == 0) | if (error == 0) | ||||
new->installed = 1; | new->installed = 1; | ||||
} | } | ||||
/* | /* | ||||
* Remove the default route for a given router. | * Remove the default route for a given router. | ||||
* This is just a subroutine function for defrouter_select_fib(), and | * This is just a subroutine function for defrouter_select_fib(), and | ||||
* should not be called from anywhere else. | * should not be called from anywhere else. | ||||
*/ | */ | ||||
static void | static void | ||||
defrouter_delreq(struct nd_defrouter *dr) | defrouter_delreq(struct nd_defrouter *dr) | ||||
{ | { | ||||
struct sockaddr_in6 def, mask, gate; | struct sockaddr_in6 def, mask, gate; | ||||
struct rtentry *oldrt = NULL; | struct rt_addrinfo info; | ||||
struct rib_cmd_info rc; | |||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
unsigned int fibnum; | unsigned int fibnum; | ||||
bzero(&def, sizeof(def)); | bzero(&def, sizeof(def)); | ||||
bzero(&mask, sizeof(mask)); | bzero(&mask, sizeof(mask)); | ||||
bzero(&gate, sizeof(gate)); | bzero(&gate, sizeof(gate)); | ||||
def.sin6_len = mask.sin6_len = gate.sin6_len = | def.sin6_len = mask.sin6_len = gate.sin6_len = | ||||
sizeof(struct sockaddr_in6); | sizeof(struct sockaddr_in6); | ||||
def.sin6_family = gate.sin6_family = AF_INET6; | def.sin6_family = gate.sin6_family = AF_INET6; | ||||
gate.sin6_addr = dr->rtaddr; | gate.sin6_addr = dr->rtaddr; | ||||
fibnum = dr->ifp->if_fib; | fibnum = dr->ifp->if_fib; | ||||
bzero((caddr_t)&info, sizeof(info)); | |||||
info.rti_flags = RTF_GATEWAY; | |||||
info.rti_info[RTAX_DST] = (struct sockaddr *)&def; | |||||
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gate; | |||||
info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask; | |||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
in6_rtrequest(RTM_DELETE, (struct sockaddr *)&def, | rib_action(fibnum, RTM_DELETE, &info, &rc); | ||||
(struct sockaddr *)&gate, | if (rc.rc_rt != NULL) | ||||
(struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, fibnum); | rt_routemsg(RTM_DELETE, rc.rc_rt, dr->ifp, 0, fibnum); | ||||
if (oldrt != NULL) | |||||
rt_routemsg(RTM_DELETE, oldrt, dr->ifp, 0, fibnum); | |||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
dr->installed = 0; | dr->installed = 0; | ||||
} | } | ||||
static void | static void | ||||
defrouter_del(struct nd_defrouter *dr) | defrouter_del(struct nd_defrouter *dr) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,267 Lines • ▼ Show 20 Lines | restart: | ||||
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) | ||||
{ | { | ||||
struct sockaddr_dl_short sdl; | struct sockaddr_dl_short sdl; | ||||
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; | ||||
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_short)); | bzero(&sdl, sizeof(struct sockaddr_dl_short)); | ||||
sdl.sdl_len = sizeof(struct sockaddr_dl_short); | sdl.sdl_len = sizeof(struct sockaddr_dl_short); | ||||
sdl.sdl_family = AF_LINK; | sdl.sdl_family = AF_LINK; | ||||
sdl.sdl_type = ifa->ifa_ifp->if_type; | sdl.sdl_type = ifa->ifa_ifp->if_type; | ||||
sdl.sdl_index = ifa->ifa_ifp->if_index; | 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++) { | ||||
struct rt_addrinfo info; | |||||
donnerUnsubmitted Done Inline Actionsdito donner: dito | |||||
struct rib_cmd_info rc; | |||||
rt = NULL; | bzero((caddr_t)&info, sizeof(info)); | ||||
error = in6_rtrequest(RTM_ADD, | info.rti_flags = rtflags; | ||||
(struct sockaddr *)&pr->ndpr_prefix, (struct sockaddr *)&sdl, | info.rti_info[RTAX_DST] = (struct sockaddr *)&pr->ndpr_prefix; | ||||
(struct sockaddr *)&mask6, rtflags, &rt, fibnum); | info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sdl; | ||||
info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6; | |||||
NET_EPOCH_ASSERT(); | |||||
error = rib_action(fibnum, RTM_ADD, &info, &rc); | |||||
if (error != 0) { | if (error != 0) { | ||||
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; | ||||
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; | sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; | ||||
nd6log((LOG_ERR, "%s: failed to add " | nd6log((LOG_ERR, "%s: failed to add " | ||||
"route for a prefix (%s/%d) on %s, gw=%s, mask=%s, " | "route for a prefix (%s/%d) on %s, gw=%s, mask=%s, " | ||||
"flags=%lx errno = %d\n", __func__, | "flags=%lx errno = %d\n", __func__, | ||||
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), | ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), | ||||
pr->ndpr_plen, if_name(pr->ndpr_ifp), | pr->ndpr_plen, if_name(pr->ndpr_ifp), | ||||
ip6_sprintf(ip6bufg, &sin6->sin6_addr), | ip6_sprintf(ip6bufg, &sin6->sin6_addr), | ||||
ip6_sprintf(ip6bufm, &mask6.sin6_addr), | ip6_sprintf(ip6bufm, &mask6.sin6_addr), | ||||
rtflags, error)); | rtflags, error)); | ||||
/* Save last error to return, see rtinit(). */ | /* Save last error to return, see rtinit(). */ | ||||
a_failure = error; | a_failure = error; | ||||
continue; | continue; | ||||
} | } | ||||
pr->ndpr_stateflags |= NDPRF_ONLINK; | pr->ndpr_stateflags |= NDPRF_ONLINK; | ||||
rt_routemsg(RTM_ADD, rt, pr->ndpr_ifp, 0, fibnum); | rt_routemsg(RTM_ADD, rc.rc_rt, pr->ndpr_ifp, 0, fibnum); | ||||
} | } | ||||
/* Return the last error we got. */ | /* Return the last error we got. */ | ||||
return (a_failure); | return (a_failure); | ||||
} | } | ||||
static int | static int | ||||
nd6_prefix_onlink(struct nd_prefix *pr) | nd6_prefix_onlink(struct nd_prefix *pr) | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
nd6_prefix_offlink(struct nd_prefix *pr) | nd6_prefix_offlink(struct nd_prefix *pr) | ||||
{ | { | ||||
int error = 0; | int error = 0; | ||||
struct ifnet *ifp = pr->ndpr_ifp; | struct ifnet *ifp = pr->ndpr_ifp; | ||||
struct nd_prefix *opr; | struct nd_prefix *opr; | ||||
struct sockaddr_in6 sa6, mask6; | struct sockaddr_in6 sa6, mask6; | ||||
struct rtentry *rt; | struct rt_addrinfo info; | ||||
donnerUnsubmitted Done Inline Actionsdito donner: dito | |||||
struct rib_cmd_info rc; | |||||
char ip6buf[INET6_ADDRSTRLEN]; | char ip6buf[INET6_ADDRSTRLEN]; | ||||
uint64_t genid; | uint64_t genid; | ||||
int fibnum, maxfib, a_failure; | int fibnum, maxfib, a_failure; | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
ND6_ONLINK_LOCK_ASSERT(); | ND6_ONLINK_LOCK_ASSERT(); | ||||
ND6_UNLOCK_ASSERT(); | ND6_UNLOCK_ASSERT(); | ||||
Show All 16 Lines | nd6_prefix_offlink(struct nd_prefix *pr) | ||||
} else { | } else { | ||||
fibnum = ifp->if_fib; | fibnum = ifp->if_fib; | ||||
maxfib = fibnum + 1; | maxfib = fibnum + 1; | ||||
} | } | ||||
a_failure = 0; | a_failure = 0; | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
for (; fibnum < maxfib; fibnum++) { | for (; fibnum < maxfib; fibnum++) { | ||||
rt = NULL; | bzero((caddr_t)&info, sizeof(info)); | ||||
error = in6_rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL, | info.rti_flags = RTF_GATEWAY; | ||||
(struct sockaddr *)&mask6, 0, &rt, fibnum); | info.rti_info[RTAX_DST] = (struct sockaddr *)&sa6; | ||||
info.rti_info[RTAX_GATEWAY] = NULL; | |||||
info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6; | |||||
NET_EPOCH_ASSERT(); | |||||
error = rib_action(fibnum, RTM_DELETE, &info, &rc); | |||||
if (error != 0) { | if (error != 0) { | ||||
/* Save last error to return, see rtinit(). */ | /* Save last error to return, see rtinit(). */ | ||||
a_failure = error; | a_failure = error; | ||||
continue; | continue; | ||||
} | } | ||||
/* report route deletion to the routing socket. */ | /* report route deletion to the routing socket. */ | ||||
rt_routemsg(RTM_DELETE, rt, ifp, 0, fibnum); | rt_routemsg(RTM_DELETE, rc.rc_rt, ifp, 0, fibnum); | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
error = a_failure; | error = a_failure; | ||||
a_failure = 1; | a_failure = 1; | ||||
if (error == 0) { | if (error == 0) { | ||||
pr->ndpr_stateflags &= ~NDPRF_ONLINK; | pr->ndpr_stateflags &= ~NDPRF_ONLINK; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 385 Lines • Show Last 20 Lines |
dito