diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2006-11-17 01:11:24 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2006-11-17 01:11:24 +0000 |
commit | d47bdeb6300d8da6e915c6e5f97a3d3d6b7e4b5d (patch) | |
tree | a7a1d754c5bbab5286abc8c4377cf6af4a694d4e /sys/netinet6/ip6_output.c | |
parent | f90ac2555337c72651bc65977807ddf57df6db9a (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.c | 69 |
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); |