diff options
-rw-r--r-- | sys/net/if.c | 7 | ||||
-rw-r--r-- | sys/netinet/ip_carp.c | 55 | ||||
-rw-r--r-- | sys/netinet/ip_carp.h | 3 |
3 files changed, 33 insertions, 32 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index bc3700c1e3f..bc63a2c221b 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.537 2018/01/10 23:50:39 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.538 2018/01/12 23:47:24 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -1005,11 +1005,6 @@ if_deactivate(struct ifnet *ifp) */ dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE); -#if NCARP > 0 - /* Remove the interface from any carp group it is a part of. */ - if (ifp->if_type != IFT_CARP && !SRPL_EMPTY_LOCKED(&ifp->if_carp)) - carp_ifdetach(ifp); -#endif NET_UNLOCK(); } 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 diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h index 3fb10f5b278..0b78c8cd528 100644 --- a/sys/netinet/ip_carp.h +++ b/sys/netinet/ip_carp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.h,v 1.45 2018/01/10 23:50:39 dlg Exp $ */ +/* $OpenBSD: ip_carp.h,v 1.46 2018/01/12 23:47:24 dlg Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -193,7 +193,6 @@ carpstat_inc(enum carpstat_counters c) counters_inc(carpcounters, c); } -void carp_ifdetach (struct ifnet *); int carp_proto_input(struct mbuf **, int *, int, int); void carp_carpdev_state(void *); void carp_group_demote_adj(struct ifnet *, int, char *); |