From 9a2277444263328168b36f5012168ceacf898972 Mon Sep 17 00:00:00 2001 From: dlg Date: Fri, 12 Jan 2018 23:47:24 +0000 Subject: [PATCH] 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@ --- sys/net/if.c | 7 +----- sys/netinet/ip_carp.c | 55 ++++++++++++++++++++++++------------------- 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 *); -- 2.20.1