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
signature.asc
Description: This is a digitally signed message part.
