summaryrefslogtreecommitdiff
path: root/sys
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
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')
-rw-r--r--sys/netinet6/icmp6.c8
-rw-r--r--sys/netinet6/in6.c106
-rw-r--r--sys/netinet6/in6.h19
-rw-r--r--sys/netinet6/in6_cksum.c6
-rw-r--r--sys/netinet6/in6_src.c25
-rw-r--r--sys/netinet6/ip6_forward.c6
-rw-r--r--sys/netinet6/ip6_input.c18
-rw-r--r--sys/netinet6/ip6_mroute.c2
-rw-r--r--sys/netinet6/ip6_output.c69
-rw-r--r--sys/netinet6/mld6.c4
-rw-r--r--sys/netinet6/nd6_nbr.c10
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;
/*