FreeBSD/sys/netpfil/ipfw/ip_fw_table.c
/*
 * Deletes one or more entries in table @ti.
 *
 * Returns 0 on success.
 */
Deletes one or more entries in table @ti.
Returns 0 on success.
Deletes one or more entries in table @ti . Returns 0 on success .
int
del_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
    struct tentry_info *tei, uint8_t flags, uint32_t count)
{
	struct table_config *tc;
	struct table_algo *ta;
	struct tentry_info *ptei;
	uint16_t kidx;
	int error, first_error, i;
	uint32_t num, numdel;
	char ta_buf[TA_BUF_SZ];
	caddr_t ta_buf_m, v;
	IPFW_UH_WLOCK(ch);
	error = find_ref_table(ch, ti, tei, count, OP_DEL, &tc);
	if (error != 0) {
		IPFW_UH_WUNLOCK(ch);
		return (error);
	}
	ta = tc->ta;
	IPFW_UH_WUNLOCK(ch);
	ta_buf_m = ta_buf;
	error = prepare_batch_buffer(ch, ta, tei, count, OP_DEL, &ta_buf_m);
	if (error != 0)
		goto cleanup;
	IPFW_UH_WLOCK(ch);
	tc->no.refcnt--;
	if (ta != tc->ta) {
		IPFW_UH_WUNLOCK(ch);
		error = EINVAL;
		goto cleanup;
	}
	kidx = tc->no.kidx;
	numdel = 0;
	first_error = 0;
	IPFW_WLOCK(ch);
	v = ta_buf_m;
	for (i = 0; i < count; i++, v += ta->ta_buf_size) {
		ptei = &tei[i];
		num = 0;
		error = ta->del(tc->astate, KIDX_TO_TI(ch, kidx), ptei, v,
		    &num);
		store_tei_result(ptei, OP_DEL, error, num);
		if (error != 0 && first_error == 0)
			first_error = error;
		tc->count -= num;
		numdel += num;
	}
	IPFW_WUNLOCK(ch);
	ipfw_garbage_table_values(ch, tc, tei, count, 0);
	if (numdel != 0) {
		check_table_space(ch, NULL, tc, KIDX_TO_TI(ch, kidx), 0);
	}
	IPFW_UH_WUNLOCK(ch);
	error = first_error;
cleanup:
	flush_batch_buffer(ch, ta, tei, count, 0, ta_buf_m, ta_buf);
	return (error);
}
int del_table_entry ( struct ip_fw_chain * ch , struct tid_info * ti , struct tentry_info * tei , uint8_t flags , uint32_t count ) { struct table_config * tc ; struct table_algo * ta ; struct tentry_info * ptei ; uint16_t kidx ; int error , first_error , i ; uint32_t num , numdel ; char ta_buf [ TA_BUF_SZ ] ; caddr_t ta_buf_m , v ; IPFW_UH_WLOCK ( ch ) ; error = find_ref_table ( ch , ti , tei , count , OP_DEL , & tc ) ; if ( error != 0 ) { IPFW_UH_WUNLOCK ( ch ) ; return ( error ) ; } ta = tc -> ta ; IPFW_UH_WUNLOCK ( ch ) ; ta_buf_m = ta_buf ; error = prepare_batch_buffer ( ch , ta , tei , count , OP_DEL , & ta_buf_m ) ; if ( error != 0 ) goto cleanup ; IPFW_UH_WLOCK ( ch ) ; tc -> no . refcnt -- ; if ( ta != tc -> ta ) { IPFW_UH_WUNLOCK ( ch ) ; error = EINVAL ; goto cleanup ; } kidx = tc -> no . kidx ; numdel = 0 ; first_error = 0 ; IPFW_WLOCK ( ch ) ; v = ta_buf_m ; for ( i = 0 ; i < count ; i ++ , v += ta -> ta_buf_size ) { ptei = & tei [ i ] ; num = 0 ; error = ta -> del ( tc -> astate , KIDX_TO_TI ( ch , kidx ) , ptei , v , & num ) ; store_tei_result ( ptei , OP_DEL , error , num ) ; if ( error != 0 && first_error == 0 ) first_error = error ; tc -> count -= num ; numdel += num ; } IPFW_WUNLOCK ( ch ) ; ipfw_garbage_table_values ( ch , tc , tei , count , 0 ) ; if ( numdel != 0 ) { check_table_space ( ch , NULL , tc , KIDX_TO_TI ( ch , kidx ) , 0 ) ; } IPFW_UH_WUNLOCK ( ch ) ; error = first_error ; cleanup : flush_batch_buffer ( ch , ta , tei , count , 0 , ta_buf_m , ta_buf ) ; return ( error ) ; }
Deletes one or more entries in table @ti.
Deletes one or more entries in table @ti .
/*
	 * Find and reference existing table.
	 */ /* Allocate memory and prepare record(s) */ /* Pass stack buffer by default */ /* Drop reference we've used in first search */ /*
	 * Check if table algo is still the same.
	 * (changed ta may be the result of table swap).
	 */ /* Save state for userland */ /* Unlink non-used values */ /* Run post-del hook to permit shrinking */ /* Return first error to user, if any */