Le Sat, Jan 09, 2021 at 06:50:50PM +0100, Denis Fondras a écrit :
> This diff place the user-set source address outside of struct art_root and 
> make
> the code more readable (to me).
> 
> Based on a concept by mpi@
> 

ping.

> Index: net/art.h
> ===================================================================
> RCS file: /cvs/src/sys/net/art.h,v
> retrieving revision 1.20
> diff -u -p -r1.20 art.h
> --- net/art.h 12 Nov 2020 15:25:28 -0000      1.20
> +++ net/art.h 9 Jan 2021 16:04:02 -0000
> @@ -42,7 +42,6 @@ struct art_root {
>       uint8_t                  ar_nlvl;       /* [I] Number of levels */
>       uint8_t                  ar_alen;       /* [I] Address length in bits */
>       uint8_t                  ar_off;        /* [I] Offset of key in bytes */
> -     struct sockaddr         *source;        /* [K] optional src addr to use 
> */
>  };
>  
>  #define ISLEAF(e)    (((unsigned long)(e) & 1) == 0)
> Index: net/route.c
> ===================================================================
> RCS file: /cvs/src/sys/net/route.c,v
> retrieving revision 1.397
> diff -u -p -r1.397 route.c
> --- net/route.c       29 Oct 2020 21:15:27 -0000      1.397
> +++ net/route.c       9 Jan 2021 16:04:02 -0000
> @@ -1192,9 +1192,9 @@ rt_ifa_del(struct ifaddr *ifa, int flags
>       if (flags & RTF_CONNECTED)
>               prio = ifp->if_priority + RTP_CONNECTED;
>  
> -     rtable_clearsource(rdomain, ifa->ifa_addr);
>       error = rtrequest_delete(&info, prio, ifp, &rt, rdomain);
>       if (error == 0) {
> +             rt_sourceclear(rt, rdomain);
>               rtm_send(rt, RTM_DELETE, 0, rdomain);
>               if (flags & RTF_LOCAL)
>                       rtm_addr(RTM_DELADDR, ifa);
> Index: net/route.h
> ===================================================================
> RCS file: /cvs/src/sys/net/route.h,v
> retrieving revision 1.183
> diff -u -p -r1.183 route.h
> --- net/route.h       29 Oct 2020 21:15:27 -0000      1.183
> +++ net/route.h       9 Jan 2021 16:04:02 -0000
> @@ -478,6 +478,9 @@ int        rtrequest_delete(struct rt_addrinfo
>  int   rt_if_track(struct ifnet *);
>  int   rt_if_linkstate_change(struct rtentry *, void *, u_int);
>  int   rtdeletemsg(struct rtentry *, struct ifnet *, u_int);
> +
> +struct ifaddr        *rt_get_ifa(struct rtentry *, unsigned int);
> +void          rt_sourceclear(struct rtentry *, unsigned int);
>  #endif /* _KERNEL */
>  
>  #endif /* _NET_ROUTE_H_ */
> Index: net/rtable.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtable.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 rtable.c
> --- net/rtable.c      7 Nov 2020 09:51:40 -0000       1.72
> +++ net/rtable.c      9 Jan 2021 16:04:02 -0000
> @@ -365,44 +365,6 @@ rtable_alloc(unsigned int rtableid, unsi
>       return (art_alloc(rtableid, alen, off));
>  }
>  
> -int
> -rtable_setsource(unsigned int rtableid, int af, struct sockaddr *src)
> -{
> -     struct art_root         *ar;
> -
> -     if ((ar = rtable_get(rtableid, af)) == NULL)
> -             return (EAFNOSUPPORT);
> -
> -     ar->source = src;
> -
> -     return (0);
> -}
> -
> -struct sockaddr *
> -rtable_getsource(unsigned int rtableid, int af)
> -{
> -     struct art_root         *ar;
> -
> -     ar = rtable_get(rtableid, af);
> -     if (ar == NULL)
> -             return (NULL);
> -
> -     return (ar->source);
> -}
> -
> -void
> -rtable_clearsource(unsigned int rtableid, struct sockaddr *src)
> -{
> -     struct sockaddr *addr;
> -
> -     addr = rtable_getsource(rtableid, src->sa_family);
> -     if (addr && (addr->sa_len == src->sa_len)) {
> -             if (memcmp(src, addr, addr->sa_len) == 0) {
> -                     rtable_setsource(rtableid, src->sa_family, NULL);
> -             }
> -     }
> -}
> -
>  struct rtentry *
>  rtable_lookup(unsigned int rtableid, struct sockaddr *dst,
>      struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio)
> Index: net/rtable.h
> ===================================================================
> RCS file: /cvs/src/sys/net/rtable.h,v
> retrieving revision 1.26
> diff -u -p -r1.26 rtable.h
> --- net/rtable.h      7 Nov 2020 09:51:40 -0000       1.26
> +++ net/rtable.h      9 Jan 2021 16:04:02 -0000
> @@ -39,9 +39,6 @@ unsigned int         rtable_l2(unsigned int);
>  unsigned int  rtable_loindex(unsigned int);
>  void          rtable_l2set(unsigned int, unsigned int, unsigned int);
>  
> -int           rtable_setsource(unsigned int, int, struct sockaddr *);
> -struct sockaddr *rtable_getsource(unsigned int, int);
> -void          rtable_clearsource(unsigned int, struct sockaddr *);
>  struct rtentry       *rtable_lookup(unsigned int, struct sockaddr *,
>                    struct sockaddr *, struct sockaddr *, uint8_t);
>  struct rtentry       *rtable_match(unsigned int, struct sockaddr *, uint32_t 
> *);
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.304
> diff -u -p -r1.304 rtsock.c
> --- net/rtsock.c      7 Nov 2020 09:51:40 -0000       1.304
> +++ net/rtsock.c      9 Jan 2021 16:04:02 -0000
> @@ -138,7 +138,8 @@ int                sysctl_iflist(int, struct walkarg 
>  int           sysctl_ifnames(struct walkarg *);
>  int           sysctl_rtable_rtstat(void *, size_t *, void *);
>  
> -int           rt_setsource(unsigned int, struct sockaddr *);
> +int           rt_sourceset(struct rtentry *, unsigned int);
> +struct rtentry       *rt_get_rt(int, unsigned int);
>  
>  /*
>   * Locks used to protect struct members
> @@ -170,6 +171,14 @@ struct rtptable {
>  struct pool rtpcb_pool;
>  struct rtptable rtptable;
>  
> +struct rt_srcaddr {
> +     LIST_ENTRY(rt_srcaddr)   rts_next;
> +     unsigned int             rts_rtableid;
> +     struct rtentry          *rts_rt;
> +};
> +
> +LIST_HEAD(, rt_srcaddr)      srcaddr_h = LIST_HEAD_INITIALIZER(srcaddr_h);
> +
>  /*
>   * These flags and timeout are used for indicating to userland (via a
>   * RTM_DESYNC msg) when the route socket has overflowed and messages
> @@ -664,10 +673,7 @@ rtm_report(struct rtentry *rt, u_char ty
>       ifp = if_get(rt->rt_ifidx);
>       if (ifp != NULL) {
>               info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
> -             info.rti_info[RTAX_IFA] =
> -                 rtable_getsource(tableid, 
> info.rti_info[RTAX_DST]->sa_family);
> -             if (info.rti_info[RTAX_IFA] == NULL)
> -                     info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
> +             info.rti_info[RTAX_IFA] = rt_get_ifa(rt, tableid)->ifa_addr;
>               if (ifp->if_flags & IFF_POINTOPOINT)
>                       info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr;
>       }
> @@ -860,10 +866,28 @@ route_output(struct mbuf *m, struct sock
>               if (info.rti_info[RTAX_IFA] == NULL) {
>                       error = EINVAL;
>                       goto fail;
> +             } else if ((info.rti_info[RTAX_IFA]->sa_family == AF_INET6 &&
> +                 IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)
> +                 info.rti_info[RTAX_IFA])->sin6_addr)) ||
> +                 (info.rti_info[RTAX_IFA]->sa_family == AF_INET &&
> +                 ((struct sockaddr_in *)
> +                 info.rti_info[RTAX_IFA])->sin_addr.s_addr == 0)) {
> +                     
> rt_sourceclear(rt_get_rt(info.rti_info[RTAX_IFA]->sa_family,
> +                         tableid), tableid);
> +                     rtfree(rt);
> +                     rt = NULL;
> +             } else {
> +                     rt = rtalloc(info.rti_info[RTAX_IFA], 0, tableid);
> +                     if (rt == NULL || !ISSET(rt->rt_flags, RTF_LOCAL)) {
> +                             error = EINVAL;
> +                             goto fail;
> +                     }
> +                     NET_LOCK();
> +                     error = rt_sourceset(rt, tableid);
> +                     NET_UNLOCK();
> +                     if (error != 0)
> +                             goto fail;
>               }
> -             if ((error =
> -                 rt_setsource(tableid, info.rti_info[RTAX_IFA])) != 0)
> -                     goto fail;
>       } else {
>               error = rtm_output(rtm, &rt, &info, prio, tableid);
>               if (!error) {
> @@ -873,9 +897,9 @@ route_output(struct mbuf *m, struct sock
>                       rtm = rtm_report(rt, type, seq, tableid);
>                       len = rtm->rtm_msglen;
>               }
> +             rtfree(rt);
>       }
>  
> -     rtfree(rt);
>       if (error) {
>               rtm->rtm_errno = error;
>       } else {
> @@ -1687,10 +1711,7 @@ rtm_send(struct rtentry *rt, int cmd, in
>       ifp = if_get(rt->rt_ifidx);
>       if (ifp != NULL) {
>               info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
> -             info.rti_info[RTAX_IFA] =
> -                 rtable_getsource(rtableid, 
> info.rti_info[RTAX_DST]->sa_family);
> -             if (info.rti_info[RTAX_IFA] == NULL)
> -                     info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
> +             info.rti_info[RTAX_IFA] = rt_get_ifa(rt, rtableid)->ifa_addr;
>       }
>  
>       rtm_miss(cmd, &info, rt->rt_flags, rt->rt_priority, rt->rt_ifidx, error,
> @@ -1928,10 +1949,7 @@ sysctl_dumpentry(struct rtentry *rt, voi
>       ifp = if_get(rt->rt_ifidx);
>       if (ifp != NULL) {
>               info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
> -             info.rti_info[RTAX_IFA] =
> -                 rtable_getsource(id, info.rti_info[RTAX_DST]->sa_family);
> -             if (info.rti_info[RTAX_IFA] == NULL)
> -                     info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
> +             info.rti_info[RTAX_IFA] = rt_get_ifa(rt, id)->ifa_addr;
>               if (ifp->if_flags & IFF_POINTOPOINT)
>                       info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr;
>       }
> @@ -2067,33 +2085,30 @@ sysctl_ifnames(struct walkarg *w)
>  }
>  
>  int
> -sysctl_source(int af, u_int tableid, struct walkarg *w)
> +sysctl_source(int af, struct walkarg *w)
>  {
> -     struct sockaddr *sa;
> -     int              size, error = 0;
> +     struct rt_srcaddr       *rtsa = NULL;
> +     unsigned int             tableid = w->w_arg;
> +     int                      error = 0;
>  
> -     sa = rtable_getsource(tableid, af);
> -     if (sa) {
> -             switch (sa->sa_family) {
> -             case AF_INET:
> -                     size = sizeof(struct sockaddr_in);
> -                     break;
> -#ifdef INET6
> -             case AF_INET6:
> -                     size = sizeof(struct sockaddr_in6);
> -                     break;
> -#endif
> -             default:
> -                     return (0);
> -             }
> -             w->w_needed += size;
> +     LIST_FOREACH(rtsa, &srcaddr_h, rts_next) {
> +             if (rtsa->rts_rtableid != tableid)
> +                     continue;
> +             if (af != 0 && rtsa->rts_rt->rt_dest->sa_family != af)
> +                     continue;
> +
> +             w->w_needed += rtsa->rts_rt->rt_dest->sa_len;
>               if (w->w_where && w->w_needed <= 0) {
> -                     if ((error = copyout(sa, w->w_where, size)))
> -                             return (error);
> -                     w->w_where += size;
> +                     error = copyout(rtsa->rts_rt->rt_ifa->ifa_addr,
> +                         w->w_where, rtsa->rts_rt->rt_dest->sa_len);
> +                     if (error == EAFNOSUPPORT)
> +                             error = 0;
> +                     if (error)
> +                             break;
> +                     w->w_where += rtsa->rts_rt->rt_dest->sa_len;
>               }
>       }
> -     return (0);
> +     return (error);
>  }
>  
>  int
> @@ -2171,16 +2186,7 @@ sysctl_rtable(int *name, u_int namelen, 
>               if (!rtable_exists(tableid))
>                       return (ENOENT);
>               NET_LOCK();
> -             for (i = 1; i <= AF_MAX; i++) {
> -                     if (af != 0 && af != i)
> -                             continue;
> -
> -                     error = sysctl_source(i, tableid, &w);
> -                     if (error == EAFNOSUPPORT)
> -                             error = 0;
> -                     if (error)
> -                             break;
> -             }
> +             error = sysctl_source(af, &w);
>               NET_UNLOCK();
>               break;
>       }
> @@ -2314,40 +2320,96 @@ rtm_validate_proposal(struct rt_addrinfo
>  }
>  
>  int
> -rt_setsource(unsigned int rtableid, struct sockaddr *src)
> +rt_sourceset(struct rtentry *rt, unsigned int rtableid)
>  {
> -     struct ifaddr   *ifa;
> -     /*
> -      * If source address is 0.0.0.0 or ::
> -      * use automatic source selection
> -      */
> -     switch(src->sa_family) {
> -     case AF_INET:
> -             if(satosin(src)->sin_addr.s_addr == INADDR_ANY) {
> -                     rtable_setsource(rtableid, AF_INET, NULL);
> -                     return (0);
> -             }
> -             break;
> -#ifdef INET6
> -     case AF_INET6:
> -             if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr)) {
> -                     rtable_setsource(rtableid, AF_INET6, NULL);
> -                     return (0);
> +     struct rt_srcaddr       *rtsa = NULL;
> +
> +     LIST_FOREACH(rtsa, &srcaddr_h, rts_next) {
> +             if (rtsa->rts_rtableid == rtableid &&
> +                 rtsa->rts_rt->rt_dest->sa_family == rt->rt_dest->sa_family)
> +                     break;
> +     }
> +     if (rtsa == NULL) {
> +             if ((rtsa = malloc(sizeof(struct rt_srcaddr), M_IFADDR,
> +                 M_NOWAIT|M_ZERO)) == NULL)
> +                     return (ENOMEM);
> +             rtsa->rts_rtableid = rtableid;
> +             rtsa->rts_rt = rt;
> +             LIST_INSERT_HEAD(&srcaddr_h, rtsa, rts_next);
> +     } else {
> +             /* Update existing entry */
> +             rtfree(rtsa->rts_rt);
> +             rtsa->rts_rt = rt;
> +     }
> +
> +     return (0);
> +}
> +
> +/*
> + * Return the 'ifa' associated to a given 'rt' unless a preferred
> + * source address has been specified for the same routing table.
> + */
> +struct rtentry *
> +rt_get_rt(int af, unsigned int rtableid)
> +{
> +     struct rt_srcaddr       *rtsa = NULL;
> +
> +     LIST_FOREACH(rtsa, &srcaddr_h, rts_next) {
> +             if (rtsa->rts_rtableid == rtableid &&
> +                 rtsa->rts_rt->rt_dest->sa_family == af)
> +                     break;
> +     }
> +     if (rtsa)
> +             return (rtsa->rts_rt);
> +
> +     return (NULL);
> +}
> +
> +struct ifaddr *
> +rt_get_ifa(struct rtentry *rt, unsigned int rtableid)
> +{
> +     struct rt_srcaddr       *rtsa = NULL;
> +     struct ifnet            *ifp = NULL;
> +
> +     if (ISSET(rt->rt_flags, RTF_HOST|RTF_LLINFO))
> +             return (rt->rt_ifa);
> +
> +     LIST_FOREACH(rtsa, &srcaddr_h, rts_next) {
> +             if (rtsa->rts_rtableid == rtableid &&
> +                 rtsa->rts_rt->rt_dest->sa_family == rt->rt_dest->sa_family)
> +                     break;
> +     }
> +     if (rtsa != NULL && rtisvalid(rtsa->rts_rt)) {
> +             struct rtentry  *nrt = rtsa->rts_rt;
> +
> +             ifp = if_get(nrt->rt_ifidx);
> +             if (ifp != NULL) {
> +                     if (ISSET(ifp->if_flags, IFF_UP)) {
> +                             if_put(ifp);
> +                             return (nrt->rt_ifa);
> +                     }
>               }
> -             break;
> -#endif
> -     default:
> -             return (EAFNOSUPPORT);
>       }
> +     return (rt->rt_ifa);
> +}
>  
> -     /*
> -      * Check if source address is assigned to an interface in the
> -      * same rdomain
> -      */
> -     if ((ifa = ifa_ifwithaddr(src, rtableid)) == NULL)
> -             return (EINVAL);
> +void
> +rt_sourceclear(struct rtentry *rt, unsigned int rtableid)
> +{
> +     struct rt_srcaddr       *rtsa = NULL;
>  
> -     return (rtable_setsource(rtableid, src->sa_family, ifa->ifa_addr));
> +     if (rt == NULL)
> +             return;
> +
> +     LIST_FOREACH(rtsa, &srcaddr_h, rts_next) {
> +             if (rtsa->rts_rtableid != rtableid)
> +                     continue;
> +             if (rtsa->rts_rt == rt) {
> +                     LIST_REMOVE(rtsa, rts_next);
> +                     free(rtsa, M_IFADDR, sizeof(struct rt_srcaddr));
> +                     break;
> +             }
> +     }
>  }
>  
>  /*
> Index: netinet/in_pcb.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in_pcb.c,v
> retrieving revision 1.252
> diff -u -p -r1.252 in_pcb.c
> --- netinet/in_pcb.c  7 Nov 2020 09:51:40 -0000       1.252
> +++ netinet/in_pcb.c  9 Jan 2021 16:04:02 -0000
> @@ -887,7 +887,6 @@ in_pcbselsrc(struct in_addr **insrc, str
>       struct route *ro = &inp->inp_route;
>       struct in_addr *laddr = &inp->inp_laddr;
>       u_int rtableid = inp->inp_rtableid;
> -     struct sockaddr *ip4_source = NULL;
>  
>       struct sockaddr_in *sin2;
>       struct in_ifaddr *ia = NULL;
> @@ -951,30 +950,11 @@ in_pcbselsrc(struct in_addr **insrc, str
>       }
>  
>       /*
> -      * If we found a route, use the address
> -      * corresponding to the outgoing interface.
> +      * If we found a route, use the address corresponding to the
> +      * outgoing interface or the preferred source address if set.
>        */
>       if (ro->ro_rt != NULL)
> -             ia = ifatoia(ro->ro_rt->rt_ifa);
> -
> -     /*
> -      * Use preferred source address if :
> -      * - destination is not onlink
> -      * - preferred source addresss is set
> -      * - output interface is UP
> -      */
> -     if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) &&
> -         !(ro->ro_rt->rt_flags & RTF_HOST)) {
> -             ip4_source = rtable_getsource(rtableid, AF_INET);
> -             if (ip4_source != NULL) {
> -                     struct ifaddr *ifa;
> -                     if ((ifa = ifa_ifwithaddr(ip4_source, rtableid)) !=
> -                         NULL && ISSET(ifa->ifa_ifp->if_flags, IFF_UP)) {
> -                             *insrc = &satosin(ip4_source)->sin_addr;
> -                             return (0);
> -                     }
> -             }
> -     }
> +             ia = ifatoia(rt_get_ifa(ro->ro_rt, rtableid));
>  
>       if (ia == NULL)
>               return (EADDRNOTAVAIL);
> Index: netinet/ip_icmp.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_icmp.c,v
> retrieving revision 1.184
> diff -u -p -r1.184 ip_icmp.c
> --- netinet/ip_icmp.c 20 Dec 2020 21:15:47 -0000      1.184
> +++ netinet/ip_icmp.c 9 Jan 2021 16:04:02 -0000
> @@ -745,7 +745,7 @@ icmp_reflect(struct mbuf *m, struct mbuf
>                       return (EHOSTUNREACH);
>               }
>  
> -             ia = ifatoia(rt->rt_ifa);
> +             ia = ifatoia(rt_get_ifa(rt, rtableid));
>       }
>  
>       ip->ip_dst = ip->ip_src;
> Index: netinet6/icmp6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/icmp6.c,v
> retrieving revision 1.233
> diff -u -p -r1.233 icmp6.c
> --- netinet6/icmp6.c  28 Oct 2020 17:27:35 -0000      1.233
> +++ netinet6/icmp6.c  9 Jan 2021 16:04:02 -0000
> @@ -1163,7 +1163,10 @@ icmp6_reflect(struct mbuf **mp, size_t o
>                       rtfree(rt);
>                       goto bad;
>               }
> -             ia6 = in6_ifawithscope(rt->rt_ifa->ifa_ifp, &t, rtableid);
> +             ia6 = ifatoia6(rt_get_ifa(rt, rtableid));
> +             if (ia6 == NULL)
> +                     ia6 = in6_ifawithscope(rt->rt_ifa->ifa_ifp, &t,
> +                         rtableid);
>               if (ia6 != NULL)
>                       src = &ia6->ia_addr.sin6_addr;
>               if (src == NULL)
> Index: netinet6/in6_src.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/in6_src.c,v
> retrieving revision 1.84
> diff -u -p -r1.84 in6_src.c
> --- netinet6/in6_src.c        7 Nov 2020 09:51:40 -0000       1.84
> +++ netinet6/in6_src.c        9 Jan 2021 16:04:02 -0000
> @@ -100,7 +100,6 @@ in6_pcbselsrc(struct in6_addr **in6src, 
>       struct in6_addr *laddr = &inp->inp_laddr6;
>       u_int rtableid = inp->inp_rtableid;
>       struct ifnet *ifp = NULL;
> -     struct sockaddr *ip6_source = NULL;
>       struct in6_addr *dst;
>       struct in6_ifaddr *ia6 = NULL;
>       struct in6_pktinfo *pi = NULL;
> @@ -208,32 +207,16 @@ in6_pcbselsrc(struct in6_addr **in6src, 
>        */
>  
>       if (ro->ro_rt) {
> -             ifp = if_get(ro->ro_rt->rt_ifidx);
> -             if (ifp != NULL) {
> -                     ia6 = in6_ifawithscope(ifp, dst, rtableid);
> -                     if_put(ifp);
> +             ia6 = ifatoia6(rt_get_ifa(ro->ro_rt, rtableid));
> +             if (ia6 == NULL) {
> +                     ifp = if_get(ro->ro_rt->rt_ifidx);
> +                     if (ifp != NULL) {
> +                             ia6 = in6_ifawithscope(ifp, dst, rtableid);
> +                             if_put(ifp);
> +                     }
>               }
>               if (ia6 == NULL) /* xxx scope error ?*/
>                       ia6 = ifatoia6(ro->ro_rt->rt_ifa);
> -     }
> -
> -     /*
> -      * Use preferred source address if :
> -      * - destination is not onlink
> -      * - preferred source addresss is set
> -      * - output interface is UP
> -      */
> -     if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) &&
> -         !(ro->ro_rt->rt_flags & RTF_HOST)) {
> -             ip6_source = rtable_getsource(rtableid, AF_INET6);
> -             if (ip6_source != NULL) {
> -                     struct ifaddr *ifa;
> -                     if ((ifa = ifa_ifwithaddr(ip6_source, rtableid)) !=
> -                         NULL && ISSET(ifa->ifa_ifp->if_flags, IFF_UP)) {
> -                             *in6src = &satosin6(ip6_source)->sin6_addr;
> -                             return (0);
> -                     }
> -             }
>       }
>  
>       if (ia6 == NULL)

Reply via email to