summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6_src.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-11-12 21:39:12 +0000
committerume <ume@FreeBSD.org>2003-11-12 21:39:12 +0000
commit89a592a70c828aa2ebb221221e8c36c83179cdb5 (patch)
tree5af80c963d5806ba96d0d952700190aaccaed477 /sys/netinet6/in6_src.c
parent6a52a51a4490ccf15281df6dbd3ae35c26c166d5 (diff)
downloadFreeBSD-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/in6_src.c')
-rw-r--r--sys/netinet6/in6_src.c20
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;
OpenPOWER on IntegriCloud