FreeBSD/sys/netpfil/ipfw/ip_fw_table.c
/*
 * Grow tables index.
 *
 * Returns 0 on success.
 */
Grow tables index.
Returns 0 on success.
Grow tables index . Returns 0 on success .
int
ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables)
{
	unsigned int ntables_old, tbl;
	struct namedobj_instance *ni;
	void *new_idx, *old_tablestate, *tablestate;
	struct table_info *ti;
	struct table_config *tc;
	int i, new_blocks;
	if (ntables == 0)
		return (EINVAL);
	if (ntables > IPFW_TABLES_MAX)
		ntables = IPFW_TABLES_MAX;
	ntables = (unsigned int)roundup2p(ntables); 
	tablestate = malloc(ntables * sizeof(struct table_info),
	    M_IPFW, M_WAITOK | M_ZERO);
	ipfw_objhash_bitmap_alloc(ntables, (void *)&new_idx, &new_blocks);
	IPFW_UH_WLOCK(ch);
	tbl = (ntables >= V_fw_tables_max) ? V_fw_tables_max : ntables;
	ni = CHAIN_TO_NI(ch);
	if (ntables < V_fw_tables_max) {
		IPFW_UH_WUNLOCK(ch);
		return (EINVAL);
	}
	memcpy(tablestate, ch->tablestate, sizeof(struct table_info) * tbl);
	ipfw_objhash_bitmap_merge(ni, &new_idx, &new_blocks);
	IPFW_WLOCK(ch);
	old_tablestate = ch->tablestate;
	ch->tablestate = tablestate;
	ipfw_objhash_bitmap_swap(ni, &new_idx, &new_blocks);
	ntables_old = V_fw_tables_max;
	V_fw_tables_max = ntables;
	IPFW_WUNLOCK(ch);
	ti = (struct table_info *)ch->tablestate;
	for (i = 0; i < tbl; i++, ti++) {
		if (ti->lookup == NULL)
			continue;
		tc = (struct table_config *)ipfw_objhash_lookup_kidx(ni, i);
		if (tc == NULL || tc->ta->change_ti == NULL)
			continue;
		tc->ta->change_ti(tc->astate, ti);
	}
	IPFW_UH_WUNLOCK(ch);
	free(old_tablestate, M_IPFW);
	ipfw_objhash_bitmap_free(new_idx, new_blocks);
	return (0);
}
int ipfw_resize_tables ( struct ip_fw_chain * ch , unsigned int ntables ) { unsigned int ntables_old , tbl ; struct namedobj_instance * ni ; void * new_idx , * old_tablestate , * tablestate ; struct table_info * ti ; struct table_config * tc ; int i , new_blocks ; if ( ntables == 0 ) return ( EINVAL ) ; if ( ntables > IPFW_TABLES_MAX ) ntables = IPFW_TABLES_MAX ; ntables = ( unsigned int ) roundup2p ( ntables ) ; tablestate = malloc ( ntables * sizeof ( struct table_info ) , M_IPFW , M_WAITOK | M_ZERO ) ; ipfw_objhash_bitmap_alloc ( ntables , ( void * ) & new_idx , & new_blocks ) ; IPFW_UH_WLOCK ( ch ) ; tbl = ( ntables >= V_fw_tables_max ) ? V_fw_tables_max : ntables ; ni = CHAIN_TO_NI ( ch ) ; if ( ntables < V_fw_tables_max ) { IPFW_UH_WUNLOCK ( ch ) ; return ( EINVAL ) ; } memcpy ( tablestate , ch -> tablestate , sizeof ( struct table_info ) * tbl ) ; ipfw_objhash_bitmap_merge ( ni , & new_idx , & new_blocks ) ; IPFW_WLOCK ( ch ) ; old_tablestate = ch -> tablestate ; ch -> tablestate = tablestate ; ipfw_objhash_bitmap_swap ( ni , & new_idx , & new_blocks ) ; ntables_old = V_fw_tables_max ; V_fw_tables_max = ntables ; IPFW_WUNLOCK ( ch ) ; ti = ( struct table_info * ) ch -> tablestate ; for ( i = 0 ; i < tbl ; i ++ , ti ++ ) { if ( ti -> lookup == NULL ) continue ; tc = ( struct table_config * ) ipfw_objhash_lookup_kidx ( ni , i ) ; if ( tc == NULL || tc -> ta -> change_ti == NULL ) continue ; tc -> ta -> change_ti ( tc -> astate , ti ) ; } IPFW_UH_WUNLOCK ( ch ) ; free ( old_tablestate , M_IPFW ) ; ipfw_objhash_bitmap_free ( new_idx , new_blocks ) ; return ( 0 ) ; }
Grow tables index.
Grow tables index .
/* Check new value for validity */ /* Alight to nearest power of 2 */ /* Allocate new pointers */ /* Temporary restrict decreasing max_tables */ /*
		 * FIXME: Check if we really can shrink
		 */ /* Copy table info/indices */ /* Change pointers */ /* Notify all consumers that their @ti pointer has changed */ /* Free old pointers */