diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2004-06-17 09:43:56 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2004-06-17 09:43:56 +0000 |
commit | 1915df669e162068452fce1b0c30205e14129e20 (patch) | |
tree | ce9b9564a8f11c51b6687eb82efdf2711daaabd8 /sys/netinet6 | |
parent | e8cb4a62ede93e58004ccfa2792c2f15d6bdaa41 (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.c | 128 |
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); } } |