FreeBSD/sys/netinet/ip_mroute.c
/*
 * Clean up the cache entry if upcall is not serviced
 */
Clean up the cache entry if upcall is not serviced
Clean up the cache entry if upcall is not serviced
static void
expire_upcalls(void *arg)
{
    u_long i;
    CURVNET_SET((struct vnet *) arg);
    MFC_LOCK();
    for (i = 0; i < mfchashsize; i++) {
	struct mfc *rt, *nrt;
	if (V_nexpire[i] == 0)
	    continue;
	LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) {
		if (TAILQ_EMPTY(&rt->mfc_stall))
			continue;
		if (rt->mfc_expire == 0 || --rt->mfc_expire > 0)
			continue;
		while (rt->mfc_bw_meter != NULL) {
		    struct bw_meter *x = rt->mfc_bw_meter;
		    rt->mfc_bw_meter = x->bm_mfc_next;
		    free(x, M_BWMETER);
		}
		MRTSTAT_INC(mrts_cache_cleanups);
		CTR3(KTR_IPMF, "%s: expire (%lx, %lx)", __func__,
		    (u_long)ntohl(rt->mfc_origin.s_addr),
		    (u_long)ntohl(rt->mfc_mcastgrp.s_addr));
		expire_mfc(rt);
	    }
    }
    MFC_UNLOCK();
    callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls,
	curvnet);
    CURVNET_RESTORE();
}
static void expire_upcalls ( void * arg ) { u_long i ; CURVNET_SET ( ( struct vnet * ) arg ) ; MFC_LOCK ( ) ; for ( i = 0 ; i < mfchashsize ; i ++ ) { struct mfc * rt , * nrt ; if ( V_nexpire [ i ] == 0 ) continue ; LIST_FOREACH_SAFE ( rt , & V_mfchashtbl [ i ] , mfc_hash , nrt ) { if ( TAILQ_EMPTY ( & rt -> mfc_stall ) ) continue ; if ( rt -> mfc_expire == 0 || -- rt -> mfc_expire > 0 ) continue ; while ( rt -> mfc_bw_meter != NULL ) { struct bw_meter * x = rt -> mfc_bw_meter ; rt -> mfc_bw_meter = x -> bm_mfc_next ; free ( x , M_BWMETER ) ; } MRTSTAT_INC ( mrts_cache_cleanups ) ; CTR3 ( KTR_IPMF , " " , __func__ , ( u_long ) ntohl ( rt -> mfc_origin . s_addr ) , ( u_long ) ntohl ( rt -> mfc_mcastgrp . s_addr ) ) ; expire_mfc ( rt ) ; } } MFC_UNLOCK ( ) ; callout_reset ( & V_expire_upcalls_ch , EXPIRE_TIMEOUT , expire_upcalls , curvnet ) ; CURVNET_RESTORE ( ) ; }
Clean up the cache entry if upcall is not serviced
Clean up the cache entry if upcall is not serviced
/*
		 * free the bw_meter entries
		 */