Skip site navigation (1)Skip section navigation (2)
Date:      Fri,  6 Jul 2001 11:03:31 -0600 (MDT)
From:      Aaron Gifford <agifford@infowest.com>
To:        gnats-admin@FreeBSD.org, freebsd-bugs@FreeBSD.org
Subject:   Re: kern/28713: NEW IPFW FEATURE [PATCHES]: Dynamic rule expiration lifetime fine-grained control
Message-ID:  <20010706170331.2D808210F5@ns1.infowest.com>

next in thread | raw e-mail | index | archive | help
Hello,

Thanks to Crist J. Clark for pointing out that the ipfw patches I
submitted could be made more efficient.  The following patches are the
same patches, modified according to Crist's suggestions.  I've also
included patches against -STABLE as of 6 July 2001.  The first set of
patches are against CVS sources (and should also work against -CURRENT),
the second set against -STABLE.

Aaron Gifford

==========PATCHES TO CURRENT/CVS BELOW==========

--- /usr/src/sys/netinet/ip_fw.h.orig	Tue Feb 13 07:12:04 2001
+++ /usr/src/sys/netinet/ip_fw.h	Fri Jul  6 10:17:48 2001
@@ -80,6 +80,7 @@
 	u_short fu_skipto_rule;		/* SKIPTO command rule number */
 	u_short fu_reject_code;		/* REJECT response code */
 	struct sockaddr_in fu_fwd_ip;
+	u_int32_t fu_dyn_lifetime;	/* Explicit dynamic rule lifetime */
     } fw_un;
     u_char fw_prot;			/* IP protocol */
 	/*
@@ -128,6 +129,7 @@
 #define fw_reject_code	fw_un.fu_reject_code
 #define fw_pipe_nr	fw_un.fu_pipe_nr
 #define fw_fwd_ip	fw_un.fu_fwd_ip
+#define fw_dyn_lifetime	fw_un.fu_dyn_lifetime
 
 struct ip_fw_chain {
 	LIST_ENTRY(ip_fw_chain) next;
@@ -154,6 +156,7 @@
     struct ipfw_flow_id mask ;
     struct ip_fw_chain *chain ;		/* pointer to parent rule	*/
     u_int32_t type ;			/* rule type			*/
+    u_int32_t lifetime ;		/* per-rule specified lifetime  */
     u_int32_t expire ;			/* expire time			*/
     u_int64_t pcnt, bcnt;		/* match counters		*/
     u_int32_t bucket ;			/* which bucket in hash table	*/
--- /usr/src/sys/netinet/ip_fw.c.orig	Mon Jul  2 09:50:31 2001
+++ /usr/src/sys/netinet/ip_fw.c	Fri Jul  6 10:17:48 2001
@@ -763,7 +763,7 @@
 	    break ;
 	case TH_SYN | (TH_SYN << 8) :
 	    /* move to established */
-	    q->expire = time_second + dyn_ack_lifetime ;
+	    q->expire = time_second + q->lifetime ;
 	    break ;
 	case TH_SYN | (TH_SYN << 8) | TH_FIN :
 	case TH_SYN | (TH_SYN << 8) | (TH_FIN << 8) :
@@ -788,7 +788,7 @@
 	}
     } else {
 	/* should do something for UDP and others... */
-	q->expire = time_second + dyn_short_lifetime ;
+	q->expire = time_second + q->lifetime ;
     }
     if (match_direction)
 	*match_direction = dir ;
@@ -834,7 +834,14 @@
     if (mask)
 	r->mask = *mask ;
     r->id = *id ;
-    r->expire = time_second + dyn_syn_lifetime ;
+    r->lifetime = chain->rule->fw_dyn_lifetime ;
+    if (r->id.proto == IPPROTO_TCP) {
+	r->lifetime = r->lifetime ? r->lifetime : dyn_ack_lifetime ;
+	r->expire = time_second + dyn_syn_lifetime ;
+    } else {
+	r->lifetime = r->lifetime ? r->lifetime : dyn_short_lifetime ;
+	r->expire = time_second + r->lifetime ;
+    }
     r->chain = chain ;
     r->type = ((struct ip_fw_ext *)chain->rule)->dyn_type ;
 
--- /usr/src/sbin/ipfw/ipfw.c.orig	Sun Jul  1 16:00:26 2001
+++ /usr/src/sbin/ipfw/ipfw.c	Fri Jul  6 10:17:50 2001
@@ -377,6 +377,8 @@
 		    printf(" keep-state %d", (int)chain->next_rule_ptr);
 		else
 		    printf(" keep-state");
+		if (chain->fw_dyn_lifetime)
+		    printf(" lifetime %d", (int)chain->fw_dyn_lifetime);
 	}
 	/* Direction */
 	if (chain->fw_flg & IP_FW_BRIDGED)
@@ -917,6 +919,7 @@
 "    tcpack {acknowledgement number}\n"
 "    tcpwin {window size}\n"
 "    icmptypes {type[, type]}...\n"
+"    keep-state [lifetime <seconds>]\n"
 "  pipeconfig:\n"
 "    {bw|bandwidth} <number>{bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n"
 "    {bw|bandwidth} interface_name\n"
@@ -1971,6 +1974,15 @@
 			if (ac > 0 && (type = atoi(*av)) != 0) {
 			    (int)rule.next_rule_ptr = type;
 			    av++; ac--;
+			}
+			if (ac > 0 && !strncmp(*av,"lifetime",strlen(*av))) {
+			    u_long lifetime ;
+
+			    av++; ac--;
+			    if (ac > 0 && (lifetime = atoi(*av)) != 0) {
+				rule.fw_dyn_lifetime = lifetime;
+				av++; ac--;
+			    }
 			}
 		} else if (!strncmp(*av, "bridged", strlen(*av))) {
 			rule.fw_flg |= IP_FW_BRIDGED;
--- /usr/src/sbin/ipfw/ipfw.8.orig	Wed Jun  6 14:56:56 2001
+++ /usr/src/sbin/ipfw/ipfw.8	Fri Jul  6 10:17:51 2001
@@ -640,18 +640,38 @@
 interface.
 .It Ar options :
 .Bl -tag -width indent
-.It Cm keep-state Op Ar method
+.It Xo Cm keep-state Op Ar method
+.Op Cm lifetime Ar number
+.Xc
 Upon a match, the firewall will create a dynamic rule, whose
-default behaviour is to matching bidirectional traffic between
+default behaviour is to match bidirectional traffic between
 source and destination IP/port using the same protocol.
-The rule has a limited lifetime (controlled by a set of
+The rule has a limited lifetime controlled by a set of
 .Xr sysctl 8
-variables), and the lifetime is refreshed every time a matching
-packet is found.
+variables that may be overridden on a per-rule basis.
+The lifetime is refreshed each time a matching packet is
+found.
 .Pp
 The actual behaviour can be modified by specifying a different
 .Ar method ,
 although at the moment only the default one is specified.
+.Pp
+The default rule lifetime may be overridden for a specific
+rule by appending
+.Cm lifetime Ar number
+to explicitly set the number of seconds for the dynamic rule
+lifetime.
+.Pp
+For TCP rules, explicitly setting a rule lifetime overrides the
+default setting stored in the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.dyn_ack_lifetime .
+For non-TCP rules, it overrides the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.dyn_short_lifetime
+instead.
 .It Cm bridged
 Matches only bridged packets.
 This can be useful for multicast or broadcast traffic, which

==========PATCHES TO STABLE BELOW==========
--- /usr/src/sys/netinet/ip_fw.h.orig	Tue Feb 20 04:39:17 2001
+++ /usr/src/sys/netinet/ip_fw.h	Fri Jul  6 10:48:11 2001
@@ -74,6 +74,7 @@
 	u_short fu_skipto_rule;		/* SKIPTO command rule number */
 	u_short fu_reject_code;		/* REJECT response code */
 	struct sockaddr_in fu_fwd_ip;
+	u_int32_t fu_dyn_lifetime;	/* Explicit dynamic rule lifetime */
     } fw_un;
     u_char fw_prot;			/* IP protocol */
 	/*
@@ -122,6 +123,7 @@
 #define fw_reject_code	fw_un.fu_reject_code
 #define fw_pipe_nr	fw_un.fu_pipe_nr
 #define fw_fwd_ip	fw_un.fu_fwd_ip
+#define fw_dyn_lifetime	fw_un.fu_dyn_lifetime
 
 struct ip_fw_chain {
 	LIST_ENTRY(ip_fw_chain) next;
@@ -148,6 +150,7 @@
     struct ipfw_flow_id mask ;
     struct ip_fw_chain *chain ;		/* pointer to parent rule	*/
     u_int32_t type ;			/* rule type			*/
+    u_int32_t lifetime ;		/* per-rule specified lifetime  */
     u_int32_t expire ;			/* expire time			*/
     u_int64_t pcnt, bcnt;		/* match counters		*/
     u_int32_t bucket ;			/* which bucket in hash table	*/
--- /usr/src/sys/netinet/ip_fw.c.orig	Tue Mar 27 22:19:00 2001
+++ /usr/src/sys/netinet/ip_fw.c	Fri Jul  6 10:48:12 2001
@@ -730,7 +730,7 @@
 	    break ;
 	case TH_SYN | (TH_SYN << 8) :
 	    /* move to established */
-	    q->expire = time_second + dyn_ack_lifetime ;
+	    q->expire = time_second + q->lifetime ;
 	    break ;
 	case TH_SYN | (TH_SYN << 8) | TH_FIN :
 	case TH_SYN | (TH_SYN << 8) | (TH_FIN << 8) :
@@ -755,7 +755,7 @@
 	}
     } else {
 	/* should do something for UDP and others... */
-	q->expire = time_second + dyn_short_lifetime ;
+	q->expire = time_second + q->lifetime ;
     }
     if (match_direction)
 	*match_direction = dir ;
@@ -801,7 +801,14 @@
     if (mask)
 	r->mask = *mask ;
     r->id = *id ;
-    r->expire = time_second + dyn_syn_lifetime ;
+    r->lifetime = chain->rule->fw_dyn_lifetime ;
+    if (r->id.proto == IPPROTO_TCP) {
+	r->lifetime = r->lifetime ? r->lifetime : dyn_ack_lifetime ;
+	r->expire = time_second + dyn_syn_lifetime ;
+    } else {
+	r->lifetime = r->lifetime ? r->lifetime : dyn_short_lifetime ;
+	r->expire = time_second + r->lifetime ;
+    }
     r->chain = chain ;
     r->type = ((struct ip_fw_ext *)chain->rule)->dyn_type ;
 
--- /usr/src/sbin/ipfw/ipfw.c.orig	Tue Feb 20 04:39:11 2001
+++ /usr/src/sbin/ipfw/ipfw.c	Fri Jul  6 10:48:12 2001
@@ -391,6 +391,8 @@
                     printf(" keep-state %d", (int)chain->next_rule_ptr);
                 else
                     printf(" keep-state");
+		if (chain->fw_dyn_lifetime)
+		    printf(" lifetime %d", (int)chain->fw_dyn_lifetime);
         }
         /* Direction */
         if (chain->fw_flg & IP_FW_BRIDGED)
@@ -845,6 +847,7 @@
 "    ipoptions [!]{ssrr|lsrr|rr|ts},...\n"
 "    tcpoptions [!]{mss|window|sack|ts|cc},...\n"
 "    icmptypes {type[,type]}...\n"
+"    keep-state [lifetime <seconds>]\n"
 "  pipeconfig:\n"
 "    {bw|bandwidth} <number>{bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n"
 "    {bw|bandwidth} interface_name\n"
@@ -1839,6 +1842,15 @@
                             (int)rule.next_rule_ptr = type ;
                             av++; ac--;
                         }
+			if (ac > 0 && !strncmp(*av,"lifetime",strlen(*av))) {
+			    u_long lifetime ;
+
+			    av++; ac--;
+			    if (ac > 0 && (lifetime = atoi(*av)) != 0) {
+				rule.fw_dyn_lifetime = lifetime;
+				av++; ac--;
+			    }
+			}
                         continue;
                 }
                 if (!strncmp(*av,"bridged",strlen(*av))) { 
--- /usr/src/sbin/ipfw/ipfw.8.orig	Wed Apr 25 20:17:54 2001
+++ /usr/src/sbin/ipfw/ipfw.8	Fri Jul  6 10:48:12 2001
@@ -622,18 +622,38 @@
 interface.
 .It Ar options :
 .Bl -tag -width indent
-.It Cm keep-state Op Ar method
+.It Xo Cm keep-state Op Ar method
+.Op Cm lifetime Ar number
+.Xc
 Upon a match, the firewall will create a dynamic rule, whose
-default behaviour is to matching bidirectional traffic between
+default behaviour is to match bidirectional traffic between
 source and destination IP/port using the same protocol.
-The rule has a limited lifetime (controlled by a set of
+The rule has a limited lifetime controlled by a set of
 .Xr sysctl 8
-variables), and the lifetime is refreshed every time a matching
-packet is found.
+variables that may be overridden on a per-rule basis.
+The lifetime is refreshed each time a matching packet is
+found.
 .Pp
 The actual behaviour can be modified by specifying a different
 .Ar method ,
 although at the moment only the default one is specified.
+.Pp
+The default rule lifetime may be overridden for a specific
+rule by appending
+.Cm lifetime Ar number
+to explicitly set the number of seconds for the dynamic rule
+lifetime.
+.Pp
+For TCP rules, explicitly setting a rule lifetime overrides the
+default setting stored in the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.dyn_ack_lifetime .
+For non-TCP rules, it overrides the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.dyn_short_lifetime
+instead.
 .It Cm bridged
 Matches only bridged packets.
 This can be useful for multicast or broadcast traffic, which

==========END OF PATCHES==========


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010706170331.2D808210F5>