svn commit: r259568 - in head: sbin/ipfw sys/netpfil/ipfw

Alexander V. Chernikov melifaro at FreeBSD.org
Wed Dec 18 20:17:06 UTC 2013


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)


More information about the svn-src-all mailing list