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);

Reply via email to