summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-02-11 04:29:30 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-02-11 04:29:30 +0000
commit956f3fcde201a9c90d72e43880628076ac60b7c8 (patch)
tree7bb154fa5c12af97918e78ee119b91c0f1fe275c
parentdf3f3076da1ae706f56bb7bec444a3fc19165807 (diff)
Until carp(4) is converted to call ether_ifattach() and ether_ifdetach(),
reroll the loop to free its Ethernet multicast addresses when destroying an interface. Prevent a panic found the hard way by phessler@ ok henning@, pelikan@, phessler@
-rw-r--r--sys/netinet/ip_carp.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index d22fa686d54..db09a8e1c5d 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.245 2015/01/21 11:20:48 mpi Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.246 2015/02/11 04:29:29 mpi Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -806,9 +806,19 @@ int
carp_clone_destroy(struct ifnet *ifp)
{
struct carp_softc *sc = ifp->if_softc;
+ struct arpcom *ac = (struct arpcom *)ifp;
+ struct ether_multi *enm;
carpdetach(sc);
- ether_ifdetach(ifp);
+
+ /* XXX should be converted to ether_ifattach() and ether_ifdetach() */
+ for (enm = LIST_FIRST(&ac->ac_multiaddrs);
+ enm != NULL;
+ enm = LIST_FIRST(&ac->ac_multiaddrs)) {
+ LIST_REMOVE(enm, enm_list);
+ free(enm, M_IFMADDR, 0);
+ }
+
if_detach(ifp);
carp_destroy_vhosts(ifp->if_softc);
free(sc->sc_imo.imo_membership, M_IPMOPTS, 0);