Two changes: Currently carp_send_ad is called under splsoftclock, but this may be unsafe due to calls into pf_test via ip_output. Raise the priority level to splsoftnet for the function run. It might be possible to get away with the splsoftnet just over the ip_output call. Also, in the case where the mbuf tagging fails due to out of memory in carp_prepare_ad, we would stop sending advertisements. Treat this as per the other out of memory case, which retries at the next scheduled interval. Diff against OPENBSD_3_6. Chris Pascoe 2004/10/05 Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.62 diff -u -r1.62 ip_carp.c --- netinet/ip_carp.c 31 Aug 2004 05:31:39 -0000 1.62 +++ netinet/ip_carp.c 5 Oct 2004 02:25:06 -0000 @@ -793,7 +793,9 @@ struct carp_softc *sc = v; struct carp_header *ch_ptr; struct mbuf *m; - int len, advbase, advskew; + int len, advbase, advskew, s; + + s = splsoftnet(); /* bow out if we've lost our UPness or RUNNINGuiness */ if ((sc->sc_ac.ac_if.if_flags & @@ -829,9 +831,7 @@ sc->sc_ac.ac_if.if_oerrors++; carpstats.carps_onomem++; /* XXX maybe less ? */ - if (advbase != 255 || advskew != 255) - timeout_add(&sc->sc_ad_tmo, tvtohz(&tv)); - return; + goto retry_later; } len = sizeof(*ip) + sizeof(ch); m->m_pkthdr.len = len; @@ -855,7 +855,7 @@ ch_ptr = (void *)ip + sizeof(*ip); bcopy(&ch, ch_ptr, sizeof(ch)); if (carp_prepare_ad(m, sc, ch_ptr)) - return; + goto retry_later; m->m_data += sizeof(*ip); ch_ptr->carp_cksum = carp_cksum(m, len - sizeof(*ip)); @@ -897,9 +897,7 @@ sc->sc_ac.ac_if.if_oerrors++; carpstats.carps_onomem++; /* XXX maybe less ? */ - if (advbase != 255 || advskew != 255) - timeout_add(&sc->sc_ad_tmo, tvtohz(&tv)); - return; + goto retry_later; } len = sizeof(*ip6) + sizeof(ch); m->m_pkthdr.len = len; @@ -923,7 +921,7 @@ ch_ptr = (void *)ip6 + sizeof(*ip6); bcopy(&ch, ch_ptr, sizeof(ch)); if (carp_prepare_ad(m, sc, ch_ptr)) - return; + goto retry_later; m->m_data += sizeof(*ip6); ch_ptr->carp_cksum = carp_cksum(m, len - sizeof(*ip6)); @@ -957,6 +955,8 @@ } #endif /* INET6 */ +retry_later: + splx(s); if (advbase != 255 || advskew != 255) timeout_add(&sc->sc_ad_tmo, tvtohz(&tv)); }