Bug 21118

Summary: Multiple problems in ipfw's stateful code
Product: Base System Reporter: missnglnk <missnglnk>
Component: kernAssignee: Luigi Rizzo <luigi>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description missnglnk 2000-09-08 15:50:00 UTC
	When a connection is made and kept track of (keep-state):
	1) Connections expire prematurely if dynamic ACK lifetime
	   is is greater than the keepalive interval.

	2) Expired connections aren't actually expired, but are
	   allowed to continue (TCP connections are extended by
	   the dynamic RST lifetime even though they have expired,
	   and all other protocol connections are extended by
	   the dynamic short lifetime).

	3) Expired connections aren't cleaned from the state table
	   unless the next dynamic rule added reaches the maximum
	   amount of dynamic rules.

	4) A new state is installed for any packet which matches
	   the rule (with keep-state), regardless of whether its
	   not a TCP packet with the SYN flag set, or if its an
	   ICMP query packet.

Fix: Nothing for problem 1, but solutions for 2-4 are in the below
	patch:

-- snip --
How-To-Repeat: 
	ipfw -f flush
	ipfw add check-state
	ipfw add allow ip from any to any via fxp0 out keep-state
	ipfw add deny ip from any to any

	Now issue a couple of connections, I did SSH, a new state
	was installed, the rule expired, but I still could continue
	my SSH connection since its expiration time was being extended
	by the dynamic RST lifetime.

	Instead of issuing a TCP packet with the SYN flag set, issue
	a TCP packet with any other flag set, and a new state is
	installed for this packet.

	Let a couple of dynamic rules timeout (you can check via ipfw
	show), and watch as they linger around, they aren't cleaned
	out until the amount of dynamic rules is equal to the maximum
	and a new rule is being installed.
Comment 1 Johan Karlsson freebsd_committer freebsd_triage 2000-09-16 13:10:52 UTC
Responsible Changed
From-To: freebsd-bugs->luigi

Over to ipfw maintainer.
Comment 2 Luigi Rizzo freebsd_committer freebsd_triage 2001-09-03 21:09:13 UTC
State Changed
From-To: open->closed

The PR addresses 4 issues: 
#1 This is the way the code currently works. There is no way out other 
than setting the timeout larger than the keepalive interval, or 
having ipfw do its own keepalives. The latter is the right way 
to handle this problem but it requires relatively large changes. 

#2 and #4 This is correct behaviour for the rules used in the PR. If 
you want connections to expire (more correctly, if you want 
dynamic rules to be created only on SYN packets) you should use 
the "setup" option in the rule e.g. 

ipfw add allow ip from any to any setup keep-state 
ipfw add deny ip from any to any. 

The "problem" is entirely caused by the use of wrong rules. 

#3 Again this is a design decision to reduce the overhead of 
garbage collection. 
Expired rules are removed only when you run out of space, 
or you happen to hit one of them during a lookup. 
There is no reason to do it otherwise. 

So, i am inclined to close this PR -- none of the above is a problem 
in the ipfw code.