Diff below converts two custom uses of rtrequest(9) to rt_ifa_add(9).
These are used to automagically install and remove the RTF_CONNECTED
route obtained from a router advertisement.
This changes the existing logic a bit to match the netinet behavior.
The route will now be attached to the ``ifa'' matching the prefix
announced:
-2001::/64 fe80::5054:ff:fe12:3456%vio0 UC 0
2 - 4 vio0
+2001::/64 2001::5054:ff:fe12:3456 UC 0
0 - 4 vio0
This should be fine as the "gateway" field does not matter for
RTF_CLONING routes.
ok?
Index: netinet6/nd6_rtr.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v
retrieving revision 1.134
diff -u -p -r1.134 nd6_rtr.c
--- netinet6/nd6_rtr.c 24 Nov 2015 13:37:16 -0000 1.134
+++ netinet6/nd6_rtr.c 1 Dec 2015 12:22:56 -0000
@@ -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);
- error = rtrequest(RTM_DELETE, &info, RTP_CONNECTED, &rt,
- ifp->if_rdomain);
+ if (nd6_need_cache(ifp))
+ rtflags = RTF_CLONING | RTF_CONNECTED;
+
+ 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);