From okor@salut.ru  Mon Dec  9 04:47:37 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 E579437B401
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  9 Dec 2002 04:47:37 -0800 (PST)
Received: from mx.salut.ru (mx.salut.ru [194.67.150.72])
	by mx1.FreeBSD.org (Postfix) with ESMTP id E503F43EB2
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  9 Dec 2002 04:47:35 -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 gB9ClQni074026
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 9 Dec 2002 15:47:26 +0300 (MSK)
	(envelope-from okor@salut.ru)
Received: (from okor@localhost)
	by bazamot.salut.ru (8.12.6/8.12.6/Submit) id gB9ClPLe074025;
	Mon, 9 Dec 2002 15:47:25 +0300 (MSK)
	(envelope-from okor)
Message-Id: <200212091247.gB9ClPLe074025@bazamot.salut.ru>
Date: Mon, 9 Dec 2002 15:47:25 +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:         46124
>Category:       kern
>Synopsis:       ipfw dynamic rules lifetime feature
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 09 04:50:00 PST 2002
>Closed-Date:    Tue Dec 17 18:44:52 PST 2002
>Last-Modified:  Tue Dec 17 18:44:52 PST 2002
>Originator:     Oleg Koreshkov
>Release:        FreeBSD 4.7-RELEASE i386
>Organization:
>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...)

  ernel part of ipfw extended by adding extra field 'dyn_lifetime' in
  p_fw structure. Userland utility ``ipfw'' extended by adding rule
  ption ``lifetime <NNN>''. This option may be used standalone or
  ith ``keep-state'' / ``limit'' rules.

  or TCP packets it option replaces lifetime for sessions in established
  tate (if no ``lifetime'' option apeared, then default
  s 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:
>Fix:

 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)

 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:
Class-Changed-From-To: sw-bug->change-request 
Class-Changed-By: keramida 
Class-Changed-When: Sat Dec 14 03:48:13 PST 2002 
Class-Changed-Why:  
Fix class using the data that was edited away in the misfiled PR text. 


Responsible-Changed-From-To: gnats-admin->freebsd-bugss 
Responsible-Changed-By: keramida 
Responsible-Changed-When: Sat Dec 14 03:48:13 PST 2002 
Responsible-Changed-Why:  
Set owner to freebsd-bugs for misfiled PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=46124 
Responsible-Changed-From-To: freebsd-bugss->freebsd-bugs 
Responsible-Changed-By: keramida 
Responsible-Changed-When: Sat Dec 14 03:50:14 PST 2002 
Responsible-Changed-Why:  
Fix typo in the reponsible name for this PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=46124 
State-Changed-From-To: open->closed 
State-Changed-By: keramida 
State-Changed-When: Tue Dec 17 18:43:24 PST 2002 
State-Changed-Why:  

Superseded by PR 46159. 

Many thanks to Oleg Koreshkov <okor@salut.ru> for pointing out 
that these two PRs are, in fact, identical. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=46124 
>Unformatted:
