Index: ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.286 diff -u -p -r1.286 ip_carp.c --- ip_carp.c 21 Jan 2016 11:23:48 -0000 1.286 +++ ip_carp.c 8 Feb 2016 12:56:27 -0000 @@ -210,6 +210,7 @@ int carp_input(struct ifnet *, struct mb void carp_proto_input_c(struct ifnet *, struct mbuf *, struct carp_header *, int, sa_family_t); void carp_proto_input_if(struct ifnet *, struct mbuf *, int); +int carp_input_mcast(struct carp_softc *, struct mbuf *); void carpattach(int); void carpdetach(struct carp_softc *); int carp_prepare_ad(struct mbuf *, struct carp_vhost_entry *, @@ -1392,6 +1393,41 @@ carp_vhe_match(struct carp_softc *sc, ui } int +carp_input_mcast(struct carp_softc *sc, struct mbuf *m) +{ + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); + struct mbuf *m0; + int len; + + MGET(m0, M_DONTWAIT, m->m_type); + if (m0 == NULL) + return (-1); + + if (m_dup_pkthdr(m0, m, M_DONTWAIT) != 0) + goto fail; + + len = m->m_pkthdr.len + max_linkhdr + ETHER_ALIGN; + + if (len > MHLEN) { + MCLGETI(m0, M_DONTWAIT, NULL, len); + if (!ISSET(m0->m_flags, M_EXT)) + goto fail; + } + m0->m_pkthdr.len = m0->m_len = len; + m_adj(m0, max_linkhdr + ETHER_ALIGN); + m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t)); + + ml_enqueue(&ml, m0); + if_input(&sc->sc_if, &ml); + + return (0); + +fail: + m_freem(m0); + return (-1); +} + +int carp_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) { struct ether_header *eh; @@ -1424,19 +1460,12 @@ carp_input(struct ifnet *ifp0, struct mb * for each CARP interface _before_ copying. */ SRPL_FOREACH(sc, &cif->vhif_vrs, &i, sc_list) { - struct mbuf *m0; - if (!(sc->sc_if.if_flags & IFF_UP)) continue; - m0 = m_copym2(m, 0, M_COPYALL, M_DONTWAIT); - if (m0 == NULL) - continue; - - ml_init(&ml); - ml_enqueue(&ml, m0); - - if_input(&sc->sc_if, &ml); + /* if we cant send one we probably cant send more */ + if (carp_input_mcast(sc, m) != 0) + break; } SRPL_LEAVE(&i, sc);