summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-12-01 21:29:11 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-12-01 21:29:11 +0000
commit0d6ca6f3fa2af05ae26768f577af8ce038ab4406 (patch)
tree500d6349839e0ef14d4ecbdd886875889573d163 /sys
parent1c35993915d8246cfd943d09ca99f118a5ff76df (diff)
Use rt_ifa_add(9) instead or rtrequest(9) when adding ND prefixes.
While here pick the corresponding ``ifa'' to attach the route instead of the one corresponding to the link-local address on the same interface. ok bluhm@
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/nd6_rtr.c86
1 files changed, 24 insertions, 62 deletions
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 19116975c72..84bc27c8b96 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_rtr.c,v 1.134 2015/11/24 13:37:16 mpi Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.135 2015/12/01 21:29:10 mpi Exp $ */
/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
@@ -1697,15 +1697,11 @@ pfxlist_onlink_check(void)
int
nd6_prefix_onlink(struct nd_prefix *pr)
{
- struct rt_addrinfo info;
- struct ifaddr *ifa;
struct ifnet *ifp = pr->ndpr_ifp;
- struct sockaddr_in6 mask6;
+ struct ifaddr *ifa;
struct nd_prefix *opr;
- struct rtentry *rt;
char addr[INET6_ADDRSTRLEN];
- u_long rtflags = 0;
- int error;
+ int error, rtflags = 0;
/* sanity check */
if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0)
@@ -1731,18 +1727,11 @@ nd6_prefix_onlink(struct nd_prefix *pr)
return (0);
}
- /*
- * We prefer link-local addresses as the associated interface address.
- */
- /* search for a link-local addr */
- ifa = &in6ifa_ifpforlinklocal(ifp,
- IN6_IFF_NOTREADY | IN6_IFF_ANYCAST)->ia_ifa;
- if (ifa == NULL) {
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family == AF_INET6)
- break;
- }
- /* should we care about ia6_flags? */
+ TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+ if (ifatoia6(ifa)->ia6_ndpr == pr)
+ break;
}
if (ifa == NULL) {
/*
@@ -1760,25 +1749,12 @@ nd6_prefix_onlink(struct nd_prefix *pr)
return (0);
}
- bzero(&mask6, sizeof(mask6));
- mask6.sin6_len = sizeof(mask6);
- mask6.sin6_addr = pr->ndpr_mask;
-
if (nd6_need_cache(ifp))
rtflags = RTF_CLONING | RTF_CONNECTED;
- bzero(&info, sizeof(info));
- info.rti_flags = rtflags;
- info.rti_info[RTAX_DST] = sin6tosa(&pr->ndpr_prefix);
- info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
- info.rti_info[RTAX_NETMASK] = sin6tosa(&mask6);
-
- error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, &rt, ifp->if_rdomain);
- if (error == 0) {
+ error = rt_ifa_add(ifa, rtflags, sin6tosa(&pr->ndpr_prefix));
+ if (error == 0)
pr->ndpr_stateflags |= NDPRF_ONLINK;
- rt_sendmsg(rt, RTM_ADD, ifp->if_rdomain);
- rtfree(rt);
- }
return (error);
}
@@ -1786,13 +1762,11 @@ nd6_prefix_onlink(struct nd_prefix *pr)
int
nd6_prefix_offlink(struct nd_prefix *pr)
{
- struct rt_addrinfo info;
struct ifnet *ifp = pr->ndpr_ifp;
+ struct ifaddr *ifa;
struct nd_prefix *opr;
- struct sockaddr_in6 sa6, mask6;
- struct rtentry *rt;
char addr[INET6_ADDRSTRLEN];
- int error;
+ int error, rtflags = 0;
/* sanity check */
if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
@@ -1804,27 +1778,22 @@ nd6_prefix_offlink(struct nd_prefix *pr)
return (EEXIST);
}
- bzero(&sa6, sizeof(sa6));
- sa6.sin6_family = AF_INET6;
- sa6.sin6_len = sizeof(sa6);
- bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr,
- sizeof(struct in6_addr));
- bzero(&mask6, sizeof(mask6));
- mask6.sin6_family = AF_INET6;
- mask6.sin6_len = sizeof(sa6);
- bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr));
- bzero(&info, sizeof(info));
- info.rti_info[RTAX_DST] = sin6tosa(&sa6);
- info.rti_info[RTAX_NETMASK] = sin6tosa(&mask6);
+ TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+ if (ifatoia6(ifa)->ia6_ndpr == pr)
+ break;
+ }
+ if (ifa == NULL)
+ return (EINVAL);
+
+ if (nd6_need_cache(ifp))
+ rtflags = RTF_CLONING | RTF_CONNECTED;
- error = rtrequest(RTM_DELETE, &info, RTP_CONNECTED, &rt,
- ifp->if_rdomain);
+ error = rt_ifa_del(ifa, rtflags, sin6tosa(&pr->ndpr_prefix));
if (error == 0) {
pr->ndpr_stateflags &= ~NDPRF_ONLINK;
- rt_sendmsg(rt, RTM_DELETE, ifp->if_rdomain);
- rtfree(rt);
-
/*
* There might be the same prefix on another interface,
* the prefix which could not be on-link just because we have
@@ -1864,13 +1833,6 @@ nd6_prefix_offlink(struct nd_prefix *pr)
}
}
}
- } else {
- /* XXX: can we still set the NDPRF_ONLINK flag? */
- nd6log((LOG_ERR,
- "nd6_prefix_offlink: failed to delete route: "
- "%s/%d on %s (errno = %d)\n",
- inet_ntop(AF_INET6, &sa6.sin6_addr, addr, sizeof(addr)),
- pr->ndpr_plen, ifp->if_xname, error));
}
return (error);