Date: Wed, 18 Dec 2013 20:17:05 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r259568 - in head: sbin/ipfw sys/netpfil/ipfw Message-ID: <201312182017.rBIKH5v2054858@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Wed Dec 18 20:17:05 2013 New Revision: 259568 URL: http://svnweb.freebsd.org/changeset/base/259568 Log: 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 Modified: head/sbin/ipfw/ipfw.8 head/sys/netpfil/ipfw/ip_fw_dynamic.c Modified: head/sbin/ipfw/ipfw.8 ============================================================================== --- head/sbin/ipfw/ipfw.8 Wed Dec 18 20:11:01 2013 (r259567) +++ head/sbin/ipfw/ipfw.8 Wed Dec 18 20:17:05 2013 (r259568) @@ -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 Modified: head/sys/netpfil/ipfw/ip_fw_dynamic.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_dynamic.c Wed Dec 18 20:11:01 2013 (r259567) +++ head/sys/netpfil/ipfw/ip_fw_dynamic.c Wed Dec 18 20:17:05 2013 (r259568) @@ -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_ #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_AU 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 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 *chai 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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312182017.rBIKH5v2054858>