From okor@salut.ru  Tue Dec 10 01:40:14 2002
Return-Path: <okor@salut.ru>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id D334437B401
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 10 Dec 2002 01:40:14 -0800 (PST)
Received: from mx.salut.ru (mx.salut.ru [194.67.150.72])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 9B96543EBE
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 10 Dec 2002 01:40:12 -0800 (PST)
	(envelope-from okor@salut.ru)
Received: from bazamot.salut.ru (mx.salut.ru [194.67.150.72])
	by mx.salut.ru (ESMTP daemon) with ESMTP id gBA9e3rB017727
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 10 Dec 2002 12:40:03 +0300 (MSK)
	(envelope-from okor@salut.ru)
Received: (from root@localhost)
	by bazamot.salut.ru (8.12.6/8.12.6/Submit) id gBA9e254017726;
	Tue, 10 Dec 2002 12:40:02 +0300 (MSK)
	(envelope-from okor)
Message-Id: <200212100940.gBA9e254017726@bazamot.salut.ru>
Date: Tue, 10 Dec 2002 12:40:02 +0300 (MSK)
From: Oleg Koreshkov <okoreshkov@salut.ru>
Reply-To: Oleg Koreshkov <okoreshkov@salut.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: ipfw dynamic rules lifetime feature
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         46159
>Category:       kern
>Synopsis:       [ipfw] [patch] [request] ipfw dynamic rules lifetime feature
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ipfw
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 10 01:50:01 PST 2002
>Closed-Date:    
>Last-Modified:  Sat Jan 26 04:48:33 UTC 2008
>Originator:     Oleg Koreshkov
>Release:        FreeBSD 4.7-RELEASE i386
>Organization:
A LOT OF...
>Environment:
System: FreeBSD xxxx.xxx.xx 4.7-RELEASE-p2 FreeBSD 4.7-RELEASE-p2 #8:
Thu Nov 14 18:48:42 MSK 2002 root@xxx.xxx.xx:/usr/obj/usr/src/sys/XXXXXXX i386

>Description:

        When you use stateful filtering (with ipfw) it sometimes useful
        to have different default lifetime for dynamic rules according
        to rule body (not only for protocol). For example, on very busy
        web server it's advisable to keep 'net.inet.ip.fw.dyn_ack_lifetime'
        moderately short, while allow other types of tcp sessions
        (smtp,ftp,ssh etc...) exist without any limitations. Another example
        is allow udp/icmp packets that are outgoing from our iface have a
        long dynamic rule lifetime, but for packets comes from other hosts -
        short one...  (because, for example, we can answer for ICMP query
        quite quickly, but we don't know how fast is remote host...)

 	Kernel part of ipfw extended by adding extra field 'dyn_lifetime' in
 	ip_fw structure. Userland utility ``ipfw'' extended by adding rule
 	option ``lifetime <NNN>''. This option may be used standalone or
 	with ``keep-state'' / ``limit'' rules.
  	
 	For TCP packets it option replaces lifetime for sessions in established
 	state (if no ``lifetime'' option apeared, then default
 	is net.inet.ip.fw.dyn_ack_lifetime).
        
        For UDP packets is replaces 'net.inet.ip.fw.dyn_udp_lifetime'
        For ICMP and other packets is replaces 'net.inet.ip.fw.dyn_short_lifetime'
        
        So, while we have default lifetime for TCP sessions in established state
        (kept in kern sysctl 'net.inet.ip.fw.dyn_ack_lifetime'), we may want
        to explicitly define it for other sessions:
        # ipfw add 1000 pass tcp from me to any setup lifetime 7200
        this example mean, that dynamic rules created from this rule will
        have ``dyn_ack_lifetime'' equal to 7200 seconds (2 hours).
 
        

>How-To-Repeat:

use patch below:

cd /usr/src
patch < ipfw.lifetime.patch

rebuild and install your kernel (and/or) ipfw kernel module...
rebuild ipfw and libalias (and all that statically use this library)
	
>Fix:
	
ipfw.lifetime.patch:
====================================================================================
--- sys/netinet/ip_fw.h	1.47.2.11 2002/07/09
+++ sys/netinet/ip_fw.h
@@ -159,6 +159,7 @@
 #define	DYN_DST_PORT	0x8
 
 	u_short		conn_limit;	/* # of connections for limit rule */
+	u_int32_t	dyn_lifetime;	/* lifetime for dynamic rule */
 };
 
 #define	fw_divert_port	fw_un.fu_divert_port
--- sys/netinet/ip_fw.c	1.131.2.35 2002/07/29
+++ sys/netinet/ip_fw.c
@@ -783,12 +783,12 @@
 	    break ;
 	case TH_SYN | (TH_SYN << 8) :
 	    /* move to established */
-	    q->expire = time_second + dyn_ack_lifetime ;
+	    q->expire = time_second + (q->rule->dyn_lifetime?q->rule->dyn_lifetime:dyn_ack_lifetime) ; 
 	    break ;
 	case TH_SYN | (TH_SYN << 8) | TH_FIN :
 	case TH_SYN | (TH_SYN << 8) | (TH_FIN << 8) :
 	    /* one side tries to close */
-	    q->expire = time_second + dyn_ack_lifetime ;
+	    q->expire = time_second + (q->rule->dyn_lifetime?q->rule->dyn_lifetime:dyn_ack_lifetime) ; 
 	    break ;
 	case TH_SYN | (TH_SYN << 8) | TH_FIN | (TH_FIN << 8) :
 	    /* both sides closed */
@@ -807,10 +807,10 @@
 	    break ;
 	}
     } else if (pkt->proto == IPPROTO_UDP) {
-	q->expire = time_second + dyn_udp_lifetime ;
+	q->expire = time_second + (q->rule->dyn_lifetime?q->rule->dyn_lifetime:dyn_udp_lifetime) ;
     } else {
 	/* other protocols */
-	q->expire = time_second + dyn_short_lifetime ;
+	q->expire = time_second + (q->rule->dyn_lifetime?q->rule->dyn_lifetime:dyn_short_lifetime) ;
     }
     if (match_direction)
 	*match_direction = dir ;
@@ -2083,6 +2083,7 @@
 
 	ip_fw_default_rule = LIST_FIRST(&ip_fw_chain_head) ;
 	printf("IP packet filtering initialized, "
+		"lifetime feature enabled, "
 #ifdef IPDIVERT
 		"divert enabled, "
 #else
--- sbin/ipfw/ipfw.c	1.80.2.24 2002/09/26
+++ sbin/ipfw/ipfw.c
@@ -402,6 +402,8 @@
 			printf(" %d", chain->conn_limit);
 			break ;
 		}
+		if(chain->dyn_lifetime)
+			printf(" lifetime %d",chain->dyn_lifetime);
 	}
 	/* Direction */
 	if (chain->fw_flg & IP_FW_BRIDGED)
@@ -890,6 +892,7 @@
 "    tcpoptions [!]{mss|window|sack|ts|cc}, ...\n"
 "    icmptypes {type[, type]}...\n"
 "    keep-state [method]\n"
+"    lifetime <number>\n"
 "  pipeconfig:\n"
 "    {bw|bandwidth} <number>{bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n"
 "    {bw|bandwidth} interface_name\n"
@@ -1958,6 +1961,16 @@
 				rule.dyn_type = type;
 				av++; ac--;
 			}
+		} else if (!strncmp(*av, "lifetime", strlen(*av))) {
+			u_int32_t dyn_lifetime;
+			rule.fw_flg |= IP_FW_F_KEEP_S;
+
+			av++; ac--;
+			if (ac > 0 && (dyn_lifetime = atoi(*av)) != 0) {
+				rule.dyn_lifetime = dyn_lifetime;
+				av++; ac--;
+			} else errx(EX_USAGE, "``lifetime'' needs"
+				    " dynamic rule lifetime (seconds)");
 		} else if (!strncmp(*av, "bridged", strlen(*av))) {
 			rule.fw_flg |= IP_FW_BRIDGED;
 			av++; ac--;
====================================================================================



>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->ipfw 
Responsible-Changed-By: johan 
Responsible-Changed-When: Tue May 6 12:58:45 PDT 2003 
Responsible-Changed-Why:  
Over to maintainer group. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=46159 

From: "Aaron Gifford" <astounding@gmail.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/46159: [ipfw] [patch] ipfw dynamic rules lifetime feature
Date: Sat, 26 Aug 2006 19:24:28 -0600

 ------=_Part_157133_22428623.1156641868079
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline
 
 Various PRs that have dealt with this issue:
   kern/46159 (still open)
   kern/28713 (closed, but should not have been in my opinion)
   kern/22065 (closed in favor of kern/28713)
 
 
 Hi,
 
 Here is the latest up-to-date version of the ipfw dynamic rule lifetime
 feature patch for 6.1-STABLE (STABLE as of 16 Aug. 2006) taken from my
 personal web site at http://www.adg.us/computers/ipfwpatch.html (currently
 down/unreachable due to gvinum issues, but should be back shortly) where
 patches for versions are available for FreeBSD from the 4.x and 5.x eras as
 well:
 
 I would very much like to see this feature become part of the mainstream
 distribution.  Even with ipfw's built-in keepalive mechanisms, per-rule
 lifetime controls remain a powerful tool in my opinion, and as Oleg
 Koreshkov indicated in his PR submission, very likely in his opinion too.
 It grants firewall administrators much greater control over the flow network
 traffic.
 
 The per-rule lifetime features have been in use on many production machines
 that I manage for well over six years now.  There have been zero stability
 issues.  The patches to add these features are simple and straightforward.
 
 There have been no negative problems brought up at any time in the past when
 I have posted about the patches to public mailing lists, and no negative
 problems mentioned in any of the PR reports submitted.  The only arguments
 against inclusion were that the features were not useful.  I believe that
 was just the personal opinion of one of the maintainers at the time (and I
 respect his opinion and his FreeBSD contributions, but in this particular
 case respectfully disagree), but it doesn't account for the usefulness that
 I and others have found even after ipfw added built-in keepalive abilities.
 
 On various hosts I have used the lifetime features, when ipfw keepalives
 were added, I rewrote my rulesets to remove the use of per-rule lifetimes in
 hopes that I could stop maintaining the patchsets.  Unfortunately, I
 discovered there were places in my own rulesets where keepalives could not
 fully replace the per-rule lifetime features, and so I've had to keep
 maintaining the patches to add these features to ipfw as I have done for
 over six years now.
 
 So please carefully consider adding per-rule lifetimes to ipfw rules.
 They're useful.  I think a wider audience of ipfw network admins. will find
 them useful.
 
 Thank you.
 Aaron Gifford
 
 --- /usr/src/sys/netinet/ip_fw.h.orig   Sat Jul 29 02:24:12 2006
 +++ /usr/src/sys/netinet/ip_fw.h        Wed Aug 16 14:52:55 2006
 @@ -101,7 +101,7 @@
         O_VERSRCREACH,          /* none                         */
 
         O_PROBE_STATE,          /* none                         */
 -       O_KEEP_STATE,           /* none                         */
 +       O_KEEP_STATE,           /* u32 = optional lifetime      */
         O_LIMIT,                /* ipfw_insn_limit              */
         O_LIMIT_PARENT,         /* dyn_type, not an opcode.     */
 
 @@ -432,6 +432,7 @@
         u_int64_t       bcnt;           /* byte match counter           */
         struct ipfw_flow_id id;         /* (masked) flow id             */
         u_int32_t       expire;         /* expire time                  */
 +       u_int32_t       lifetime;       /* per-rule lifetime            */
         u_int32_t       bucket;         /* which bucket in hash table   */
         u_int32_t       state;          /* state of this rule (typically a
                                          * combination of TCP flags)
 --- /usr/src/sys/netinet/ip_fw2.c.orig  Sat Jul 29 02:24:12 2006
 +++ /usr/src/sys/netinet/ip_fw2.c       Wed Aug 16 14:54:37 2006
 @@ -1261,7 +1261,7 @@
                                 }
                             }
                         }
 -                       q->expire = time_second + dyn_ack_lifetime;
 +                       q->expire = time_second + q->lifetime;
                         break;
 
                 case BOTH_SYN | BOTH_FIN:       /* both sides closed */
 @@ -1284,11 +1284,16 @@
                         q->expire = time_second + dyn_rst_lifetime;
                         break;
                 }
 -       } else if (pkt->proto == IPPROTO_UDP) {
 -               q->expire = time_second + dyn_udp_lifetime;
         } else {
 -               /* other protocols */
 -               q->expire = time_second + dyn_short_lifetime;
 +               /*
 +                * UDP and other protocols:
 +                *   NOTE: The value of q->lifetime was set at the time this
 +                *   dynamic rule was created.  It was either explicitly set
 +                *   by the ruleset creator to a specific value, or was pre-
 +                *   set to either dyn_udp_lifetime for UDP, or to
 +                *   dyn_short_lifetime for non-UDP protocols.
 +                */
 +               q->expire = time_second + q->lifetime;
         }
  done:
         if (match_direction)
 @@ -1350,7 +1355,8 @@
   * - "parent" rules for the above (O_LIMIT_PARENT).
   */
  static ipfw_dyn_rule *
 -add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw
 *rule)
 +add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw
 *rule,
 +            u_int32_t lifetime)
  {
         ipfw_dyn_rule *r;
         int i;
 @@ -1382,7 +1388,20 @@
         }
 
         r->id = *id;
 -       r->expire = time_second + dyn_syn_lifetime;
 +       r->lifetime = lifetime;
 +       if (r->id.proto == IPPROTO_TCP) {
 +               r->lifetime = r->lifetime ? r->lifetime : dyn_ack_lifetime;
 +               r->expire = time_second + dyn_syn_lifetime;
 +       } else {
 +               if (r->lifetime == 0) {
 +                       if (r->id.proto == IPPROTO_UDP) {
 +                               r->lifetime = dyn_udp_lifetime;
 +                       } else {
 +                               r->lifetime = dyn_short_lifetime;
 +                       }
 +               }
 +               r->expire = time_second + r->lifetime;
 +       }
         r->rule = rule;
         r->dyn_type = dyn_type;
         r->pcnt = r->bcnt = 0;
 @@ -1437,7 +1456,7 @@
                                 return q;
                         }
         }
 -       return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
 +       return add_dyn_rule(pkt, O_LIMIT_PARENT, rule, 0);
  }
 
  /**
 @@ -1490,7 +1509,8 @@
 
         switch (cmd->o.opcode) {
         case O_KEEP_STATE:      /* bidir rule */
 -               add_dyn_rule(&args->f_id, O_KEEP_STATE, rule);
 +               add_dyn_rule(&args->f_id, O_KEEP_STATE, rule,
 +                            ((ipfw_insn_u32 *)cmd)->d[0]);
                 break;
 
         case O_LIMIT: {         /* limit number of sessions */
 @@ -1549,7 +1569,7 @@
                                 return (1);
                         }
                 }
 -               add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent);
 +               add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent,
 0);
                 break;
         }
         default:
 @@ -3645,7 +3665,6 @@
                 DEB(printf("ipfw: opcode %d\n", cmd->opcode);)
                 switch (cmd->opcode) {
                 case O_PROBE_STATE:
 -               case O_KEEP_STATE:
                 case O_PROTO:
                 case O_IP_SRC_ME:
                 case O_IP_DST_ME:
 @@ -3677,6 +3696,7 @@
                                 goto bad_size;
                         break;
 
 +               case O_KEEP_STATE:
                 case O_UID:
                 case O_GID:
                 case O_JAIL:
 --- /usr/src/sbin/ipfw/ipfw2.c.orig     Mon Aug  7 13:32:57 2006
 +++ /usr/src/sbin/ipfw/ipfw2.c  Wed Aug 16 14:52:55 2006
 @@ -260,6 +260,7 @@
         TOK_IN,
         TOK_LIMIT,
         TOK_KEEPSTATE,
 +       TOK_LIFETIME,
         TOK_LAYER2,
         TOK_OUT,
         TOK_DIVERTED,
 @@ -394,6 +395,7 @@
         { "in",                 TOK_IN },
         { "limit",              TOK_LIMIT },
         { "keep-state",         TOK_KEEPSTATE },
 +       { "lifetime",           TOK_LIFETIME },
         { "bridged",            TOK_LAYER2 },
         { "layer2",             TOK_LAYER2 },
         { "out",                TOK_OUT },
 @@ -1939,6 +1941,8 @@
 
                         case O_KEEP_STATE:
                                 printf(" keep-state");
 +                               if (cmd32->d[0])
 +                                       printf(" lifetime %u", cmd32->d[0]);
                                 break;
 
                         case O_LIMIT: {
 @@ -3857,6 +3861,9 @@
 
         struct ip_fw *rule;
 
 +       /* Temporary pointer to the most recent keep-state command: */
 +       ipfw_insn_u32 *cmd_keepstate = (ipfw_insn_u32 *)0;
 +
         /*
          * various flags used to record that we entered some fields.
          */
 @@ -4558,7 +4565,20 @@
                                 errx(EX_USAGE, "only one of keep-state "
                                         "and limit is allowed");
                         have_state = cmd;
 -                       fill_cmd(cmd, O_KEEP_STATE, 0, 0);
 +                       cmd->opcode = O_KEEP_STATE;
 +                       cmd->len = F_INSN_SIZE(ipfw_insn_u32);
 +                       cmd32->d[0] = 0;
 +                       cmd_keepstate = cmd32;
 +                       break;
 +
 +               case TOK_LIFETIME:
 +                       if (cmd_keepstate == (ipfw_insn_u32 *)0)
 +                               errx(EX_USAGE, "lifetime must immediately "
 +                                       "follow keep-state");
 +                       NEED1("lifetime requires # of seconds");
 +                       cmd_keepstate->d[0] = strtoul(*av, NULL, 0);
 +                       cmd_keepstate = (ipfw_insn_u32 *)0;
 +                       ac--; av++;
                         break;
 
                 case TOK_LIMIT: {
 --- /usr/src/sbin/ipfw/ipfw.8.orig      Sat Jul 29 02:24:12 2006
 +++ /usr/src/sbin/ipfw/ipfw.8   Wed Aug 16 14:52:55 2006
 @@ -1282,14 +1282,35 @@
  .It Cm ipversion Ar ver
  Matches IP packets whose IP version field is
  .Ar ver .
 -.It Cm keep-state
 +.It Xo Cm keep-state
 +.Op Cm lifetime Ar number
 +.Xc
  Upon a match, the firewall will create a dynamic rule, whose
  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
 +variables, and the lifetime is refreshed every time a matching
  packet is found.
 +.Pp
 +The default limited rule lifetime behavior may be modified
 +for a specific rule by appending
 +.Cm lifetime Ar number
 +immediately after
 +.Cm keep-state .
 +Doing so will explicitly set the dynamic rule lifetime to the
 +specified number of seconds, overriding the default lifetime
 +behavior for the specified rule.
 +.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 UDP rules, it overrides
 +.Em net.inet.ip.fw.dyn_udp_lifetime .
 +For all other rules, it overrides
 +.Em net.inet.ip.fw.dyn_short_lifetime .
  .It Cm layer2
  Matches only layer2 packets, i.e., those passed to
  .Nm
 
 ------=_Part_157133_22428623.1156641868079
 Content-Type: text/html; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline
 
 Various PRs that have dealt with this issue:<br>&nbsp; kern/46159 (still open)<br>&nbsp; kern/28713 (closed, but should not have been in my opinion)<br>&nbsp; kern/22065 (closed in favor of kern/28713)<br><br><br>Hi,<br><br>Here is the latest up-to-date version of the ipfw dynamic rule lifetime feature patch for 
 6.1-STABLE (STABLE as of 16 Aug. 2006) taken from my personal web site at <a href="http://www.adg.us/computers/ipfwpatch.html">http://www.adg.us/computers/ipfwpatch.html</a> (currently down/unreachable due to gvinum issues, but should be back shortly) where patches for versions are available for FreeBSD from the 
 4.x and 5.x eras as well:<br><br>I would very much like to see this feature become part of the mainstream distribution.&nbsp; Even with ipfw's built-in keepalive mechanisms, per-rule lifetime controls remain a powerful tool in my opinion, and as 
 Oleg Koreshkov indicated in his PR submission, very likely in his opinion too.&nbsp; It grants firewall administrators much greater control over the flow network traffic.<br><br>The per-rule lifetime features have been in use on many production machines that I manage for well over six years now.&nbsp; There have been zero stability issues.&nbsp; The patches to add these features are simple and straightforward.
 <br><br>There have been no negative problems brought up at any time in the past when I have posted about the patches to public mailing lists, and no negative problems mentioned in any of the PR reports submitted.&nbsp; The only arguments against inclusion were that the features were not useful.&nbsp; I believe that was just the personal opinion of one of the maintainers at the time (and I respect his opinion and his FreeBSD contributions, but in this particular case respectfully disagree), but it doesn't a ccount for the usefulness that I and others have found even after ipfw added built-in keepalive abilities.
 <br><br>On various hosts I have used the lifetime features, when ipfw keepalives were added, I rewrote my rulesets to remove the use of per-rule lifetimes in hopes that I could stop maintaining the patchsets.&nbsp; Unfortunately, I discovered there were places in my own rulesets where keepalives could not fully replace the per-rule lifetime features, and so I've had to keep maintaining the patches to add these features to ipfw as I have done for over six years now.
 <br><br>So please carefully consider adding per-rule lifetimes to ipfw rules.&nbsp; They're useful.&nbsp; I think a wider audience of ipfw network admins. will find them useful.<br><br>Thank you.<br>Aaron Gifford<br><br>--- /usr/src/sys/netinet/ip_fw.h.orig&nbsp;&nbsp; Sat Jul 29 02:24:12 2006
 <br>+++ /usr/src/sys/netinet/ip_fw.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Wed Aug 16 14:52:55 2006<br>@@ -101,7 +101,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_VERSRCREACH,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_PROBE_STATE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp; /* none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
 <br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_KEEP_STATE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_KEEP_STATE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* u32 = optional lifetime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_LIMIT,&nbsp;&nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* ipfw_insn_limit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; O_LIMIT_PARENT,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* dyn_type, not an opcode.&nbsp;&nbsp;&nbsp;&nbsp; */
 <br><br>@@ -432,6 +432,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_int64_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bcnt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* byte match counter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ipfw_flow_id id;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* (masked) flow id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; u_int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expire;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* expire time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
 <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lifetime;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* per-rule lifetime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bucket;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* which bucket in hash table&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; st ate;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* state of this rule (typically a
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * combination of TCP flags)<br>--- /usr/src/sys/netinet/ip_fw2.c.orig&nbsp; Sat Jul 29 02:24:12 2006<br>+++ /usr/src/sys/netinet/ip_fw2.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Wed Aug 16 14:54:37 2006<br>@@ -1261,7 +1261,7 @@
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br
>Unformatted:
 >-&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;expire = time_second + dyn_ack_lifetime;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;expire = time_second + q-&gt;lifetime;
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case  BOTH_SYN | BOTH_FIN:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* both sides closed */<br>@@ -1284,11 +1284,16 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&g t;ex pire = time_second + dyn_rst_lifetime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (pkt-&gt;proto == IPPROTO_UDP) {<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp; q-&gt;expire = time_second + dyn_udp_lifetime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* other protocols */<br>-&nbsp;&nbsp;&nbsp;&n bsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;expire = time_second + dyn_short_lifetime;
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * UDP and other protocols:<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; NOTE: The value of q-&gt;lifetime was set at the time this<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; dynamic rule wa s cr eated.&nbsp; It was either explicitly set
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; by the ruleset creator to a specific value, or was pre-<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp; *&nbsp;&nbsp; set to either dyn_udp_lifetime for UDP, or to<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; dyn_short_lifetime for non-UDP protocols.<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;expire = time_second + q-&gt;lifetime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;done:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (match _direction)<br>@@ -1350,7 +1355,8 @@<br>&nbsp; * - &quot;parent&quot; rules for the above (O_LIMIT_PARENT).<br>&nbsp; */<br>
  &nbsp;static ipfw_dyn_rule *<br>-add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)<br>+add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp; u_int32_t lifetime)
  <br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ipfw_dyn_rule *r;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>@@ -1382,7 +1388,20 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  r-&gt;id = *id;<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;expire = time_second + dyn_syn_lifetime;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;lifetime = lifetime;<br>
  +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (r-&gt;id.proto == IPPROTO_TCP) {<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;lifetime = r-&gt;lifetime ? r-&gt;lifetime : dyn_ack_lifetime;<br>+&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;expire = time_second + dyn_syn_lifetime;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>
  +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (r-&gt;lifetime == 0) {<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if  (r-&gt;id.proto == IPPROTO_UDP) {<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;lifetime = dyn_udp_lifetime;< br>+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;lifetime = dyn_short_lifetime;
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;expire = time_second + r-&gt;lifetime;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;rule = rule;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbsp ;&nbsp; r-&gt;dyn_type = dyn_type;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r-&gt;pcnt = r-&gt;bcnt = 0;
  <br>@@ -1437,7 +1456,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return q;<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);< br>+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return add_dyn_rule(pkt, O_LIMIT_PARENT, rule, 0);
  <br>&nbsp;}<br><br>&nbsp;/**<br>@@ -1490,7 +1509,8 @@<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (cmd-&gt;o.opcode) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_KEEP_STATE:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* bidir rule */<br>-&nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_dyn_rule(&amp;args-&gt;f_id, O_KEEP_STATE, rule);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_dyn_rule(&amp;args-&gt;f_id , O_ KEEP_STATE, rule,
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((ipfw_insn_u32 *)cmd)-&gt;d[0]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_LIMIT: {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* limit number of sessions */<br>@@ -1549,7 +1569,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (1);
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>-&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_dyn_rule(&amp;args-&gt;f_id, O_LIMIT, (struct ip_fw *)parent);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_dyn_rule(&amp;arg s-&g t;f_id, O_LIMIT, (struct ip_fw *)parent, 0);
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br>@@ -3645,7 +3665,6 @@<br>&nbsp;&nbsp;&nbsp;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEB(printf(&quot;ipfw: opcode %d\n&quot;, cmd-&gt;opcode);)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (cmd-&gt;opcode) {<br> &nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_PROBE_STATE:
  <br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_KEEP_STATE:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_PROTO:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_IP_SRC_ME:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_IP_DST_ME:<br>@@ -3677,6 +3696,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto bad_size;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br><br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_KEEP_ST ATE:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_UID:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_GID:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&n bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_JAIL:<br>--- /usr/src/sbin/ipfw/ipfw2.c.orig&nbsp;&nbsp;&nbsp;&nbsp; Mon Aug&nbsp; 7 13:32:57 2006
  <br>+++ /usr/src/sbin/ipfw/ipfw2.c&nbsp; Wed Aug 16 14:52:55 2006<br>@@ -260,6 +260,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_IN,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_LIMIT,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_KEE PSTATE,<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_LIFETIME,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_LAYER2,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_OUT,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_DIVERTED,<br>@@ -394,6 +395,7 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;in&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_IN },<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;limit&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_LIMIT },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;keep-state&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&n bsp;&nbsp;&nbsp; TOK_KEEPSTATE },<br>
  +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;lifetime&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_LIFETIME },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;bridged&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;&nbsp; TOK_LAYER2 },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;layer2&quot;,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_LAYER2 },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;out&quot;,&n bsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TOK_OUT },
  <br>@@ -1939,6 +1941,8 @@<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_KEEP_STATE:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot; keep-state&quot;);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nb sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cmd32-&gt;d[0])<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot; lifetime %u&quot;, cmd32-&gt;d[0]);
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case O_LIMIT: {<br>@@ -3857,6 +3861,9 @@<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ip_fw *rule;<br><br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Temp orar y pointer to the most recent keep-state command: */
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ipfw_insn_u32 *cmd_keepstate = (ipfw_insn_u32 *)0;<br>+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * various flags used to record that we entered some fi elds.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>@@ -4558,7 +4565,20 @@<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp; &nbsp;&nbsp;&nbsp; errx(EX_USAGE, &quot;only one of keep-state &quot;
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;and limi t is allowed&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; have_state = cmd;<br>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;& nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill_cmd(cmd, O_KEEP_STATE, 0, 0);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd-&gt;opcode =  O_KEEP_STATE;
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd-&gt;len = F_INSN_SIZE(ipfw_insn_u32);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd32-&gt;d[0] = 0;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd_keepstate = cmd32;<br>+&nbsp; &nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>+<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case TOK_LIFETIME:
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cmd_keepstate == (ipfw_insn_u32 *)0)<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errx(EX_USAGE, &quot;lifetime must immediately &quot;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& nbsp ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;follow keep-state&quot;);
  <br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEED1(&quot;lifetime requires # of seconds&quot;);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd_keepstate-&gt;d[0] = strtoul(*av, NULL, 0);<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb sp;  cmd_keepstate = (ipfw_insn_u32 *)0;<br>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ac--; av++;
  <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case  TOK_LIMIT: {<br>--- /usr/src/sbin/ipfw/ipfw.8.orig&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sat Jul 29 02:24:12 2006<br>+++ /usr/src/sbin/ipfw/ipfw.8&nbsp;&nbsp; Wed Aug 16 14:52:55 2006<br>@@ -1282,14 +1282,35 @@
  <br>&nbsp;.It Cm ipversion Ar ver<br>&nbsp;Matches IP packets whose IP version field is<br>&nbsp;.Ar ver .<br>-.It Cm keep-state<br>+.It Xo Cm keep-state<br>+.Op Cm lifetime Ar number<br>+.Xc<br>&nbsp;Upon a match, the firewall will create a dynamic rul e, whose
  <br>&nbsp;default behaviour is to match bidirectional traffic between<br>&nbsp;source and destination IP/port using the same protocol.<br>-The rule has a limited lifetime (controlled by a set of<br>+The rule has a limited lifetime controlled by a set of 
  <br>&nbsp;.Xr sysctl 8<br>-variables), and the lifetime is refreshed every time a matching<br>+variables, and the lifetime is refreshed every time a matching<br>&nbsp;packet is found.<br>+.Pp<br>+The default limited rule lifetime behavior may be modifie d
  <br>+for a specific rule by appending<br>+.Cm lifetime Ar number<br>+immediately after<br>+.Cm keep-state .<br>+Doing so will explicitly set the dynamic rule lifetime to the<br>+specified number of seconds, overriding the default lifetime
  <br>+behavior for the specified rule.<br>+.Pp<br>+For TCP rules, explicitly setting a rule lifetime overrides the<br>+default setting stored in the<br>+.Xr sysctl 8<br>+variable<br>+.Em net.inet.ip.fw.dyn_ack_lifetime .<br>
  +For UDP rules, it overrides<br>+.Em net.inet.ip.fw.dyn_udp_lifetime .<br>+For all other rules, it overrides<br>+.Em net.inet.ip.fw.dyn_short_lifetime .<br>&nbsp;.It Cm layer2<br>&nbsp;Matches only layer2 packets, i.e., those passed to
  <br>&nbsp;.Nm<br><br>
  
  ------=_Part_157133_22428623.1156641868079--
