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:
parent
0f9eb6b09c
commit
2e089d5c04
@ -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
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user