diff options
author | ume <ume@FreeBSD.org> | 2003-11-12 21:39:12 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-11-12 21:39:12 +0000 |
commit | 89a592a70c828aa2ebb221221e8c36c83179cdb5 (patch) | |
tree | 5af80c963d5806ba96d0d952700190aaccaed477 /sys/netinet6 | |
parent | 6a52a51a4490ccf15281df6dbd3ae35c26c166d5 (diff) | |
download | FreeBSD-src-89a592a70c828aa2ebb221221e8c36c83179cdb5.zip FreeBSD-src-89a592a70c828aa2ebb221221e8c36c83179cdb5.tar.gz |
reflect ip6_pktopts and ip6_moptions into embeded scope of
destination address. it makes `ping6 -I <if> <link-local>'
work again. since we don't merge scope cleanup yet, we need
this for workaround.
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_src.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index cec11c9..d584956 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -173,9 +173,23 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp) struct sockaddr_in6 dstsock0; dstsock0 = *dstsock; - if ((*errorp = in6_embedscope(&dstsock0.sin6_addr, &dstsock0, - NULL, NULL)) != 0) - return (NULL); + if (IN6_IS_SCOPE_LINKLOCAL(&dstsock0.sin6_addr) || + IN6_IS_ADDR_MC_INTFACELOCAL(&dstsock0.sin6_addr)) { + /* KAME assumption: link id == interface id */ + if (opts && opts->ip6po_pktinfo && + opts->ip6po_pktinfo->ipi6_ifindex) { + ifp = ifnet_byindex(opts->ip6po_pktinfo->ipi6_ifindex); + dstsock0.sin6_addr.s6_addr16[1] = + htons(opts->ip6po_pktinfo->ipi6_ifindex); + } else if (mopts && + IN6_IS_ADDR_MULTICAST(&dstsock0.sin6_addr) && + mopts->im6o_multicast_ifp) { + ifp = mopts->im6o_multicast_ifp; + dstsock0.sin6_addr.s6_addr16[1] = htons(ifp->if_index); + } else if ((*errorp = in6_embedscope(&dstsock0.sin6_addr, + &dstsock0, NULL, NULL)) != 0) + return (NULL); + } dstsock = &dstsock0; dst = &dstsock->sin6_addr; |