diff options
Diffstat (limited to 'sys/netinet6/in6_src.c')
-rw-r--r-- | sys/netinet6/in6_src.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index f087faef5390..8e82ef117aef 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sx.h> #include <net/if.h> +#include <net/if_dl.h> #include <net/route.h> #include <net/if_llatbl.h> #ifdef RADIX_MPATH @@ -697,8 +698,25 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, if (error == EHOSTUNREACH) V_ip6stat.ip6s_noroute++; - if (retifp != NULL) + if (retifp != NULL) { *retifp = ifp; + + /* + * Adjust the "outgoing" interface. If we're going to loop + * the packet back to ourselves, the ifp would be the loopback + * interface. However, we'd rather know the interface associated + * to the destination address (which should probably be one of + * our own addresses.) + */ + if (rt) { + if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) && + (rt->rt_gateway->sa_family == AF_LINK)) + *retifp = + ifnet_byindex(((struct sockaddr_dl *) + rt->rt_gateway)->sdl_index); + } + } + if (retrt != NULL) *retrt = rt; /* rt may be NULL */ @@ -750,16 +768,6 @@ in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, return (flags); } - /* - * Adjust the "outgoing" interface. If we're going to loop the packet - * back to ourselves, the ifp would be the loopback interface. - * However, we'd rather know the interface associated to the - * destination address (which should probably be one of our own - * addresses.) - */ - if (rt && rt->rt_ifa && rt->rt_ifa->ifa_ifp) - *retifp = rt->rt_ifa->ifa_ifp; - if (ro == &sro && rt && rt == sro.ro_rt) RTFREE(rt); return (0); |