Make ipfw dynamic states operations SMP-ready.

* Global IPFW_DYN_LOCK() is changed to per-bucket mutex.
* State expiration is done in ipfw_tick every second.
* No expiration is done on forwarding path.
* hash table resize is done automatically and does not flush all states.
* Dynamic UMA zone is now allocated per each VNET
* State limiting is now done via UMA(9) api.

Discussed with:	ipfw
MFC after:	3 weeks
Sponsored by:	Yandex LLC
This commit is contained in:
Alexander V. Chernikov 2012-11-30 16:33:22 +00:00
parent 0f9eb6b09c
commit 2e089d5c04
4 changed files with 643 additions and 335 deletions

View File

@ -2046,7 +2046,7 @@ do { \
f->rulenum, f->id);
cmd = ACTION_PTR(f);
l = f->cmd_len - f->act_ofs;
ipfw_dyn_unlock();
ipfw_dyn_unlock(q);
cmdlen = 0;
match = 1;
break;
@ -2525,7 +2525,6 @@ ipfw_init(void)
{
int error = 0;
ipfw_dyn_attach();
/*
* Only print out this stuff the first time around,
* when called from the sysinit code.
@ -2579,7 +2578,6 @@ ipfw_destroy(void)
{
ipfw_log_bpf(0); /* uninit */
ipfw_dyn_detach();
printf("IP firewall unloaded\n");
}
@ -2637,7 +2635,7 @@ vnet_ipfw_init(const void *unused)
chain->id = rule->id = 1;
IPFW_LOCK_INIT(chain);
ipfw_dyn_init();
ipfw_dyn_init(chain);
/* First set up some values that are compile time options */
V_ipfw_vnet_ready = 1; /* Open for business */

File diff suppressed because it is too large Load Diff

View File

@ -175,7 +175,9 @@ enum { /* result for matching dynamic rules */
* and only to release the result of lookup_dyn_rule().
* Eventually we may implement it with a callback on the function.
*/
void ipfw_dyn_unlock(void);
struct ip_fw_chain;
void ipfw_expire_dyn_rules(struct ip_fw_chain *, struct ip_fw *, int);
void ipfw_dyn_unlock(ipfw_dyn_rule *q);
struct tcphdr;
struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
@ -185,11 +187,9 @@ int ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
ipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt,
int *match_direction, struct tcphdr *tcp);
void ipfw_remove_dyn_children(struct ip_fw *rule);
void ipfw_get_dynamic(char **bp, const char *ep);
void ipfw_get_dynamic(struct ip_fw_chain *chain, char **bp, const char *ep);
void ipfw_dyn_attach(void); /* uma_zcreate .... */
void ipfw_dyn_detach(void); /* uma_zdestroy ... */
void ipfw_dyn_init(void); /* per-vnet initialization */
void ipfw_dyn_init(struct ip_fw_chain *); /* per-vnet initialization */
void ipfw_dyn_uninit(int); /* per-vnet deinitialization */
int ipfw_dyn_len(void);
@ -259,6 +259,9 @@ struct sockopt; /* used by tcp_var.h */
#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx)
#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx)
#define IPFW_UH_RLOCK_ASSERT(_chain) rw_assert(&(_chain)->uh_lock, RA_RLOCKED)
#define IPFW_UH_WLOCK_ASSERT(_chain) rw_assert(&(_chain)->uh_lock, RA_WLOCKED)
#define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock)
#define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock)
#define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock)

View File

@ -382,7 +382,7 @@ del_entry(struct ip_fw_chain *chain, uint32_t arg)
continue;
l = RULESIZE(rule);
chain->static_len -= l;
ipfw_remove_dyn_children(rule);
ipfw_expire_dyn_rules(chain, rule, RESVD_SET);
rule->x_next = chain->reap;
chain->reap = rule;
}
@ -925,7 +925,7 @@ ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
dst->timestamp += boot_seconds;
bp += l;
}
ipfw_get_dynamic(&bp, ep); /* protected by the dynamic lock */
ipfw_get_dynamic(chain, &bp, ep); /* protected by the dynamic lock */
return (bp - (char *)buf);
}