diff options
Diffstat (limited to 'sys/netinet6/in6.c')
-rw-r--r-- | sys/netinet6/in6.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 144bc1be623..7f3f526445d 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.9 2000/02/02 17:01:50 itojun Exp $ */ +/* $OpenBSD: in6.c,v 1.10 2000/02/02 17:16:52 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -1280,6 +1280,8 @@ in6_savemkludge(oia) for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){ next = in6m->in6m_entry.le_next; + IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ + in6m->in6m_ia = NULL; LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry); } @@ -1310,6 +1312,8 @@ in6_restoremkludge(ia, ifp) for (in6m = mk->mk_head.lh_first; in6m; in6m = next){ next = in6m->in6m_entry.le_next; + in6m->in6m_ia = ia; + ia->ia_ifa.ifa_refcnt++; LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry); } @@ -1320,6 +1324,29 @@ in6_restoremkludge(ia, ifp) } } +void +in6_purgemkludge(ifp) + struct ifnet *ifp; +{ + struct multi6_kludge *mk; + struct in6_multi *in6m, *next; + + for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) { + if (mk->mk_ifp != ifp) + continue; + + for (in6m = mk->mk_head.lh_first; in6m; in6m = next) { + next = in6m->in6m_entry.le_next; + LIST_REMOVE(in6m, in6m_entry); + in6_delmulti(in6m); + in6m = NULL; + } + LIST_REMOVE(mk, mk_entry); + free(mk, M_IPMADDR); + break; + } +} + /* * Add an address to the list of IP6 multicast addresses for a * given interface. @@ -1421,7 +1448,8 @@ in6_delmulti(in6m) * Unlink from list. */ LIST_REMOVE(in6m, in6m_entry); - IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ + if (in6m->in6m_ia) + IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ /* * Notify the network driver to update its multicast |