summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6_ifattach.c
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2009-04-29 19:19:13 +0000
committerbms <bms@FreeBSD.org>2009-04-29 19:19:13 +0000
commit32a71137f08bc028578417de36a241d7e6011f58 (patch)
tree51d9a006ee48417962ce45f044b7e5603910fe13 /sys/netinet6/in6_ifattach.c
parent51a4d1c4a3d279a3638c0b40f351aa93f965c7df (diff)
downloadFreeBSD-src-32a71137f08bc028578417de36a241d7e6011f58.zip
FreeBSD-src-32a71137f08bc028578417de36a241d7e6011f58.tar.gz
Bite the bullet, and make the IPv6 SSM and MLDv2 mega-commit:
import from p4 bms_netdev. Summary of changes: * Connect netinet6/in6_mcast.c to build. The legacy KAME KPIs are mostly preserved. * Eliminate now dead code from ip6_output.c. Don't do mbuf bingo, we are not going to do RFC 2292 style CMSG tricks for multicast options as they are not required by any current IPv6 normative reference. * Refactor transports (UDP, raw_ip6) to do own mcast filtering. SCTP, TCP unaffected by this change. * Add ip6_msource, in6_msource structs to in6_var.h. * Hookup mld_ifinfo state to in6_ifextra, allocate from domifattach path. * Eliminate IN6_LOOKUP_MULTI(), it is no longer referenced. Kernel consumers which need this should use in6m_lookup(). * Refactor IPv6 socket group memberships to use a vector (like IPv4). * Update ifmcstat(8) for IPv6 SSM. * Add witness lock order for IN6_MULTI_LOCK. * Move IN6_MULTI_LOCK out of lower ip6_output()/ip6_input() paths. * Introduce IP6STAT_ADD/SUB/INC/DEC as per rwatson's IPv4 cleanup. * Update carp(4) for new IPv6 SSM KPIs. * Virtualize ip6_mrouter socket. Changes mostly localized to IPv6 MROUTING. * Don't do a local group lookup in MROUTING. * Kill unused KAME prototypes in6_purgemkludge(), in6_restoremkludge(). * Preserve KAME DAD timer jitter behaviour in MLDv1 compatibility mode. * Bump __FreeBSD_version to 800084. * Update UPDATING. NOTE WELL: * This code hasn't been tested against real MLDv2 queriers (yet), although the on-wire protocol has been verified in Wireshark. * There are a few unresolved issues in the socket layer APIs to do with scope ID propagation. * There is a LOR present in ip6_output()'s use of in6_setscope() which needs to be resolved. See comments in mld6.c. This is believed to be benign and can't be avoided for the moment without re-introducing an indirect netisr. This work was mostly derived from the IGMPv3 implementation, and has been sponsored by a third party.
Diffstat (limited to 'sys/netinet6/in6_ifattach.c')
-rw-r--r--sys/netinet6/in6_ifattach.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 80b6d6b..077014e 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/in6_ifattach.h>
#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
+#include <netinet6/mld6_var.h>
#include <netinet6/scope6_var.h>
#include <netinet6/vinet6.h>
@@ -918,11 +919,35 @@ in6_tmpaddrtimer(void *ignored_arg)
static void
in6_purgemaddrs(struct ifnet *ifp)
{
- struct in6_multi *in6m;
- struct in6_multi *oin6m;
+ INIT_VNET_INET6(ifp->if_vnet);
+ LIST_HEAD(,in6_multi) purgeinms;
+ struct in6_multi *inm, *tinm;
+ struct ifmultiaddr *ifma;
+
+ LIST_INIT(&purgeinms);
+ IN6_MULTI_LOCK();
+
+ /*
+ * Extract list of in6_multi associated with the detaching ifp
+ * which the PF_INET6 layer is about to release.
+ * We need to do this as IF_ADDR_LOCK() may be re-acquired
+ * by code further down.
+ */
+ IF_ADDR_LOCK(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_INET6 ||
+ ifma->ifma_protospec == NULL)
+ continue;
+ inm = (struct in6_multi *)ifma->ifma_protospec;
+ LIST_INSERT_HEAD(&purgeinms, inm, in6m_entry);
+ }
+ IF_ADDR_UNLOCK(ifp);
- LIST_FOREACH_SAFE(in6m, &in6_multihead, in6m_entry, oin6m) {
- if (in6m->in6m_ifp == ifp)
- in6_delmulti(in6m);
+ LIST_FOREACH_SAFE(inm, &purgeinms, in6m_entry, tinm) {
+ LIST_REMOVE(inm, in6m_entry);
+ in6m_release_locked(inm);
}
+ mld_ifdetach(ifp);
+
+ IN6_MULTI_UNLOCK();
}
OpenPOWER on IntegriCloud