summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_carp.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2018-01-12 23:47:25 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2018-01-12 23:47:25 +0000
commitf83556ac984bc07433a33f17732af5a010eba9dc (patch)
treedc717349d32ce687d469ddc53c17b90f6dc81a9c /sys/netinet/ip_carp.c
parentd7cd63481e4f3d4064a8cb1315cfd4c67a6b443c (diff)
have carp use standard detach hooks instead of getting special handling
if_deactivate looked for carp parent interfaces and called carp_ifdetach to have children interfaces unplug themselves. this diff has the carp interfaces register detach hooks on the parent instead. the effect is the same, but using the standard every other interface uses. while im here i shuffle the order the hooks carp_set_ifp are estabilshed so it will fail if they arent allocated. ok visa@ mpi@
Diffstat (limited to 'sys/netinet/ip_carp.c')
-rw-r--r--sys/netinet/ip_carp.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index bb9fa4220bd..08620190049 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.326 2018/01/12 23:29:37 dlg Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.327 2018/01/12 23:47:24 dlg Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -133,6 +133,7 @@ struct carp_softc {
#define sc_carpdev sc_ac.ac_if.if_carpdev
void *ah_cookie;
void *lh_cookie;
+ void *dh_cookie;
struct ip_moptions sc_imo;
#ifdef INET6
struct ip6_moptions sc_im6o;
@@ -215,7 +216,7 @@ int carp_proto_input_if(struct ifnet *, struct mbuf **, int *, int);
int carp6_proto_input_if(struct ifnet *, struct mbuf **, int *, int);
#endif
void carpattach(int);
-void carpdetach(struct carp_softc *);
+void carpdetach(void *);
int carp_prepare_ad(struct mbuf *, struct carp_vhost_entry *,
struct carp_header *);
void carp_send_ad_all(void);
@@ -908,8 +909,9 @@ carp_del_all_timeouts(struct carp_softc *sc)
}
void
-carpdetach(struct carp_softc *sc)
+carpdetach(void *arg)
{
+ struct carp_softc *sc = arg;
struct ifnet *ifp0;
struct srpl *cif;
@@ -936,26 +938,13 @@ carpdetach(struct carp_softc *sc)
/* Restore previous input handler. */
if_ih_remove(ifp0, carp_input, NULL);
- if (sc->lh_cookie != NULL)
- hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie);
-
SRPL_REMOVE_LOCKED(&carp_sc_rc, cif, sc, carp_softc, sc_list);
if (SRPL_EMPTY_LOCKED(cif))
ifpromisc(ifp0, 0);
sc->sc_carpdev = NULL;
-}
-
-/* Detach an interface from the carp. */
-void
-carp_ifdetach(struct ifnet *ifp0)
-{
- struct carp_softc *sc, *nextsc;
- struct srpl *cif = &ifp0->if_carp;
-
- KERNEL_ASSERT_LOCKED(); /* touching if_carp */
- SRPL_FOREACH_SAFE_LOCKED(sc, cif, sc_list, nextsc)
- carpdetach(sc);
+ hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie);
+ hook_disestablish(ifp0->if_detachhooks, sc->dh_cookie);
}
void
@@ -1704,13 +1693,27 @@ carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp0)
if (ifp0->if_type != IFT_ETHER)
return (EINVAL);
+ sc->dh_cookie = hook_establish(ifp0->if_detachhooks, 0,
+ carpdetach, sc);
+ if (sc->dh_cookie == NULL)
+ return (ENOMEM);
+
+ sc->lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1,
+ carp_carpdev_state, ifp0);
+ if (sc->lh_cookie == NULL) {
+ error = ENOMEM;
+ goto rm_dh;
+ }
+
cif = &ifp0->if_carp;
if (SRPL_EMPTY_LOCKED(cif)) {
if ((error = ifpromisc(ifp0, 1)))
- return (error);
+ goto rm_lh;
- } else if (carp_check_dup_vhids(sc, cif, NULL))
- return (EINVAL);
+ } else if (carp_check_dup_vhids(sc, cif, NULL)) {
+ error = EINVAL;
+ goto rm_lh;
+ }
/* detach from old interface */
if (sc->sc_carpdev != NULL)
@@ -1751,15 +1754,19 @@ carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp0)
sc->sc_if.if_flags |= IFF_UP;
carp_set_enaddr(sc);
- sc->lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1,
- carp_carpdev_state, ifp0);
-
/* Change input handler of the physical interface. */
if_ih_insert(ifp0, carp_input, NULL);
carp_carpdev_state(ifp0);
return (0);
+
+rm_lh:
+ hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie);
+rm_dh:
+ hook_disestablish(ifp0->if_detachhooks, sc->dh_cookie);
+
+ return (error);
}
void