have carp register detachhooks rather than get special handling in if.c

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

have carp register detachhooks rather than get special handling in if.c

David Gwynne-5
this makes carp less special by having it register detachhooks.
right now if.c treats it better than it needs to.

the diff shuffles establishment of the link status hook and the new
detachhook to make carp_set_ifp fail if the hooks cannot be allocated.

the following seems to work both before and after the diff:

        ifconfig vether1 create

        ifconfig -g carp carpdemote 20
        ifconfig carp0 create
        ifconfig carp0 carpdev vether1
        ifconfig carp0 vhid 66
        ifconfig carp0 pass `openssl rand -base64 12`
        ifconfig carp0 advskew 192
        ifconfig carp0 inet alias 100.64.0.1 netmask 255.255.255.0

        ifconfig vether1
        ifconfig carp0

        ifconfig vether1 destroy

        ifconfig carp0

tests?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.537
diff -u -p -r1.537 if.c
--- net/if.c 10 Jan 2018 23:50:39 -0000 1.537
+++ net/if.c 12 Jan 2018 01:50:44 -0000
@@ -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();
 }
 
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.325
diff -u -p -r1.325 ip_carp.c
--- netinet/ip_carp.c 12 Jan 2018 00:36:13 -0000 1.325
+++ netinet/ip_carp.c 12 Jan 2018 01:50:44 -0000
@@ -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 *,
 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);
@@ -901,8 +902,9 @@ carp_del_all_timeouts(struct carp_softc
 }
 
 void
-carpdetach(struct carp_softc *sc)
+carpdetach(void *arg)
 {
+ struct carp_softc *sc = arg;
  struct ifnet *ifp0;
  struct srpl *cif;
 
@@ -929,26 +931,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
@@ -1697,13 +1686,27 @@ carp_set_ifp(struct carp_softc *sc, stru
  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)
@@ -1744,15 +1747,19 @@ carp_set_ifp(struct carp_softc *sc, stru
  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
Index: netinet/ip_carp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.h,v
retrieving revision 1.45
diff -u -p -r1.45 ip_carp.h
--- netinet/ip_carp.h 10 Jan 2018 23:50:39 -0000 1.45
+++ netinet/ip_carp.h 12 Jan 2018 01:50:44 -0000
@@ -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 *);