Re: carp(4) is out
On 23/05/15(Sat) 19:08, mxb wrote: [...] so far no problems. Here's an updated version to match recent changes. It also includes a nitpick fix from bluhm@. Tests and oks welcome. Index: net/if_ethersubr.c === RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.201 diff -u -p -r1.201 if_ethersubr.c --- net/if_ethersubr.c 26 May 2015 11:39:07 - 1.201 +++ net/if_ethersubr.c 28 May 2015 08:05:02 - @@ -490,18 +490,6 @@ ether_input(struct mbuf *m) } #endif -#if NCARP 0 - if (ifp-if_carp) { - if (ifp-if_type != IFT_CARP (carp_input(ifp, eh, m) == 0)) - return (1); - /* clear mcast if received on a carp IP balanced address */ - else if (ifp-if_type == IFT_CARP - m-m_flags (M_BCAST|M_MCAST) - carp_our_mcastaddr(ifp, (u_int8_t *)eh-ether_dhost)) - m-m_flags = ~(M_BCAST|M_MCAST); - } -#endif /* NCARP 0 */ - ac = (struct arpcom *)ifp; /* Index: netinet/ip_carp.c === RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.257 diff -u -p -r1.257 ip_carp.c --- netinet/ip_carp.c 21 May 2015 09:17:53 - 1.257 +++ netinet/ip_carp.c 28 May 2015 09:06:00 - @@ -120,6 +120,7 @@ struct carp_softc { #definesc_carpdev sc_ac.ac_if.if_carpdev void *ah_cookie; void *lh_cookie; + struct ifih *sc_ifih; struct ip_moptions sc_imo; #ifdef INET6 struct ip6_moptions sc_im6o; @@ -193,6 +194,7 @@ voidcarp_hmac_generate(struct carp_vhos unsigned char *, u_int8_t); intcarp_hmac_verify(struct carp_vhost_entry *, u_int32_t *, unsigned char *); +intcarp_input(struct mbuf *); void carp_proto_input_c(struct mbuf *, struct carp_header *, int, sa_family_t); void carpattach(int); @@ -824,6 +826,7 @@ carp_del_all_timeouts(struct carp_softc void carpdetach(struct carp_softc *sc) { + struct ifnet *ifp; struct carp_if *cif; int s; @@ -839,20 +842,29 @@ carpdetach(struct carp_softc *sc) carp_setrun_all(sc, 0); carp_multicast_cleanup(sc); - s = splnet(); if (sc-ah_cookie != NULL) hook_disestablish(sc-sc_if.if_addrhooks, sc-ah_cookie); - if (sc-sc_carpdev != NULL) { - if (sc-lh_cookie != NULL) - hook_disestablish(sc-sc_carpdev-if_linkstatehooks, - sc-lh_cookie); - cif = (struct carp_if *)sc-sc_carpdev-if_carp; - TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); - if (!--cif-vhif_nvrs) { - ifpromisc(sc-sc_carpdev, 0); - sc-sc_carpdev-if_carp = NULL; - free(cif, M_IFADDR, sizeof(*cif)); - } + + ifp = sc-sc_carpdev; + if (ifp == NULL) + return; + + s = splnet(); + /* Restore previous input handler. */ + if (--sc-sc_ifih-ifih_refcnt == 0) { + SLIST_REMOVE(ifp-if_inputs, sc-sc_ifih, ifih, ifih_next); + free(sc-sc_ifih, M_DEVBUF, sizeof(*sc-sc_ifih)); + } + + if (sc-lh_cookie != NULL) + hook_disestablish(ifp-if_linkstatehooks, + sc-lh_cookie); + cif = (struct carp_if *)ifp-if_carp; + TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); + if (!--cif-vhif_nvrs) { + ifpromisc(ifp, 0); + ifp-if_carp = NULL; + free(cif, M_IFADDR, sizeof(*cif)); } sc-sc_carpdev = NULL; splx(s); @@ -1403,27 +1415,21 @@ carp_get_srclladdr(struct ifnet *ifp, u_ } int -carp_our_mcastaddr(struct ifnet *ifp, u_int8_t *d_enaddr) -{ - struct carp_softc *sc = ifp-if_softc; - - if (sc-sc_balancing != CARP_BAL_IP) - return (0); - - return (!memcmp(sc-sc_ac.ac_enaddr, d_enaddr, ETHER_ADDR_LEN)); -} - - -int -carp_input(struct ifnet *ifp0, struct ether_header *eh0, struct mbuf *m) +carp_input(struct mbuf *m) { + struct carp_softc *sc; struct ether_header *eh; - struct carp_if *cif = (struct carp_if *)ifp0-if_carp; - struct ifnet *ifp; + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); + struct carp_if *cif; + struct ifnet *ifp0, *ifp; - ifp = carp_ourether(cif, eh0-ether_dhost); - if (ifp == NULL (m-m_flags (M_BCAST|M_MCAST)) == 0) - return (1); + ifp0 = m-m_pkthdr.rcvif; + eh = mtod(m, struct ether_header *); + cif = (struct carp_if *)ifp0-if_carp; + + ifp = carp_ourether(cif, eh-ether_dhost); + if (ifp == NULL !ETHER_IS_MULTICAST(eh-ether_dhost)) + return (0); if (ifp == NULL) { struct carp_softc *vh; @@ -1439,41 +1445,33 @@
Re: carp(4) is out
Hey, so far no problems. //mxb On 22 maj 2015, at 16:05, Martin Pieuchot m...@openbsd.org wrote: Let's take carp(4) out of ether_input(). This is quite similar to what happened to trunk(4) and vlan(4). I appreciate tests of any kind, reviews and oks. Index: net/if_ethersubr.c === RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.199 diff -u -p -r1.199 if_ethersubr.c --- net/if_ethersubr.c19 May 2015 11:09:24 - 1.199 +++ net/if_ethersubr.c22 May 2015 13:39:44 - @@ -502,18 +502,6 @@ ether_input(struct mbuf *m, void *hdr) } #endif -#if NCARP 0 - if (ifp-if_carp) { - if (ifp-if_type != IFT_CARP (carp_input(ifp, eh, m) == 0)) - return (1); - /* clear mcast if received on a carp IP balanced address */ - else if (ifp-if_type == IFT_CARP - m-m_flags (M_BCAST|M_MCAST) - carp_our_mcastaddr(ifp, (u_int8_t *)eh-ether_dhost)) - m-m_flags = ~(M_BCAST|M_MCAST); - } -#endif /* NCARP 0 */ - ac = (struct arpcom *)ifp; /* Index: netinet/ip_carp.c === RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.257 diff -u -p -r1.257 ip_carp.c --- netinet/ip_carp.c 21 May 2015 09:17:53 - 1.257 +++ netinet/ip_carp.c 22 May 2015 13:54:30 - @@ -120,6 +120,7 @@ struct carp_softc { #define sc_carpdev sc_ac.ac_if.if_carpdev void *ah_cookie; void *lh_cookie; + struct ifih *sc_ifih; struct ip_moptions sc_imo; #ifdef INET6 struct ip6_moptions sc_im6o; @@ -193,6 +194,7 @@ void carp_hmac_generate(struct carp_vhos unsigned char *, u_int8_t); int carp_hmac_verify(struct carp_vhost_entry *, u_int32_t *, unsigned char *); +int carp_input(struct mbuf *, void *); void carp_proto_input_c(struct mbuf *, struct carp_header *, int, sa_family_t); void carpattach(int); @@ -824,6 +826,7 @@ carp_del_all_timeouts(struct carp_softc void carpdetach(struct carp_softc *sc) { + struct ifnet *ifp; struct carp_if *cif; int s; @@ -839,20 +842,29 @@ carpdetach(struct carp_softc *sc) carp_setrun_all(sc, 0); carp_multicast_cleanup(sc); - s = splnet(); if (sc-ah_cookie != NULL) hook_disestablish(sc-sc_if.if_addrhooks, sc-ah_cookie); - if (sc-sc_carpdev != NULL) { - if (sc-lh_cookie != NULL) - hook_disestablish(sc-sc_carpdev-if_linkstatehooks, - sc-lh_cookie); - cif = (struct carp_if *)sc-sc_carpdev-if_carp; - TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); - if (!--cif-vhif_nvrs) { - ifpromisc(sc-sc_carpdev, 0); - sc-sc_carpdev-if_carp = NULL; - free(cif, M_IFADDR, sizeof(*cif)); - } + + ifp = sc-sc_carpdev; + if (ifp == NULL) + return; + + s = splnet(); + /* Restore previous input handler. */ + if (--sc-sc_ifih-ifih_refcnt == 0) { + SLIST_REMOVE(ifp-if_inputs, sc-sc_ifih, ifih, ifih_next); + free(sc-sc_ifih, M_DEVBUF, sizeof(*sc-sc_ifih)); + } + + if (sc-lh_cookie != NULL) + hook_disestablish(ifp-if_linkstatehooks, + sc-lh_cookie); + cif = (struct carp_if *)ifp-if_carp; + TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); + if (!--cif-vhif_nvrs) { + ifpromisc(ifp, 0); + ifp-if_carp = NULL; + free(cif, M_IFADDR, sizeof(*cif)); } sc-sc_carpdev = NULL; splx(s); @@ -1403,27 +1415,21 @@ carp_get_srclladdr(struct ifnet *ifp, u_ } int -carp_our_mcastaddr(struct ifnet *ifp, u_int8_t *d_enaddr) -{ - struct carp_softc *sc = ifp-if_softc; - - if (sc-sc_balancing != CARP_BAL_IP) - return (0); - - return (!memcmp(sc-sc_ac.ac_enaddr, d_enaddr, ETHER_ADDR_LEN)); -} - - -int -carp_input(struct ifnet *ifp0, struct ether_header *eh0, struct mbuf *m) +carp_input(struct mbuf *m, void *hdr) { + struct carp_softc *sc; struct ether_header *eh; - struct carp_if *cif = (struct carp_if *)ifp0-if_carp; - struct ifnet *ifp; + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); + struct carp_if *cif; + struct ifnet *ifp0, *ifp; - ifp = carp_ourether(cif, eh0-ether_dhost); - if (ifp == NULL (m-m_flags (M_BCAST|M_MCAST)) == 0) - return (1); + ifp0 = m-m_pkthdr.rcvif; + eh = mtod(m, struct ether_header *); + cif = (struct carp_if *)ifp0-if_carp; + + ifp = carp_ourether(cif, eh-ether_dhost); + if (ifp == NULL !ETHER_IS_MULTICAST(eh-ether_dhost)) + return (0); if (ifp
carp(4) is out
Let's take carp(4) out of ether_input(). This is quite similar to what happened to trunk(4) and vlan(4). I appreciate tests of any kind, reviews and oks. Index: net/if_ethersubr.c === RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.199 diff -u -p -r1.199 if_ethersubr.c --- net/if_ethersubr.c 19 May 2015 11:09:24 - 1.199 +++ net/if_ethersubr.c 22 May 2015 13:39:44 - @@ -502,18 +502,6 @@ ether_input(struct mbuf *m, void *hdr) } #endif -#if NCARP 0 - if (ifp-if_carp) { - if (ifp-if_type != IFT_CARP (carp_input(ifp, eh, m) == 0)) - return (1); - /* clear mcast if received on a carp IP balanced address */ - else if (ifp-if_type == IFT_CARP - m-m_flags (M_BCAST|M_MCAST) - carp_our_mcastaddr(ifp, (u_int8_t *)eh-ether_dhost)) - m-m_flags = ~(M_BCAST|M_MCAST); - } -#endif /* NCARP 0 */ - ac = (struct arpcom *)ifp; /* Index: netinet/ip_carp.c === RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.257 diff -u -p -r1.257 ip_carp.c --- netinet/ip_carp.c 21 May 2015 09:17:53 - 1.257 +++ netinet/ip_carp.c 22 May 2015 13:54:30 - @@ -120,6 +120,7 @@ struct carp_softc { #definesc_carpdev sc_ac.ac_if.if_carpdev void *ah_cookie; void *lh_cookie; + struct ifih *sc_ifih; struct ip_moptions sc_imo; #ifdef INET6 struct ip6_moptions sc_im6o; @@ -193,6 +194,7 @@ voidcarp_hmac_generate(struct carp_vhos unsigned char *, u_int8_t); intcarp_hmac_verify(struct carp_vhost_entry *, u_int32_t *, unsigned char *); +intcarp_input(struct mbuf *, void *); void carp_proto_input_c(struct mbuf *, struct carp_header *, int, sa_family_t); void carpattach(int); @@ -824,6 +826,7 @@ carp_del_all_timeouts(struct carp_softc void carpdetach(struct carp_softc *sc) { + struct ifnet *ifp; struct carp_if *cif; int s; @@ -839,20 +842,29 @@ carpdetach(struct carp_softc *sc) carp_setrun_all(sc, 0); carp_multicast_cleanup(sc); - s = splnet(); if (sc-ah_cookie != NULL) hook_disestablish(sc-sc_if.if_addrhooks, sc-ah_cookie); - if (sc-sc_carpdev != NULL) { - if (sc-lh_cookie != NULL) - hook_disestablish(sc-sc_carpdev-if_linkstatehooks, - sc-lh_cookie); - cif = (struct carp_if *)sc-sc_carpdev-if_carp; - TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); - if (!--cif-vhif_nvrs) { - ifpromisc(sc-sc_carpdev, 0); - sc-sc_carpdev-if_carp = NULL; - free(cif, M_IFADDR, sizeof(*cif)); - } + + ifp = sc-sc_carpdev; + if (ifp == NULL) + return; + + s = splnet(); + /* Restore previous input handler. */ + if (--sc-sc_ifih-ifih_refcnt == 0) { + SLIST_REMOVE(ifp-if_inputs, sc-sc_ifih, ifih, ifih_next); + free(sc-sc_ifih, M_DEVBUF, sizeof(*sc-sc_ifih)); + } + + if (sc-lh_cookie != NULL) + hook_disestablish(ifp-if_linkstatehooks, + sc-lh_cookie); + cif = (struct carp_if *)ifp-if_carp; + TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); + if (!--cif-vhif_nvrs) { + ifpromisc(ifp, 0); + ifp-if_carp = NULL; + free(cif, M_IFADDR, sizeof(*cif)); } sc-sc_carpdev = NULL; splx(s); @@ -1403,27 +1415,21 @@ carp_get_srclladdr(struct ifnet *ifp, u_ } int -carp_our_mcastaddr(struct ifnet *ifp, u_int8_t *d_enaddr) -{ - struct carp_softc *sc = ifp-if_softc; - - if (sc-sc_balancing != CARP_BAL_IP) - return (0); - - return (!memcmp(sc-sc_ac.ac_enaddr, d_enaddr, ETHER_ADDR_LEN)); -} - - -int -carp_input(struct ifnet *ifp0, struct ether_header *eh0, struct mbuf *m) +carp_input(struct mbuf *m, void *hdr) { + struct carp_softc *sc; struct ether_header *eh; - struct carp_if *cif = (struct carp_if *)ifp0-if_carp; - struct ifnet *ifp; + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); + struct carp_if *cif; + struct ifnet *ifp0, *ifp; - ifp = carp_ourether(cif, eh0-ether_dhost); - if (ifp == NULL (m-m_flags (M_BCAST|M_MCAST)) == 0) - return (1); + ifp0 = m-m_pkthdr.rcvif; + eh = mtod(m, struct ether_header *); + cif = (struct carp_if *)ifp0-if_carp; + + ifp = carp_ourether(cif, eh-ether_dhost); + if (ifp == NULL !ETHER_IS_MULTICAST(eh-ether_dhost)) + return (0); if (ifp == NULL) { struct carp_softc *vh; @@ -1439,41 +1445,33
carp(4) is out
Let's take carp(4) out of ether_input(). This is quite similar to what happened to trunk(4) and vlan(4). I appreciate tests of any kind, reviews and oks. Index: net/if_ethersubr.c === RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.199 diff -u -p -r1.199 if_ethersubr.c --- net/if_ethersubr.c 19 May 2015 11:09:24 - 1.199 +++ net/if_ethersubr.c 22 May 2015 13:39:44 - @@ -502,18 +502,6 @@ ether_input(struct mbuf *m, void *hdr) } #endif -#if NCARP 0 - if (ifp-if_carp) { - if (ifp-if_type != IFT_CARP (carp_input(ifp, eh, m) == 0)) - return (1); - /* clear mcast if received on a carp IP balanced address */ - else if (ifp-if_type == IFT_CARP - m-m_flags (M_BCAST|M_MCAST) - carp_our_mcastaddr(ifp, (u_int8_t *)eh-ether_dhost)) - m-m_flags = ~(M_BCAST|M_MCAST); - } -#endif /* NCARP 0 */ - ac = (struct arpcom *)ifp; /* Index: netinet/ip_carp.c === RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.257 diff -u -p -r1.257 ip_carp.c --- netinet/ip_carp.c 21 May 2015 09:17:53 - 1.257 +++ netinet/ip_carp.c 22 May 2015 13:39:44 - @@ -120,6 +120,7 @@ struct carp_softc { #definesc_carpdev sc_ac.ac_if.if_carpdev void *ah_cookie; void *lh_cookie; + struct ifih *sc_ifih; struct ip_moptions sc_imo; #ifdef INET6 struct ip6_moptions sc_im6o; @@ -193,6 +194,7 @@ voidcarp_hmac_generate(struct carp_vhos unsigned char *, u_int8_t); intcarp_hmac_verify(struct carp_vhost_entry *, u_int32_t *, unsigned char *); +intcarp_input(struct mbuf *); void carp_proto_input_c(struct mbuf *, struct carp_header *, int, sa_family_t); void carpattach(int); @@ -824,6 +826,7 @@ carp_del_all_timeouts(struct carp_softc void carpdetach(struct carp_softc *sc) { + struct ifnet *ifp; struct carp_if *cif; int s; @@ -839,20 +842,29 @@ carpdetach(struct carp_softc *sc) carp_setrun_all(sc, 0); carp_multicast_cleanup(sc); - s = splnet(); if (sc-ah_cookie != NULL) hook_disestablish(sc-sc_if.if_addrhooks, sc-ah_cookie); - if (sc-sc_carpdev != NULL) { - if (sc-lh_cookie != NULL) - hook_disestablish(sc-sc_carpdev-if_linkstatehooks, - sc-lh_cookie); - cif = (struct carp_if *)sc-sc_carpdev-if_carp; - TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); - if (!--cif-vhif_nvrs) { - ifpromisc(sc-sc_carpdev, 0); - sc-sc_carpdev-if_carp = NULL; - free(cif, M_IFADDR, sizeof(*cif)); - } + + ifp = sc-sc_carpdev; + if (ifp == NULL) + return; + + s = splnet(); + /* Restore previous input handler. */ + if (--sc-sc_ifih-ifih_refcnt == 0) { + SLIST_REMOVE(ifp-if_inputs, sc-sc_ifih, ifih, ifih_next); + free(sc-sc_ifih, M_DEVBUF, sizeof(*sc-sc_ifih)); + } + + if (sc-lh_cookie != NULL) + hook_disestablish(ifp-if_linkstatehooks, + sc-lh_cookie); + cif = (struct carp_if *)ifp-if_carp; + TAILQ_REMOVE(cif-vhif_vrs, sc, sc_list); + if (!--cif-vhif_nvrs) { + ifpromisc(ifp, 0); + ifp-if_carp = NULL; + free(cif, M_IFADDR, sizeof(*cif)); } sc-sc_carpdev = NULL; splx(s); @@ -1403,27 +1415,21 @@ carp_get_srclladdr(struct ifnet *ifp, u_ } int -carp_our_mcastaddr(struct ifnet *ifp, u_int8_t *d_enaddr) -{ - struct carp_softc *sc = ifp-if_softc; - - if (sc-sc_balancing != CARP_BAL_IP) - return (0); - - return (!memcmp(sc-sc_ac.ac_enaddr, d_enaddr, ETHER_ADDR_LEN)); -} - - -int -carp_input(struct ifnet *ifp0, struct ether_header *eh0, struct mbuf *m) +carp_input(struct mbuf *m) { + struct carp_softc *sc; struct ether_header *eh; - struct carp_if *cif = (struct carp_if *)ifp0-if_carp; - struct ifnet *ifp; + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); + struct carp_if *cif; + struct ifnet *ifp0, *ifp; - ifp = carp_ourether(cif, eh0-ether_dhost); - if (ifp == NULL (m-m_flags (M_BCAST|M_MCAST)) == 0) - return (1); + ifp0 = m-m_pkthdr.rcvif; + eh = mtod(m, struct ether_header *); + cif = (struct carp_if *)ifp0-if_carp; + + ifp = carp_ourether(cif, eh-ether_dhost); + if (ifp == NULL !ETHER_IS_MULTICAST(eh-ether_dhost)) + return (0); if (ifp == NULL) { struct carp_softc *vh; @@ -1439,41 +1445,33 @@ carp_input