On Tue, Dec 01, 2015 at 01:34:15PM +0100, Martin Pieuchot wrote: > 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?
OK bluhm@ > > 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);