Add net.inet.ip.fw.dyn_keep_states sysctl which
re-links dynamic states to default rule instead of flushing on rule deletion. This can be useful while performing ruleset reload (think about `atomic` reload via changing sets). Currently it is turned off by default. MFC after: 2 weeks Sponsored by: Yandex LLC
This commit is contained in:
parent
11188df260
commit
fb2b51fab1
@ -2933,6 +2933,11 @@ and
|
||||
must be strictly lower than 5 seconds, the period of
|
||||
repetition of keepalives.
|
||||
The firewall enforces that.
|
||||
.It Va net.inet.ip.fw.dyn_keep_states: No 0
|
||||
Keep dynamic states on rule/set deletion.
|
||||
States are relinked to default rule (65535).
|
||||
This can be handly for ruleset reload.
|
||||
Turned off by default.
|
||||
.It Va net.inet.ip.fw.enable : No 1
|
||||
Enables the firewall.
|
||||
Setting this variable to 0 lets you run your machine without
|
||||
|
@ -106,7 +106,8 @@ __FBSDID("$FreeBSD$");
|
||||
*
|
||||
* Each dynamic rule holds a pointer to the parent ipfw rule so
|
||||
* we know what action to perform. Dynamic rules are removed when
|
||||
* the parent rule is deleted. XXX we should make them survive.
|
||||
* the parent rule is deleted. This can be changed by dyn_keep_states
|
||||
* sysctl.
|
||||
*
|
||||
* There are some limitations with dynamic rules -- we do not
|
||||
* obey the 'randomized match', and we do not do multiple
|
||||
@ -141,6 +142,10 @@ static VNET_DEFINE(uma_zone_t, ipfw_dyn_rule_zone);
|
||||
#define IPFW_BUCK_UNLOCK(i) mtx_unlock(&V_ipfw_dyn_v[(i)].mtx)
|
||||
#define IPFW_BUCK_ASSERT(i) mtx_assert(&V_ipfw_dyn_v[(i)].mtx, MA_OWNED)
|
||||
|
||||
|
||||
static VNET_DEFINE(int, dyn_keep_states);
|
||||
#define V_dyn_keep_states VNET(dyn_keep_states)
|
||||
|
||||
/*
|
||||
* Timeouts for various events in handing dynamic rules.
|
||||
*/
|
||||
@ -234,6 +239,9 @@ SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
|
||||
SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
|
||||
CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
|
||||
"Enable keepalives for dyn. rules");
|
||||
SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_keep_states,
|
||||
CTLFLAG_RW, &VNET_NAME(dyn_keep_states), 0,
|
||||
"Do not flush dynamic states on rule deletion");
|
||||
|
||||
SYSEND
|
||||
|
||||
@ -307,6 +315,7 @@ print_dyn_rule_flags(struct ipfw_flow_id *id, int dyn_type, int log_flags,
|
||||
print_dyn_rule_flags(id, dtype, LOG_DEBUG, prefix, postfix)
|
||||
|
||||
#define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
||||
#define TIME_LE(a,b) ((int)((a)-(b)) < 0)
|
||||
|
||||
/*
|
||||
* Lookup a dynamic rule, locked version.
|
||||
@ -1100,6 +1109,20 @@ check_dyn_rules(struct ip_fw_chain *chain, struct ip_fw *rule,
|
||||
if ((TIME_LEQ(q->expire, time_uptime)) ||
|
||||
((rule != NULL) && (q->rule == rule)) ||
|
||||
((set != RESVD_SET) && (q->rule->set == set))) {
|
||||
if (TIME_LE(time_uptime, q->expire) &&
|
||||
q->dyn_type == O_KEEP_STATE &&
|
||||
V_dyn_keep_states != 0) {
|
||||
/*
|
||||
* Do not delete state if
|
||||
* it is not expired and
|
||||
* dyn_keep_states is ON.
|
||||
* However we need to re-link it
|
||||
* to any other stable rule
|
||||
*/
|
||||
q->rule = chain->default_rule;
|
||||
NEXT_RULE();
|
||||
}
|
||||
|
||||
/* Unlink q from current list */
|
||||
q_next = q->next;
|
||||
if (q == V_ipfw_dyn_v[i].head)
|
||||
|
Loading…
Reference in New Issue
Block a user