summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2004-06-17 09:43:56 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2004-06-17 09:43:56 +0000
commit1915df669e162068452fce1b0c30205e14129e20 (patch)
treece9b9564a8f11c51b6687eb82efdf2711daaabd8 /sys/netinet6
parente8cb4a62ede93e58004ccfa2792c2f15d6bdaa41 (diff)
correct multicast handling for special groups (like solicited node multicast).
from jinmei@kame
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c128
1 files changed, 56 insertions, 72 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index f8419140293..7d717f8b85c 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.c,v 1.55 2004/06/15 04:03:20 itojun Exp $ */
+/* $OpenBSD: in6.c,v 1.56 2004/06/17 09:43:55 itojun Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
@@ -796,7 +796,6 @@ in6_update_ifa(ifp, ifra, ia)
struct in6_ifaddr *oia;
struct sockaddr_in6 dst6;
struct in6_addrlifetime *lt;
- struct in6_multi *in6m;
struct in6_multi_mship *imm;
struct rtentry *rt;
@@ -1044,46 +1043,45 @@ in6_update_ifa(ifp, ifra, ia)
ia->ia6_flags |= IN6_IFF_TENTATIVE;
/*
+ * We are done if we have simply modified an existing address.
+ */
+ if (!hostIsNew)
+ return (error);
+
+ /*
* Beyond this point, we should call in6_purgeaddr upon an error,
* not just go to unlink.
*/
+ /* join necessary multiast groups */
if ((ifp->if_flags & IFF_MULTICAST) != 0) {
struct sockaddr_in6 mltaddr, mltmask;
#ifndef SCOPEDROUTING
u_int32_t zoneid = 0;
#endif
- if (hostIsNew) {
- /* join solicited multicast addr for new host id */
- struct sockaddr_in6 llsol;
-
- bzero(&llsol, sizeof(llsol));
- llsol.sin6_family = AF_INET6;
- llsol.sin6_len = sizeof(llsol);
- llsol.sin6_addr.s6_addr16[0] = htons(0xff02);
- llsol.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
- llsol.sin6_addr.s6_addr32[1] = 0;
- llsol.sin6_addr.s6_addr32[2] = htonl(1);
- llsol.sin6_addr.s6_addr32[3] =
- ifra->ifra_addr.sin6_addr.s6_addr32[3];
- llsol.sin6_addr.s6_addr8[12] = 0xff;
- IN6_LOOKUP_MULTI(llsol.sin6_addr, ifp, in6m);
- if (!in6m) {
- imm = in6_joingroup(ifp, &llsol.sin6_addr,
- &error);
- if (!imm) {
- nd6log((LOG_ERR, "in6_update_ifa: "
- "addmulti failed for %s on %s "
- "(errno=%d)\n",
- ip6_sprintf(&llsol.sin6_addr),
- ifp->if_xname, error));
- goto cleanup;
- }
- LIST_INSERT_HEAD(&ia->ia6_memberships, imm,
- i6mm_chain);
- }
+ /* join solicited multicast addr for new host id */
+ struct sockaddr_in6 llsol;
+
+ bzero(&llsol, sizeof(llsol));
+ llsol.sin6_family = AF_INET6;
+ llsol.sin6_len = sizeof(llsol);
+ llsol.sin6_addr.s6_addr16[0] = htons(0xff02);
+ llsol.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+ llsol.sin6_addr.s6_addr32[1] = 0;
+ llsol.sin6_addr.s6_addr32[2] = htonl(1);
+ llsol.sin6_addr.s6_addr32[3] =
+ ifra->ifra_addr.sin6_addr.s6_addr32[3];
+ llsol.sin6_addr.s6_addr8[12] = 0xff;
+ imm = in6_joingroup(ifp, &llsol.sin6_addr, &error);
+ if (!imm) {
+ nd6log((LOG_ERR, "in6_update_ifa: "
+ "addmulti failed for %s on %s (errno=%d)\n",
+ ip6_sprintf(&llsol.sin6_addr),
+ ifp->if_xname, error));
+ goto cleanup;
}
+ LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
bzero(&mltmask, sizeof(mltmask));
mltmask.sin6_len = sizeof(struct sockaddr_in6);
@@ -1140,39 +1138,31 @@ in6_update_ifa(ifp, ifra, ia)
#ifndef SCOPEDROUTING
mltaddr.sin6_scope_id = zoneid; /* XXX */
#endif
- IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
- if (!in6m) {
- 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);
+ 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);
/*
* join node information group address
*/
if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr) == 0) {
- IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
- if (!in6m) {
- 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));
- /* XXX not very fatal, go on... */
- } else {
- LIST_INSERT_HEAD(&ia->ia6_memberships,
- imm, i6mm_chain);
- }
+ 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));
+ /* XXX not very fatal, go on... */
+ } else {
+ LIST_INSERT_HEAD(&ia->ia6_memberships,
+ imm, i6mm_chain);
}
}
@@ -1212,21 +1202,15 @@ in6_update_ifa(ifp, ifra, ia)
} else {
RTFREE(rt);
}
- IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
- if (!in6m) {
- 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);
+ 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);
}
}