currently carp uses a struct carp_if to hold an srp list head, which
is accessed by both if_carp in struct ifnet, and via the if input
handlers list.

this gets rid of some indirection by making if_carp itself the list
head, and makes accessing the list consistent by only using if_carp
to get to it.

after this i would like to restrict carp to using IFT_ETHER interfaces
instead of !IFT_CARP, and then i could move the srp list head into
struct arpcom.

ok?

Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.88
diff -u -p -r1.88 if_var.h
--- net/if_var.h        8 Jan 2018 23:05:21 -0000       1.88
+++ net/if_var.h        10 Jan 2018 10:28:53 -0000
@@ -134,7 +134,7 @@ struct ifnet {                              /* and the 
entries */
        caddr_t if_mcast6;              /* used by IPv6 multicast code */
        caddr_t if_pf_kif;              /* pf interface abstraction */
        union {
-               caddr_t carp_s;         /* carp structure (used by !carp ifs) */
+               struct srpl carp_s;     /* carp if list (used by !carp ifs) */
                struct ifnet *carp_d;   /* ptr to carpdev (used by carp ifs) */
        } if_carp_ptr;
 #define if_carp                if_carp_ptr.carp_s
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.536
diff -u -p -r1.536 if.c
--- net/if.c    9 Jan 2018 17:50:57 -0000       1.536
+++ net/if.c    10 Jan 2018 10:28:53 -0000
@@ -1007,7 +1007,7 @@ if_deactivate(struct ifnet *ifp)
 
 #if NCARP > 0
        /* Remove the interface from any carp group it is a part of.  */
-       if (ifp->if_carp && ifp->if_type != IFT_CARP)
+       if (ifp->if_type != IFT_CARP && !SRPL_EMPTY_LOCKED(&ifp->if_carp))
                carp_ifdetach(ifp);
 #endif
        NET_UNLOCK();
Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.300
diff -u -p -r1.300 if_bridge.c
--- net/if_bridge.c     9 Jan 2018 15:24:24 -0000       1.300
+++ net/if_bridge.c     10 Jan 2018 10:28:53 -0000
@@ -1108,8 +1108,8 @@ bridge_process(struct ifnet *ifp, struct
                ac = (struct arpcom *)ifl->ifp;
                if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0
 #if NCARP > 0
-                   || (ifl->ifp->if_carp && carp_ourether(ifl->ifp->if_carp,
-                       (u_int8_t *)&eh->ether_dhost) != NULL)
+                   || (!SRPL_EMPTY_LOCKED(&ifl->ifp->if_carp) &&
+                       !carp_ourether(ifl->ifp, eh->ether_dhost))
 #endif
                    ) {
                        if (srcifl->bif_flags & IFBIF_LEARNING)
@@ -1131,8 +1131,8 @@ bridge_process(struct ifnet *ifp, struct
                }
                if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0
 #if NCARP > 0
-                   || (ifl->ifp->if_carp && carp_ourether(ifl->ifp->if_carp,
-                       (u_int8_t *)&eh->ether_shost) != NULL)
+                   || (!SRPL_EMPTY_LOCKED(&ifl->ifp->if_carp) &&
+                       !carp_ourether(ifl->ifp, eh->ether_shost))
 #endif
                    ) {
                        m_freem(m);
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.322
diff -u -p -r1.322 ip_carp.c
--- netinet/ip_carp.c   10 Jan 2018 10:25:52 -0000      1.322
+++ netinet/ip_carp.c   10 Jan 2018 10:28:53 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_carp.c,v 1.322 2018/01/10 10:25:52 dlg Exp $       */
+/*     $OpenBSD: ip_carp.c,v 1.321 2018/01/09 15:24:24 bluhm Exp $     */
 
 /*
  * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -188,10 +188,6 @@ struct cpumem *carpcounters;
 
 int    carp_send_all_recur = 0;
 
-struct carp_if {
-       struct srpl vhif_vrs;
-};
-
 #define        CARP_LOG(l, sc, s)                                              
\
        do {                                                            \
                if (carp_opts[CARPCTL_LOG] >= l) {                      \
@@ -231,7 +227,7 @@ void        carp_timer_down(void *);
 void   carp_master_down(struct carp_vhost_entry *);
 int    carp_ioctl(struct ifnet *, u_long, caddr_t);
 int    carp_vhids_ioctl(struct carp_softc *, struct carpreq *);
-int    carp_check_dup_vhids(struct carp_softc *, struct carp_if *,
+int    carp_check_dup_vhids(struct carp_softc *, struct srpl *,
            struct carpreq *);
 void   carp_ifgroup_ioctl(struct ifnet *, u_long, caddr_t);
 void   carp_ifgattr_ioctl(struct ifnet *, u_long, caddr_t);
@@ -595,15 +591,15 @@ carp_proto_input_c(struct ifnet *ifp, st
        struct carp_softc *sc;
        struct carp_vhost_entry *vhe;
        struct timeval sc_tv, ch_tv;
-       struct carp_if *cif;
+       struct srpl *cif;
 
        if (ifp->if_type == IFT_CARP)
-               cif = (struct carp_if *)ifp->if_carpdev->if_carp;
+               cif = &ifp->if_carpdev->if_carp;
        else
-               cif = (struct carp_if *)ifp->if_carp;
+               cif = &ifp->if_carp;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs + carp_vhosts */
-       SRPL_FOREACH_LOCKED(sc, &cif->vhif_vrs, sc_list) {
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp + carp_vhosts */
+       SRPL_FOREACH_LOCKED(sc, cif, sc_list) {
                if (af == AF_INET &&
                    ismulti != IN_MULTICAST(sc->sc_peer.s_addr))
                        continue;
@@ -908,7 +904,7 @@ void
 carpdetach(struct carp_softc *sc)
 {
        struct ifnet *ifp0;
-       struct carp_if *cif;
+       struct srpl *cif;
 
        carp_del_all_timeouts(sc);
 
@@ -926,23 +922,19 @@ carpdetach(struct carp_softc *sc)
        if (ifp0 == NULL)
                return;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp */
 
-       cif = (struct carp_if *)ifp0->if_carp;
+       cif = &ifp0->if_carp;
 
        /* Restore previous input handler. */
-       if_ih_remove(ifp0, carp_input, cif);
+       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->vhif_vrs, sc,
-           carp_softc, sc_list);
-       if (SRPL_EMPTY_LOCKED(&cif->vhif_vrs)) {
+       SRPL_REMOVE_LOCKED(&carp_sc_rc, cif, sc, carp_softc, sc_list);
+       if (SRPL_EMPTY_LOCKED(cif))
                ifpromisc(ifp0, 0);
-               ifp0->if_carp = NULL;
-               free(cif, M_IFADDR, sizeof(*cif));
-       }
        sc->sc_carpdev = NULL;
 }
 
@@ -951,12 +943,12 @@ void
 carp_ifdetach(struct ifnet *ifp0)
 {
        struct carp_softc *sc, *nextsc;
-       struct carp_if *cif = (struct carp_if *)ifp0->if_carp;
+       struct srpl *cif = &ifp0->if_carp;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp */
 
-       SRPL_FOREACH_SAFE_LOCKED(sc, &cif->vhif_vrs, sc_list, nextsc)
-               carpdetach(sc); /* this can free cif */
+       SRPL_FOREACH_SAFE_LOCKED(sc, cif, sc_list, nextsc)
+               carpdetach(sc);
 }
 
 void
@@ -1000,20 +992,20 @@ void
 carp_send_ad_all(void)
 {
        struct ifnet *ifp0;
-       struct carp_if *cif;
+       struct srpl *cif;
        struct carp_softc *vh;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp */
 
        if (carp_send_all_recur > 0)
                return;
        ++carp_send_all_recur;
        TAILQ_FOREACH(ifp0, &ifnet, if_list) {
-               if (ifp0->if_carp == NULL || ifp0->if_type == IFT_CARP)
+               if (ifp0->if_type == IFT_CARP)
                        continue;
 
-               cif = (struct carp_if *)ifp0->if_carp;
-               SRPL_FOREACH_LOCKED(vh, &cif->vhif_vrs, sc_list) {
+               cif = &ifp0->if_carp;
+               SRPL_FOREACH_LOCKED(vh, cif, sc_list) {
                        if ((vh->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) ==
                            (IFF_UP|IFF_RUNNING)) {
                                carp_vhe_send_ad_all(vh);
@@ -1348,15 +1340,17 @@ carp_iamatch(struct ifnet *ifp)
        return (match);
 }
 
-struct ifnet *
-carp_ourether(void *v, u_int8_t *ena)
+int
+carp_ourether(struct ifnet *ifp, u_int8_t *ena)
 {
-       struct carp_if *cif = (struct carp_if *)v;
+       struct srpl *cif;
        struct carp_softc *vh;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs + carp_vhosts */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp + carp_vhosts */
+       KASSERT(ifp->if_type == IFT_CARP);
+       cif = &ifp->if_carp;
 
-       SRPL_FOREACH_LOCKED(vh, &cif->vhif_vrs, sc_list) {
+       SRPL_FOREACH_LOCKED(vh, cif, sc_list) {
                struct carp_vhost_entry *vhe;
                if ((vh->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
                    (IFF_UP|IFF_RUNNING))
@@ -1364,9 +1358,9 @@ carp_ourether(void *v, u_int8_t *ena)
                vhe = SRPL_FIRST_LOCKED(&vh->carp_vhosts);
                if ((vhe->state == MASTER || vh->sc_balancing >= CARP_BAL_IP) &&
                    !memcmp(ena, vh->sc_ac.ac_enaddr, ETHER_ADDR_LEN))
-                       return (&vh->sc_if);
+                       return (1);
        }
-       return (NULL);
+       return (0);
 }
 
 int
@@ -1389,7 +1383,7 @@ carp_input(struct ifnet *ifp0, struct mb
 {
        struct ether_header *eh;
        struct mbuf_list ml = MBUF_LIST_INITIALIZER();
-       struct carp_if *cif;
+       struct srpl *cif;
        struct carp_softc *sc;
        struct srp_ref sr;
 
@@ -1403,10 +1397,9 @@ carp_input(struct ifnet *ifp0, struct mb
 #endif
 
        eh = mtod(m, struct ether_header *);
-       cif = (struct carp_if *)cookie;
-       KASSERT(cif == (struct carp_if *)ifp0->if_carp);
+       cif = &ifp0->if_carp;
 
-       SRPL_FOREACH(sc, &sr, &cif->vhif_vrs, sc_list) {
+       SRPL_FOREACH(sc, &sr, cif, sc_list) {
                if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
                    (IFF_UP|IFF_RUNNING))
                        continue;
@@ -1442,7 +1435,7 @@ carp_input(struct ifnet *ifp0, struct mb
                 * XXX Should really check the list of multicast addresses
                 * for each CARP interface _before_ copying.
                 */
-               SRPL_FOREACH(sc, &sr, &cif->vhif_vrs, sc_list) {
+               SRPL_FOREACH(sc, &sr, cif, sc_list) {
                        struct mbuf *m0;
 
                        if (!(sc->sc_if.if_flags & IFF_UP))
@@ -1691,12 +1684,12 @@ carp_multicast_cleanup(struct carp_softc
 int
 carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp0)
 {
-       struct carp_if *cif, *ncif = NULL;
+       struct srpl *cif;
        struct carp_softc *vr, *last = NULL, *after = NULL;
        int myself = 0, error = 0;
 
        KASSERT(ifp0 != sc->sc_carpdev);
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp */
 
        if ((ifp0->if_flags & IFF_MULTICAST) == 0)
                return (EADDRNOTAVAIL);
@@ -1704,34 +1697,24 @@ carp_set_ifp(struct carp_softc *sc, stru
        if (ifp0->if_type == IFT_CARP)
                return (EINVAL);
 
-       if (ifp0->if_carp == NULL) {
-               ncif = malloc(sizeof(*cif), M_IFADDR, M_NOWAIT|M_ZERO);
-               if (ncif == NULL)
-                       return (ENOBUFS);
-               if ((error = ifpromisc(ifp0, 1))) {
-                       free(ncif, M_IFADDR, sizeof(*ncif));
+       cif = &ifp0->if_carp;
+       if (SRPL_EMPTY_LOCKED(cif)) {
+               if ((error = ifpromisc(ifp0, 1)))
                        return (error);
-               }
 
-               SRPL_INIT(&ncif->vhif_vrs);
-       } else {
-               cif = (struct carp_if *)ifp0->if_carp;
-               if (carp_check_dup_vhids(sc, cif, NULL))
-                       return (EINVAL);
-       }
+       } else if (carp_check_dup_vhids(sc, cif, NULL))
+               return (EINVAL);
 
        /* detach from old interface */
        if (sc->sc_carpdev != NULL)
                carpdetach(sc);
 
        /* attach carp interface to physical interface */
-       if (ncif != NULL)
-               ifp0->if_carp = (caddr_t)ncif;
        sc->sc_carpdev = ifp0;
        sc->sc_if.if_capabilities = ifp0->if_capabilities &
            IFCAP_CSUM_MASK;
-       cif = (struct carp_if *)ifp0->if_carp;
-       SRPL_FOREACH_LOCKED(vr, &cif->vhif_vrs, sc_list) {
+
+       SRPL_FOREACH_LOCKED(vr, cif, sc_list) {
                struct carp_vhost_entry *vrhead, *schead;
                last = vr;
 
@@ -1747,7 +1730,7 @@ carp_set_ifp(struct carp_softc *sc, stru
        if (!myself) {
                /* We're trying to keep things in order */
                if (last == NULL) {
-                       SRPL_INSERT_HEAD_LOCKED(&carp_sc_rc, &cif->vhif_vrs,
+                       SRPL_INSERT_HEAD_LOCKED(&carp_sc_rc, cif,
                            sc, sc_list);
                } else if (after == NULL) {
                        SRPL_INSERT_AFTER_LOCKED(&carp_sc_rc, last,
@@ -1765,7 +1748,7 @@ carp_set_ifp(struct carp_softc *sc, stru
            carp_carpdev_state, ifp0);
 
        /* Change input handler of the physical interface. */
-       if_ih_insert(ifp0, carp_input, cif);
+       if_ih_insert(ifp0, carp_input, NULL);
 
        carp_carpdev_state(ifp0);
 
@@ -2170,16 +2153,16 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
 }
 
 int
-carp_check_dup_vhids(struct carp_softc *sc, struct carp_if *cif,
+carp_check_dup_vhids(struct carp_softc *sc, struct srpl *cif,
     struct carpreq *carpr)
 {
        struct carp_softc *vr;
        struct carp_vhost_entry *vhe, *vhe0;
        int i;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs + carp_vhosts */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp + carp_vhosts */
 
-       SRPL_FOREACH_LOCKED(vr, &cif->vhif_vrs, sc_list) {
+       SRPL_FOREACH_LOCKED(vr, cif, sc_list) {
                if (vr == sc)
                        continue;
                SRPL_FOREACH_LOCKED(vhe, &vr->carp_vhosts, vhost_entries) {
@@ -2216,8 +2199,8 @@ carp_vhids_ioctl(struct carp_softc *sc, 
                taken_vhids[carpr->carpr_vhids[i]] = 1;
 
                if (sc->sc_carpdev) {
-                       struct carp_if *cif;
-                       cif = (struct carp_if *)sc->sc_carpdev->if_carp;
+                       struct srpl *cif;
+                       cif = &sc->sc_carpdev->if_carp;
                        if (carp_check_dup_vhids(sc, cif, carpr))
                                return (EINVAL);
                }
@@ -2482,18 +2465,18 @@ carp_group_demote_count(struct carp_soft
 void
 carp_carpdev_state(void *v)
 {
-       struct carp_if *cif;
+       struct srpl *cif;
        struct carp_softc *sc;
        struct ifnet *ifp0 = v;
 
        if (ifp0->if_type == IFT_CARP)
                return;
 
-       cif = (struct carp_if *)ifp0->if_carp;
+       cif = &ifp0->if_carp;
 
-       KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs */
+       KERNEL_ASSERT_LOCKED(); /* touching if_carp */
 
-       SRPL_FOREACH_LOCKED(sc, &cif->vhif_vrs, sc_list) {
+       SRPL_FOREACH_LOCKED(sc, cif, sc_list) {
                int suppressed = sc->sc_suppress;
 
                if (sc->sc_carpdev->if_link_state == LINK_STATE_DOWN ||
Index: netinet/ip_carp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.h,v
retrieving revision 1.44
diff -u -p -r1.44 ip_carp.h
--- netinet/ip_carp.h   23 Nov 2017 13:32:25 -0000      1.44
+++ netinet/ip_carp.h   10 Jan 2018 10:28:53 -0000
@@ -199,7 +199,7 @@ void                 carp_carpdev_state(void *);
 void            carp_group_demote_adj(struct ifnet *, int, char *);
 int             carp6_proto_input(struct mbuf **, int *, int, int);
 int             carp_iamatch(struct ifnet *);
-struct ifnet   *carp_ourether(void *, u_int8_t *);
+int             carp_ourether(struct ifnet *, u_int8_t *);
 int             carp_output(struct ifnet *, struct mbuf *, struct sockaddr *,
                     struct rtentry *);
 int             carp_sysctl(int *, u_int,  void *, size_t *, void *, size_t);

Reply via email to