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 | |
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')
-rw-r--r-- | sys/netinet6/icmp6.c | 8 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 106 | ||||
-rw-r--r-- | sys/netinet6/in6.h | 19 | ||||
-rw-r--r-- | sys/netinet6/in6_cksum.c | 6 | ||||
-rw-r--r-- | sys/netinet6/in6_src.c | 25 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 6 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 18 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 2 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 69 | ||||
-rw-r--r-- | sys/netinet6/mld6.c | 4 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 10 |
11 files changed, 129 insertions, 144 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index ea813cebdb7..85da9ea96b4 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.88 2006/11/15 03:07:44 itojun Exp $ */ +/* $OpenBSD: icmp6.c,v 1.89 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -377,9 +377,9 @@ icmp6_error(m, type, code, param) nip6->ip6_src = oip6->ip6_src; nip6->ip6_dst = oip6->ip6_dst; - if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src)) + if (IN6_IS_SCOPE_EMBED(&oip6->ip6_src)) oip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst)) + if (IN6_IS_SCOPE_EMBED(&oip6->ip6_dst)) oip6->ip6_dst.s6_addr16[1] = 0; icmp6 = (struct icmp6_hdr *)(nip6 + 1); @@ -1261,7 +1261,7 @@ ni6_input(m, off) m_copydata(m, off + sizeof(struct icmp6_nodeinfo), subjlen, (caddr_t)&sin6.sin6_addr); /* XXX kame scope hack */ - if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) { + if (IN6_IS_SCOPE_EMBED(&sin6.sin6_addr)) { if ((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) { sin6.sin6_addr.s6_addr16[1] = diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 0b810a17153..05fa7db2e70 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.71 2006/11/15 03:07:44 itojun Exp $ */ +/* $OpenBSD: in6.c,v 1.72 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -100,8 +100,8 @@ */ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; -const struct in6_addr in6addr_nodelocal_allnodes = - IN6ADDR_NODELOCAL_ALLNODES_INIT; +const struct in6_addr in6addr_intfacelocal_allnodes = + IN6ADDR_INTFACELOCAL_ALLNODES_INIT; const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; const struct in6_addr in6addr_linklocal_allrouters = @@ -1037,7 +1037,6 @@ in6_update_ifa(ifp, ifra, ia) /* join necessary multiast groups */ if ((ifp->if_flags & IFF_MULTICAST) != 0) { struct sockaddr_in6 mltaddr, mltmask; - u_int32_t zoneid = 0; /* join solicited multicast addr for new host id */ struct sockaddr_in6 llsol; @@ -1075,6 +1074,7 @@ in6_update_ifa(ifp, ifra, ia) mltaddr.sin6_family = AF_INET6; mltaddr.sin6_addr = in6addr_linklocal_allnodes; mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); + mltaddr.sin6_scope_id = 0; /* * XXX: do we really need this automatic routes? @@ -1113,7 +1113,6 @@ in6_update_ifa(ifp, ifra, ia) } else { RTFREE(rt); } - mltaddr.sin6_scope_id = zoneid; /* XXX */ imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error); if (!imm) { nd6log((LOG_WARNING, @@ -1142,52 +1141,55 @@ in6_update_ifa(ifp, ifra, ia) } } - if (ifp->if_flags & IFF_LOOPBACK) { - /* - * join node-local all-nodes address, on loopback. - * (ff01::1%ifN, and ff01::%ifN/32) - */ - mltaddr.sin6_addr = in6addr_nodelocal_allnodes; - - /* XXX: again, do we really need the route? */ - rt = rtalloc1((struct sockaddr *)&mltaddr, 0, 0); - if (rt) { - /* 32bit came from "mltmask" */ - if (memcmp(&mltaddr.sin6_addr, - &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr, - 32 / 8)) { - RTFREE(rt); - rt = NULL; - } - } - if (!rt) { - struct rt_addrinfo info; - - bzero(&info, sizeof(info)); - info.rti_info[RTAX_DST] = (struct sockaddr *)&mltaddr; - info.rti_info[RTAX_GATEWAY] = - (struct sockaddr *)&ia->ia_addr; - info.rti_info[RTAX_NETMASK] = - (struct sockaddr *)&mltmask; - info.rti_info[RTAX_IFA] = - (struct sockaddr *)&ia->ia_addr; - info.rti_flags = RTF_UP | RTF_CLONING; - error = rtrequest1(RTM_ADD, &info, NULL, 0); - if (error) - goto cleanup; - } else { + /* + * join interface-local all-nodes address. + * (ff01::1%ifN, and ff01::%ifN/32) + */ + bzero(&mltaddr.sin6_addr, sizeof(mltaddr.sin6_addr)); + mltaddr.sin6_len = sizeof(struct sockaddr_in6); + mltaddr.sin6_family = AF_INET6; + mltaddr.sin6_addr = in6addr_intfacelocal_allnodes; + mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); + mltaddr.sin6_scope_id = 0; + + /* XXX: again, do we really need the route? */ + rt = rtalloc1((struct sockaddr *)&mltaddr, 0, 0); + if (rt) { + /* 32bit came from "mltmask" */ + if (memcmp(&mltaddr.sin6_addr, + &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr, + 32 / 8)) { RTFREE(rt); + rt = NULL; } - imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error); - if (!imm) { - nd6log((LOG_WARNING, "in6_update_ifa: " - "addmulti failed for %s on %s (errno=%d)\n", - ip6_sprintf(&mltaddr.sin6_addr), - ifp->if_xname, error)); + } + if (!rt) { + struct rt_addrinfo info; + + bzero(&info, sizeof(info)); + info.rti_info[RTAX_DST] = (struct sockaddr *)&mltaddr; + info.rti_info[RTAX_GATEWAY] = + (struct sockaddr *)&ia->ia_addr; + info.rti_info[RTAX_NETMASK] = + (struct sockaddr *)&mltmask; + info.rti_info[RTAX_IFA] = + (struct sockaddr *)&ia->ia_addr; + info.rti_flags = RTF_UP | RTF_CLONING; + error = rtrequest1(RTM_ADD, &info, NULL, 0); + if (error) goto cleanup; - } - LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain); + } else { + RTFREE(rt); + } + imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error); + if (!imm) { + nd6log((LOG_WARNING, "in6_update_ifa: " + "addmulti failed for %s on %s (errno=%d)\n", + ip6_sprintf(&mltaddr.sin6_addr), + ifp->if_xname, error)); + goto cleanup; } + LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain); } /* @@ -2059,8 +2061,8 @@ struct in6_addr *addr; * return scope doesn't work. */ switch (scope) { - case IPV6_ADDR_SCOPE_NODELOCAL: - return IPV6_ADDR_SCOPE_NODELOCAL; + case IPV6_ADDR_SCOPE_INTFACELOCAL: + return IPV6_ADDR_SCOPE_INTFACELOCAL; break; case IPV6_ADDR_SCOPE_LINKLOCAL: return IPV6_ADDR_SCOPE_LINKLOCAL; @@ -2076,7 +2078,7 @@ struct in6_addr *addr; if (bcmp(&in6addr_loopback, addr, sizeof(*addr) - 1) == 0) { if (addr->s6_addr8[15] == 1) /* loopback */ - return IPV6_ADDR_SCOPE_NODELOCAL; + return IPV6_ADDR_SCOPE_INTFACELOCAL; if (addr->s6_addr8[15] == 0) /* unspecified */ return IPV6_ADDR_SCOPE_LINKLOCAL; } @@ -2092,9 +2094,7 @@ in6_addr2scopeid(ifp, addr) int scope = in6_addrscope(addr); switch(scope) { - case IPV6_ADDR_SCOPE_NODELOCAL: - return (-1); /* XXX: is this an appropriate value? */ - + case IPV6_ADDR_SCOPE_INTFACELOCAL: case IPV6_ADDR_SCOPE_LINKLOCAL: /* XXX: we do not distinguish between a link and an I/F. */ return (ifp->if_index); diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 50c41795d97..fbb706a2abb 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.h,v 1.39 2006/06/18 11:47:46 pascoe Exp $ */ +/* $OpenBSD: in6.h,v 1.40 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -208,6 +208,9 @@ extern const struct in6_addr in6mask128; #define IN6ADDR_NODELOCAL_ALLNODES_INIT \ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} +#define IN6ADDR_INTFACELOCAL_ALLNODES_INIT \ + {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} #define IN6ADDR_LINKLOCAL_ALLNODES_INIT \ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} @@ -219,7 +222,7 @@ extern const struct in6_addr in6mask128; extern const struct in6_addr in6addr_any; extern const struct in6_addr in6addr_loopback; #if __BSD_VISIBLE -extern const struct in6_addr in6addr_nodelocal_allnodes; +extern const struct in6_addr in6addr_intfacelocal_allnodes; extern const struct in6_addr in6addr_linklocal_allnodes; extern const struct in6_addr in6addr_linklocal_allrouters; #endif @@ -282,12 +285,14 @@ extern const struct in6_addr in6addr_linklocal_allrouters; #ifdef _KERNEL /* XXX nonstandard */ #define IPV6_ADDR_SCOPE_NODELOCAL 0x01 +#define IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 #define IPV6_ADDR_SCOPE_LINKLOCAL 0x02 #define IPV6_ADDR_SCOPE_SITELOCAL 0x05 #define IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */ #define IPV6_ADDR_SCOPE_GLOBAL 0x0e #else #define __IPV6_ADDR_SCOPE_NODELOCAL 0x01 +#define __IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 #define __IPV6_ADDR_SCOPE_LINKLOCAL 0x02 #define __IPV6_ADDR_SCOPE_SITELOCAL 0x05 #define __IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */ @@ -321,6 +326,9 @@ extern const struct in6_addr in6addr_linklocal_allrouters; #define IN6_IS_ADDR_MC_NODELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL)) +#define IN6_IS_ADDR_MC_INTFACELOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_INTFACELOCAL)) #define IN6_IS_ADDR_MC_LINKLOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL)) @@ -337,6 +345,9 @@ extern const struct in6_addr in6addr_linklocal_allrouters; #define IN6_IS_ADDR_MC_NODELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL)) +#define IN6_IS_ADDR_MC_INTFACELOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_INTFACELOCAL)) #define IN6_IS_ADDR_MC_LINKLOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL)) @@ -358,6 +369,10 @@ extern const struct in6_addr in6addr_linklocal_allrouters; #define IN6_IS_SCOPE_LINKLOCAL(a) \ ((IN6_IS_ADDR_LINKLOCAL(a)) || \ (IN6_IS_ADDR_MC_LINKLOCAL(a))) +#define IN6_IS_SCOPE_EMBED(a) \ + ((IN6_IS_ADDR_LINKLOCAL(a)) || \ + (IN6_IS_ADDR_MC_LINKLOCAL(a)) || \ + (IN6_IS_ADDR_MC_INTFACELOCAL(a))) #define IFA6_IS_DEPRECATED(a) \ ((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \ diff --git a/sys/netinet6/in6_cksum.c b/sys/netinet6/in6_cksum.c index 254f2ef7fa9..164b2859ffa 100644 --- a/sys/netinet6/in6_cksum.c +++ b/sys/netinet6/in6_cksum.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_cksum.c,v 1.13 2003/11/16 20:30:07 avsm Exp $ */ +/* $OpenBSD: in6_cksum.c,v 1.14 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: in6_cksum.c,v 1.10 2000/12/03 00:53:59 itojun Exp $ */ /* @@ -130,13 +130,13 @@ in6_cksum(m, nxt, off, len) /* IPv6 source address */ sum += w[0]; - if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) + if (!IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) sum += w[1]; sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; /* IPv6 destination address */ sum += w[8]; - if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) + if (!IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) sum += w[9]; sum += w[10]; sum += w[11]; sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index cb35e0e1894..107ee15eb4a 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.19 2006/06/18 11:47:46 pascoe Exp $ */ +/* $OpenBSD: in6_src.c,v 1.20 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -141,15 +141,15 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp) /* * If the destination address is a link-local unicast address or - * a multicast address, and if the outgoing interface is specified - * by the sin6_scope_id filed, use an address associated with the - * interface. + * a link/interface-local multicast address, and if the outgoing + * interface is specified by the sin6_scope_id filed, use an address + * associated with the interface. * XXX: We're now trying to define more specific semantics of * sin6_scope_id field, so this part will be rewritten in * the near future. */ - if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MC_LINKLOCAL(dst)) && - dstsock->sin6_scope_id) { + if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MC_LINKLOCAL(dst) || + IN6_IS_ADDR_MC_INTFACELOCAL(dst)) && dstsock->sin6_scope_id) { /* * I'm not sure if boundary check for scope_id is done * somewhere... @@ -173,17 +173,14 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp) * If the destination address is a multicast address and * the outgoing interface for the address is specified * by the caller, use an address associated with the interface. - * There is a sanity check here; if the destination has node-local - * scope, the outgoing interfacde should be a loopback address. * Even if the outgoing interface is not specified, we also * choose a loopback interface as the outgoing interface. */ if (IN6_IS_ADDR_MULTICAST(dst)) { struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL; - if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst)) { - ifp = lo0ifp; - } + if (!ifp && dstsock->sin6_scope_id) + ifp = ifindex2ifnet[htons(dstsock->sin6_scope_id)]; if (ifp) { ia6 = in6_ifawithscope(ifp, dst); @@ -352,7 +349,7 @@ in6_embedscope(in6, sin6, in6p, ifpp) * ask us to overwrite existing sockaddr_in6 */ - if (IN6_IS_SCOPE_LINKLOCAL(in6)) { + if (IN6_IS_SCOPE_EMBED(in6)) { struct in6_pktinfo *pi; /* @@ -411,7 +408,7 @@ in6_recoverscope(sin6, in6, ifp) */ sin6->sin6_scope_id = 0; - if (IN6_IS_SCOPE_LINKLOCAL(in6)) { + if (IN6_IS_SCOPE_EMBED(in6)) { /* * KAME assumption: link id == interface id */ @@ -438,6 +435,6 @@ void in6_clearscope(addr) struct in6_addr *addr; { - if (IN6_IS_SCOPE_LINKLOCAL(addr)) + if (IN6_IS_SCOPE_EMBED(addr)) addr->s6_addr16[1] = 0; } diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index d5a11518ade..4b3ec716eef 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.35 2006/06/18 11:47:46 pascoe Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.36 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -425,9 +425,9 @@ ip6_forward(m, srcrt) } else origifp = rt->rt_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; #if NPF > 0 diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 8a18ef8b167..3f7b5dc09be 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.68 2006/06/18 11:47:46 pascoe Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.69 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -321,24 +321,22 @@ ip6_input(m) /* drop packets if interface ID portion is already filled */ if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) { - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src) && + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src) && ip6->ip6_src.s6_addr16[1]) { ip6stat.ip6s_badscope++; goto bad; } - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst) && + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst) && ip6->ip6_dst.s6_addr16[1]) { ip6stat.ip6s_badscope++; goto bad; } } - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) - ip6->ip6_src.s6_addr16[1] - = htons(m->m_pkthdr.rcvif->if_index); - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] - = htons(m->m_pkthdr.rcvif->if_index); + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) + ip6->ip6_src.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index); + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) + ip6->ip6_dst.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index); /* * We use rt->rt_ifp to determine if the address is ours or not. @@ -939,7 +937,7 @@ ip6_savecontrol(in6p, mp, ip6, m) if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) { struct in6_pktinfo pi6; bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr)); - if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr)) + if (IN6_IS_SCOPE_EMBED(&pi6.ipi6_addr)) pi6.ipi6_addr.s6_addr16[1] = 0; pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif) ? m->m_pkthdr.rcvif->if_index diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 56b16093d90..3585cc24a3d 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -1025,7 +1025,7 @@ ip6_mforward(ip6, ifp, m) * Don't forward a packet with Hop limit of zero or one, * or a packet destined to a local-only group. */ - if (ip6->ip6_hlim <= 1 || IN6_IS_ADDR_MC_NODELOCAL(&ip6->ip6_dst) || + if (ip6->ip6_hlim <= 1 || IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) || IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) return 0; ip6->ip6_hlim--; 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); diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 348731c0435..ecb9160903a 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mld6.c,v 1.21 2006/05/27 23:40:27 claudio Exp $ */ +/* $OpenBSD: mld6.c,v 1.22 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: mld6.c,v 1.26 2001/02/16 14:50:35 itojun Exp $ */ /* @@ -167,7 +167,7 @@ mld6_stop_listening(in6m) if (in6m->in6m_state == MLD_IREPORTEDLAST && (!IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &mld_all_nodes_linklocal)) && - IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > IPV6_ADDR_SCOPE_NODELOCAL) + IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > IPV6_ADDR_SCOPE_INTFACELOCAL) mld6_sendpkt(in6m, MLD_LISTENER_DONE, &mld_all_routers_linklocal); } diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 3ad7136bcef..e3a1fe72926 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_nbr.c,v 1.41 2006/06/16 16:49:40 henning Exp $ */ +/* $OpenBSD: nd6_nbr.c,v 1.42 2006/11/17 01:11:23 itojun Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -141,7 +141,7 @@ nd6_ns_input(m, off, icmp6len) goto bad; } - if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) + if (IN6_IS_SCOPE_EMBED(&taddr6)) taddr6.s6_addr16[1] = htons(ifp->if_index); icmp6len -= sizeof(*nd_ns); @@ -470,7 +470,7 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, dad) nd_ns->nd_ns_reserved = 0; nd_ns->nd_ns_target = *taddr6; - if (IN6_IS_SCOPE_LINKLOCAL(&nd_ns->nd_ns_target)) + if (IN6_IS_SCOPE_EMBED(&nd_ns->nd_ns_target)) nd_ns->nd_ns_target.s6_addr16[1] = 0; /* @@ -577,7 +577,7 @@ nd6_na_input(m, off, icmp6len) is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0); is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0); - if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) + if (IN6_IS_SCOPE_EMBED(&taddr6)) taddr6.s6_addr16[1] = htons(ifp->if_index); if (IN6_IS_ADDR_MULTICAST(&taddr6)) { @@ -922,7 +922,7 @@ nd6_na_output(ifp, daddr6, taddr6, flags, tlladdr, sdl0) nd_na->nd_na_type = ND_NEIGHBOR_ADVERT; nd_na->nd_na_code = 0; nd_na->nd_na_target = *taddr6; - if (IN6_IS_SCOPE_LINKLOCAL(&nd_na->nd_na_target)) + if (IN6_IS_SCOPE_EMBED(&nd_na->nd_na_target)) nd_na->nd_na_target.s6_addr16[1] = 0; /* |