FreeBSD/sys/netinet/ip_reass.c
/*
 * Seek for old fragment queue header that can be reused.  Try to
 * reuse a header from currently locked hash bucket.
 */
Seek for old fragment queue header that can be reused.  Try to
reuse a header from currently locked hash bucket.
Seek for old fragment queue header that can be reused . Try to reuse a header from currently locked hash bucket .
static struct ipq *
ipq_reuse(int start)
{
	struct ipq *fp;
	int i;
	IPQ_LOCK_ASSERT(start);
	for (i = start;; i++) {
		if (i == IPREASS_NHASH)
			i = 0;
		if (i != start && IPQ_TRYLOCK(i) == 0)
			continue;
		fp = TAILQ_LAST(&V_ipq[i].head, ipqhead);
		if (fp) {
			struct mbuf *m;
			IPSTAT_ADD(ips_fragtimeout, fp->ipq_nfrags);
			while (fp->ipq_frags) {
				m = fp->ipq_frags;
				fp->ipq_frags = m->m_nextpkt;
				m_freem(m);
			}
			TAILQ_REMOVE(&V_ipq[i].head, fp, ipq_list);
			if (i != start)
				IPQ_UNLOCK(i);
			IPQ_LOCK_ASSERT(start);
			return (fp);
		}
		if (i != start)
			IPQ_UNLOCK(i);
	}
}
static struct ipq * ipq_reuse ( int start ) { struct ipq * fp ; int i ; IPQ_LOCK_ASSERT ( start ) ; for ( i = start ; ; i ++ ) { if ( i == IPREASS_NHASH ) i = 0 ; if ( i != start && IPQ_TRYLOCK ( i ) == 0 ) continue ; fp = TAILQ_LAST ( & V_ipq [ i ] . head , ipqhead ) ; if ( fp ) { struct mbuf * m ; IPSTAT_ADD ( ips_fragtimeout , fp -> ipq_nfrags ) ; while ( fp -> ipq_frags ) { m = fp -> ipq_frags ; fp -> ipq_frags = m -> m_nextpkt ; m_freem ( m ) ; } TAILQ_REMOVE ( & V_ipq [ i ] . head , fp , ipq_list ) ; if ( i != start ) IPQ_UNLOCK ( i ) ; IPQ_LOCK_ASSERT ( start ) ; return ( fp ) ; } if ( i != start ) IPQ_UNLOCK ( i ) ; } }
Seek for old fragment queue header that can be reused.
Seek for old fragment queue header that can be reused .