summaryrefslogtreecommitdiff
path: root/sys/netinet6/ip6_output.c
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2006-11-17 01:11:24 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2006-11-17 01:11:24 +0000
commitd47bdeb6300d8da6e915c6e5f97a3d3d6b7e4b5d (patch)
treea7a1d754c5bbab5286abc8c4377cf6af4a694d4e /sys/netinet6/ip6_output.c
parentf90ac2555337c72651bc65977807ddf57df6db9a (diff)
change semantics of ff01::/16 to interface local multicast
(to sync up with more recent IPv6 spec) ok from: deraadt mcbride
Diffstat (limited to 'sys/netinet6/ip6_output.c')
-rw-r--r--sys/netinet6/ip6_output.c69
1 files changed, 22 insertions, 47 deletions
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index b9f247515d8..84f62a56b84 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.93 2006/06/18 11:47:46 pascoe Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.94 2006/11/17 01:11:23 itojun Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -592,26 +592,6 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
if (opt && opt->ip6po_pktinfo && opt->ip6po_pktinfo->ipi6_ifindex)
ifp = ifindex2ifnet[opt->ip6po_pktinfo->ipi6_ifindex];
- /*
- * If the destination is a node-local scope multicast,
- * the packet should be loop-backed only.
- */
- if (IN6_IS_ADDR_MC_NODELOCAL(&ip6->ip6_dst)) {
- /*
- * If the outgoing interface is already specified,
- * it should be a loopback interface.
- */
- if (ifp && (ifp->if_flags & IFF_LOOPBACK) == 0) {
- ip6stat.ip6s_badscope++;
- error = ENETUNREACH; /* XXX: better error? */
- /* XXX correct ifp? */
- in6_ifstat_inc(ifp, ifs6_out_discard);
- goto bad;
- } else {
- ifp = lo0ifp;
- }
- }
-
if (opt && opt->ip6po_hlim != -1)
ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
@@ -691,7 +671,8 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
* loop back a copy if this host actually belongs to the
* destination group on the loopback interface.
*/
- if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK)) {
+ if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) ||
+ IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
m_freem(m);
goto done;
}
@@ -736,9 +717,9 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
* future.
*/
origifp = NULL;
- if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+ if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
origifp = ifindex2ifnet[ntohs(ip6->ip6_src.s6_addr16[1])];
- else if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+ else if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
origifp = ifindex2ifnet[ntohs(ip6->ip6_dst.s6_addr16[1])];
/*
* XXX: origifp can be NULL even in those two cases above.
@@ -756,9 +737,9 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
origifp = ifp;
} else
origifp = ifp;
- if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+ if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
ip6->ip6_src.s6_addr16[1] = 0;
- if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+ if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
/*
@@ -1953,29 +1934,23 @@ ip6_setmoptions(optname, im6op, m)
*/
if (mreq->ipv6mr_interface == 0) {
/*
- * If the multicast address is in node-local scope,
- * the interface should be a loopback interface.
- * Otherwise, look up the routing table for the
+ * Look up the routing table for the
* address, and choose the outgoing interface.
* XXX: is it a good approach?
*/
- if (IN6_IS_ADDR_MC_NODELOCAL(&mreq->ipv6mr_multiaddr)) {
- ifp = lo0ifp;
- } else {
- ro.ro_rt = NULL;
- dst = (struct sockaddr_in6 *)&ro.ro_dst;
- bzero(dst, sizeof(*dst));
- dst->sin6_len = sizeof(struct sockaddr_in6);
- dst->sin6_family = AF_INET6;
- dst->sin6_addr = mreq->ipv6mr_multiaddr;
- rtalloc((struct route *)&ro);
- if (ro.ro_rt == NULL) {
- error = EADDRNOTAVAIL;
- break;
- }
- ifp = ro.ro_rt->rt_ifp;
- rtfree(ro.ro_rt);
+ ro.ro_rt = NULL;
+ dst = (struct sockaddr_in6 *)&ro.ro_dst;
+ bzero(dst, sizeof(*dst));
+ dst->sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_addr = mreq->ipv6mr_multiaddr;
+ rtalloc((struct route *)&ro);
+ if (ro.ro_rt == NULL) {
+ error = EADDRNOTAVAIL;
+ break;
}
+ ifp = ro.ro_rt->rt_ifp;
+ rtfree(ro.ro_rt);
} else {
/*
* If the interface is specified, validate it.
@@ -2391,9 +2366,9 @@ ip6_mloopback(ifp, m, dst)
#endif
ip6 = mtod(copym, struct ip6_hdr *);
- if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+ if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
ip6->ip6_src.s6_addr16[1] = 0;
- if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+ if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
(void)looutput(ifp, copym, (struct sockaddr *)dst, NULL);