return;
goto retry_later;
carp_send_ad(void *v){	struct carp_header ch;	struct timeval tv;	struct carp_softc *sc = v;	struct carp_header *ch_ptr;	struct mbuf *m;	int len, advbase, advskew;	/* bow out if we've lost our UPness or RUNNINGuiness */	if ((sc->sc_ac.ac_if.if_flags &	    (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {		advbase = 255;		advskew = 255;	} else {		advbase = sc->sc_advbase;		if (!carp_suppress_preempt || sc->sc_advskew > 240)			advskew = sc->sc_advskew;		else			advskew = 240;		tv.tv_sec = advbase;		tv.tv_usec = advskew * 1000000 / 256;	}	ch.carp_version = CARP_VERSION;	ch.carp_type = CARP_ADVERTISEMENT;	ch.carp_vhid = sc->sc_vhid;	ch.carp_advbase = advbase;	ch.carp_advskew = advskew;	ch.carp_authlen = 7;	/* XXX DEFINE */	ch.carp_pad1 = 0;	/* must be zero */	ch.carp_cksum = 0;#ifdef INET	if (sc->sc_ia) {		struct ip *ip;		MGETHDR(m, M_DONTWAIT, MT_HEADER);		if (m == NULL) {			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;		}		len = sizeof(*ip) + sizeof(ch);		m->m_pkthdr.len = len;		m->m_pkthdr.rcvif = NULL;		m->m_len = len;		MH_ALIGN(m, m->m_len);		m->m_flags |= M_MCAST;		ip = mtod(m, struct ip *);		ip->ip_v = IPVERSION;		ip->ip_hl = sizeof(*ip) >> 2;		ip->ip_tos = IPTOS_LOWDELAY;		ip->ip_len = htons(len);		ip->ip_id = htons(ip_randomid());		ip->ip_off = htons(IP_DF);		ip->ip_ttl = CARP_DFLTTL;		ip->ip_p = IPPROTO_CARP;		ip->ip_sum = 0;		ip->ip_src.s_addr = sc->sc_ia->ia_addr.sin_addr.s_addr;		ip->ip_dst.s_addr = INADDR_CARP_GROUP;		ch_ptr = (void *)ip + sizeof(*ip);		bcopy(&ch, ch_ptr, sizeof(ch));		if (carp_prepare_ad(m, sc, ch_ptr))			return;		m->m_data += sizeof(*ip);		ch_ptr->carp_cksum = carp_cksum(m, len - sizeof(*ip));		m->m_data -= sizeof(*ip);		getmicrotime(&sc->sc_ac.ac_if.if_lastchange);		sc->sc_ac.ac_if.if_opackets++;		sc->sc_ac.ac_if.if_obytes += len;		carpstats.carps_opackets++;		if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) {			sc->sc_ac.ac_if.if_oerrors++;			if (sc->sc_sendad_errors < INT_MAX)				sc->sc_sendad_errors++;			if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) {				carp_suppress_preempt++;				if (carp_suppress_preempt == 1)					carp_send_ad_all();			}			sc->sc_sendad_success = 0;		} else {			if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) {				if (++sc->sc_sendad_success >=				    CARP_SENDAD_MIN_SUCCESS) {					carp_suppress_preempt--;					sc->sc_sendad_errors = 0;				}			} else				sc->sc_sendad_errors = 0;		}	}#endif /* INET */#ifdef INET6	if (sc->sc_ia6) {		struct ip6_hdr *ip6;		MGETHDR(m, M_DONTWAIT, MT_HEADER);		if (m == NULL) {			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;		}		len = sizeof(*ip6) + sizeof(ch);		m->m_pkthdr.len = len;		m->m_pkthdr.rcvif = NULL;		m->m_len = len;		MH_ALIGN(m, m->m_len);		m->m_flags |= M_MCAST;		ip6 = mtod(m, struct ip6_hdr *);		bzero(ip6, sizeof(*ip6));		ip6->ip6_vfc |= IPV6_VERSION;		ip6->ip6_hlim = CARP_DFLTTL;		ip6->ip6_nxt = IPPROTO_CARP;		bcopy(&sc->sc_ia6->ia_addr.sin6_addr, &ip6->ip6_src,		    sizeof(struct in6_addr));		/* set the multicast destination */		ip6->ip6_dst.s6_addr8[0] = 0xff;		ip6->ip6_dst.s6_addr8[1] = 0x02;		ip6->ip6_dst.s6_addr8[15] = 0x12;		ch_ptr = (void *)ip6 + sizeof(*ip6);		bcopy(&ch, ch_ptr, sizeof(ch));		if (carp_prepare_ad(m, sc, ch_ptr))			return;		m->m_data += sizeof(*ip6);		ch_ptr->carp_cksum = carp_cksum(m, len - sizeof(*ip6));		m->m_data -= sizeof(*ip6);		getmicrotime(&sc->sc_ac.ac_if.if_lastchange);		sc->sc_ac.ac_if.if_opackets++;		sc->sc_ac.ac_if.if_obytes += len;		carpstats.carps_opackets6++;		if (ip6_output(m, NULL, NULL, 0, &sc->sc_im6o, NULL)) {			sc->sc_ac.ac_if.if_oerrors++;			if (sc->sc_sendad_errors < INT_MAX)				sc->sc_sendad_errors++;			if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) {				carp_suppress_preempt++;				if (carp_suppress_preempt == 1)					carp_send_ad_all();			}			sc->sc_sendad_success = 0;		} else {			if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) {				if (++sc->sc_sendad_success >=				    CARP_SENDAD_MIN_SUCCESS) {					carp_suppress_preempt--;					sc->sc_sendad_errors = 0;				}			} else				sc->sc_sendad_errors = 0;		}	}#endif /* INET6 */	if (advbase != 255 || advskew != 255)		timeout_add(&sc->sc_ad_tmo, tvtohz(&tv));}