On Wednesday 05 September 2007, Rian Shelley wrote:
> As far as I can tell, am having the same problem described by bill
> marquette. I have two firewalls using pfsync, where the secondary
> firewall just increases its state count steadily.
>
> I created a simple libpcap program to watch the pfsync headers flowing
> by, and i see types 8, 4, 2, which are PFSYNC_ACT_UREQ,
> PFSYNC_ACT_UPD_C, PFSYNC_ACT_UPD. I dont see any of type 3 or 5, which
> are the ones that delete state. As far as i can tell, states are
> pumped across the link, but never removed and are left to time out on
> their own.

Very good observation.  I don't quite believe that you don't see *any* 
three or fives, but I do see that those would get lost most easily.  The 
problem stems from the way states are purged in 3.7/RELENG_6.  Newer pf 
4.1/(soon to be)RELENG_7 splits the state removal.

I'm attaching a *very* experimental *HACK* that might help the situation.  
I believe however, that you would be better off with moving to 
4.1/RELENG_6 (patches at [1]) or 4.1/RELENG_7 as soon as it's done.  The 
state purge is one of the biggest weaknesses of 3.7/RELENG_6 which isn't 
easily solveable.

Another way to go is setting the queuelength for the internal processing 
queue to something insanely high (1000+).  This will most likely work 
around the problem at the cost of burning (mbuf) memory.

[1] http://people.freebsd.org/~mlaier/PF41/

-- 
/"\  Best regards,                      | [EMAIL PROTECTED]
\ /  Max Laier                          | ICQ #67774661
 X   http://pf4freebsd.love2party.net/  | [EMAIL PROTECTED]
/ \  ASCII Ribbon Campaign              | Against HTML Mail and News
Index: pf.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/contrib/pf/net/pf.c,v
retrieving revision 1.34.2.5
diff -u -r1.34.2.5 pf.c
--- pf.c	28 Jul 2007 22:32:57 -0000	1.34.2.5
+++ pf.c	9 Aug 2007 20:51:42 -0000
@@ -1145,17 +1145,34 @@
 	pf_status.states--;
 }
 
+static struct pf_state *pf_purge_pickup;
+
 void
 pf_purge_expired_states(void)
 {
 	struct pf_state		*cur, *next;
+	int			 max_purge = 5000;
+
+	if (pf_purge_pickup != NULL)
+		cur = pf_purge_pickup;
+	else
+		cur = RB_MIN(pf_state_tree_id, &tree_id);
 
-	for (cur = RB_MIN(pf_state_tree_id, &tree_id);
-	    cur; cur = next) {
+	pf_purge_pickup = NULL;
+	for (;cur && max_purge; max_purge--, cur = next) {
 		next = RB_NEXT(pf_state_tree_id, &tree_id, cur);
 		if (pf_state_expires(cur) <= time_second)
 			pf_purge_expired_state(cur);
 	}
+	if (max_purge) {
+		cur = RB_MIN(pf_state_tree_id, &tree_id);
+		for (;cur && max_purge; max_purge--, cur = next) {
+			next = RB_NEXT(pf_state_tree_id, &tree_id, cur);
+			if (pf_state_expires(cur) <= time_second)
+				pf_purge_expired_state(cur);
+		}
+	}
+	pf_purge_pickup = cur;
 }
 
 int

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to