From 9368aa5260205de56b99271d31937b9ad95e1a16 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 8 Jun 2015 13:40:48 +0000 Subject: [PATCH] Move carp-related logic from ether_output() into carp_start(). ok sthen@, phessler@ --- sys/net/if_ethersubr.c | 37 +++------------------- sys/netinet/ip_carp.c | 70 +++++++++++++++++++++++++++--------------- sys/netinet/ip_carp.h | 3 +- 3 files changed, 52 insertions(+), 58 deletions(-) diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 468a287cff6..842dbe0c882 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.202 2015/06/02 09:38:24 mpi Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.203 2015/06/08 13:40:48 mpi Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -113,11 +113,6 @@ didn't get a copy, you may request one from . #include #endif /* NVLAN > 0 */ -#include "carp.h" -#if NCARP > 0 -#include -#endif - #include "pppoe.h" #if NPPPOE > 0 #include @@ -243,18 +238,17 @@ ether_addheader(struct mbuf **m, struct ifnet *ifp, u_int16_t etype, * Assumes that ifp is actually pointer to arpcom structure. */ int -ether_output(struct ifnet *ifp0, struct mbuf *m0, struct sockaddr *dst, +ether_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, struct rtentry *rt) { u_int16_t etype; - int len, error = 0; u_char edst[ETHER_ADDR_LEN]; u_char *esrc; struct mbuf *m = m0; struct mbuf *mcopy = NULL; struct ether_header *eh; - struct arpcom *ac = (struct arpcom *)ifp0; - struct ifnet *ifp = ifp0; + struct arpcom *ac = (struct arpcom *)ifp; + int error = 0; #ifdef DIAGNOSTIC if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) { @@ -267,20 +261,6 @@ ether_output(struct ifnet *ifp0, struct mbuf *m0, struct sockaddr *dst, esrc = ac->ac_enaddr; -#if NCARP > 0 - if (ifp->if_type == IFT_CARP) { - ifp = ifp->if_carpdev; - ac = (struct arpcom *)ifp; - - if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) - senderr(ENETDOWN); - } - - if (ifp0 != ifp && ifp0->if_type == IFT_CARP) - esrc = carp_get_srclladdr(ifp0, esrc); -#endif /* NCARP > 0 */ - if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); @@ -402,14 +382,7 @@ ether_output(struct ifnet *ifp0, struct mbuf *m0, struct sockaddr *dst, } #endif - len = m->m_pkthdr.len; - - error = if_output(ifp, m); -#if NCARP > 0 - if (!error && ifp != ifp0) - ifp0->if_obytes += len; -#endif /* NCARP > 0 */ - return (error); + return (if_output(ifp, m)); bad: if (m) m_freem(m); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index cb16a2615cf..5c42326d870 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.258 2015/06/02 09:38:24 mpi Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.259 2015/06/08 13:40:48 mpi Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -745,7 +745,7 @@ carp_clone_create(struct if_clone *ifc, int unit) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = carp_ioctl; ifp->if_start = carp_start; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_MAXLEN(&ifp->if_snd, 1); IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp); @@ -1399,21 +1399,6 @@ carp_ourether(void *v, u_int8_t *ena) return (NULL); } -u_char * -carp_get_srclladdr(struct ifnet *ifp, u_char *esrc) -{ - struct carp_softc *sc = ifp->if_softc; - - if (sc->sc_balancing != CARP_BAL_IPSTEALTH && - sc->sc_balancing != CARP_BAL_IP && sc->cur_vhe) { - if (sc->cur_vhe->vhe_leader) - return (sc->sc_ac.ac_enaddr); - else - return (sc->cur_vhe->vhe_enaddr); - } - return (esrc); -} - int carp_input(struct mbuf *m) { @@ -2257,15 +2242,52 @@ carp_ifgattr_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) carp_vhe_send_ad_all(sc); } -/* - * Start output on carp interface. This function should never be called. - */ void carp_start(struct ifnet *ifp) { -#ifdef DEBUG - printf("%s: start called\n", ifp->if_xname); -#endif + struct carp_softc *sc = ifp->if_softc; + struct mbuf *m; + + for (;;) { + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); +#endif /* NBPFILTER > 0 */ + + if ((ifp->if_carpdev->if_flags & (IFF_UP|IFF_RUNNING)) != + (IFF_UP|IFF_RUNNING)) { + IF_DROP(&ifp->if_carpdev->if_snd); + ifp->if_oerrors++; + m_freem(m); + continue; + } + + /* + * Do not leak the multicast address when sending + * advertisements in 'ip' and 'ip-stealth' balacing + * modes. + */ + if (sc->sc_balancing != CARP_BAL_IPSTEALTH && + sc->sc_balancing != CARP_BAL_IP && + (sc->cur_vhe && !sc->cur_vhe->vhe_leader)) { + struct ether_header *eh; + uint8_t *esrc; + + eh = mtod(m, struct ether_header *); + esrc = sc->cur_vhe->vhe_enaddr; + memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost)); + } + + if (if_output(ifp->if_carpdev, m)) { + ifp->if_oerrors++; + continue; + } + ifp->if_opackets++; + } } int @@ -2283,7 +2305,7 @@ carp_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, return (ENETUNREACH); } - return (sc->sc_carpdev->if_output(ifp, m, sa, rt)); + return (ether_output(ifp, m, sa, rt)); } void diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h index 799a7a18878..b2998786046 100644 --- a/sys/netinet/ip_carp.h +++ b/sys/netinet/ip_carp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.h,v 1.33 2015/06/02 09:38:24 mpi Exp $ */ +/* $OpenBSD: ip_carp.h,v 1.34 2015/06/08 13:40:48 mpi Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -176,6 +176,5 @@ int carp_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int carp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int carp_lsdrop(struct mbuf *, sa_family_t, u_int32_t *, u_int32_t *); -u_char *carp_get_srclladdr(struct ifnet *, u_char *); #endif /* _KERNEL */ #endif /* _NETINET_IP_CARP_H_ */ -- 2.20.1