In order to analyse this problem some more...
There is a patch attached to this email that will keep "orphans" in the
linked list
of state entries but will remove them from the state table (lookups will
not find
them.)
Output from "ipfstat -sl" will prepend the word "ORPHAN" to the first line
of an entry, should it encounter one...
Darren
Index: ip_state.c
===================================================================
RCS file: /devel/CVS/IP-Filter/ip_state.c,v
retrieving revision 2.186.2.49
diff -c -r2.186.2.49 ip_state.c
*** ip_state.c 28 Oct 2006 06:56:03 -0000 2.186.2.49
--- ip_state.c 8 Dec 2006 04:20:13 -0000
***************
*** 128,134 ****
static ipstate_t *fr_checkicmpmatchingstate __P((fr_info_t *));
static int fr_state_flush __P((int, int));
static ips_stat_t *fr_statetstats __P((void));
! static void fr_delstate __P((ipstate_t *, int));
static int fr_state_remove __P((caddr_t));
static void fr_ipsmove __P((ipstate_t *, u_int));
static int fr_tcpstate __P((fr_info_t *, tcphdr_t *, ipstate_t *));
--- 128,134 ----
static ipstate_t *fr_checkicmpmatchingstate __P((fr_info_t *));
static int fr_state_flush __P((int, int));
static ips_stat_t *fr_statetstats __P((void));
! static int fr_delstate __P((ipstate_t *, int));
static int fr_state_remove __P((caddr_t));
static void fr_ipsmove __P((ipstate_t *, u_int));
static int fr_tcpstate __P((fr_info_t *, tcphdr_t *, ipstate_t *));
***************
*** 301,307 ****
ipstate_t *is;
while ((is = ips_list) != NULL)
! fr_delstate(is, 0);
/*
* Proxy timeout queues are not cleaned here because although they
--- 301,307 ----
ipstate_t *is;
while ((is = ips_list) != NULL)
! fr_delstate(is, ISL_UNLOAD);
/*
* Proxy timeout queues are not cleaned here because although they
***************
*** 2838,2844 ****
/* and timeout queue lists. Make adjustments to hash table statistics and */
/* global counters as required. */
/* ------------------------------------------------------------------------ */
! static void fr_delstate(is, why)
ipstate_t *is;
int why;
{
--- 2838,2844 ----
/* and timeout queue lists. Make adjustments to hash table statistics and */
/* global counters as required. */
/* ------------------------------------------------------------------------ */
! static int fr_delstate(is, why)
ipstate_t *is;
int why;
{
***************
*** 2849,2864 ****
* Since we want to delete this, remove it from the state table,
* where it can be found & used, first.
*/
- if (is->is_pnext != NULL) {
- *is->is_pnext = is->is_next;
-
- if (is->is_next != NULL)
- is->is_next->is_pnext = is->is_pnext;
-
- is->is_pnext = NULL;
- is->is_next = NULL;
- }
-
if (is->is_phnext != NULL) {
*is->is_phnext = is->is_hnext;
if (is->is_hnext != NULL)
--- 2849,2854 ----
***************
*** 2904,2910 ****
*/
is->is_ref--;
if (is->is_ref > 0)
! return;
if (is->is_tqehead[0] != NULL) {
if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0)
--- 2894,2900 ----
*/
is->is_ref--;
if (is->is_ref > 0)
! return is->is_ref;
if (is->is_tqehead[0] != NULL) {
if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0)
***************
*** 2923,2928 ****
--- 2913,2931 ----
(void) ipsc_detachis(is);
#endif
+ /*
+ * Now remove it from the linked list of known states
+ */
+ if (is->is_pnext != NULL) {
+ *is->is_pnext = is->is_next;
+
+ if (is->is_next != NULL)
+ is->is_next->is_pnext = is->is_pnext;
+
+ is->is_pnext = NULL;
+ is->is_next = NULL;
+ }
+
if (ipstate_logging != 0 && why != 0)
ipstate_log(is, why);
***************
*** 2939,2944 ****
--- 2942,2949 ----
MUTEX_DESTROY(&is->is_lock);
KFREE(is);
ips_num--;
+
+ return 0;
}
***************
*** 3056,3063 ****
}
if (delete) {
! fr_delstate(is, ISL_FLUSH);
! removed++;
} else
isp = &is->is_next;
}
--- 3061,3070 ----
}
if (delete) {
! if (fr_delstate(is, ISL_FLUSH) == 0)
! removed++;
! else
! isp = &is->is_next;
} else
isp = &is->is_next;
}
***************
*** 3104,3111 ****
break;
tqn = tqe->tqe_next;
is = tqe->tqe_parent;
! fr_delstate(is, ISL_EXPIRE);
! removed++;
}
}
--- 3111,3118 ----
break;
tqn = tqe->tqe_next;
is = tqe->tqe_parent;
! if (fr_delstate(is, ISL_EXPIRE) == 0)
! removed++;
}
}
***************
*** 3118,3125 ****
break;
tqn = tqe->tqe_next;
is = tqe->tqe_parent;
! fr_delstate(is, ISL_EXPIRE);
! removed++;
}
}
if (try + interval > maxtick)
--- 3125,3132 ----
break;
tqn = tqe->tqe_next;
is = tqe->tqe_parent;
! if (fr_delstate(is, ISL_EXPIRE) == 0)
! removed++;
}
}
if (try + interval > maxtick)
Index: lib/printstate.c
===================================================================
RCS file: /devel/CVS/IP-Filter/lib/printstate.c,v
retrieving revision 1.11.2.9
diff -c -r1.11.2.9 printstate.c
*** lib/printstate.c 14 Jul 2006 06:12:27 -0000 1.11.2.9
--- lib/printstate.c 8 Dec 2006 04:19:32 -0000
***************
*** 17,22 ****
--- 17,24 ----
{
synclist_t ipsync;
+ if (sp->is_phnext == NULL)
+ PRINTF("ORPHAN ");
PRINTF("%s -> ", hostname(sp->is_v, &sp->is_src.in4));
PRINTF("%s pass %#x pr %d state %d/%d bkt %d\n",
hostname(sp->is_v, &sp->is_dst.in4), sp->is_pass, sp->is_p,