Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Dec 2002 12:40:02 +0300 (MSK)
From:      Oleg Koreshkov <okoreshkov@salut.ru>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/46159: ipfw dynamic rules lifetime feature
Message-ID:  <200212100940.gBA9e254017726@bazamot.salut.ru>

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

>Number:         46159
>Category:       kern
>Synopsis:       ipfw dynamic rules lifetime feature
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>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:
>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:
>Unformatted:

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?200212100940.gBA9e254017726>