[Bug 56] New: super-long erroneous timeouts in conntrack table (semantics of list_del() change)

bugzilla-daemon@netfilter.org bugzilla-daemon@netfilter.org
Wed, 26 Feb 2003 19:37:01 +0100


           Summary: super-long erroneous timeouts in conntrack table
                    (semantics of list_del() change)
           Product: netfilter/iptables
           Version: linux-2.4.x
          Platform: other
               URL: http://lists.netfilter.org/pipermail/netfilter-
        OS/Version: other
            Status: NEW
          Severity: normal
          Priority: P2
         Component: connection tracking
        AssignedTo: laforge@netfilter.org
        ReportedBy: laforge@netfilter.org
                CC: netfilter-buglog@lists.netfilter.org

Hello, netfilter guys.

 We run transparent web caches using ipt_REDIRECT, and after upgrading
to 2.4.20, found that conntrack table overflows after a week or so.
Quick examination showed large number of entries in SYN_SENT state
with super long timeouts exist.  The offending change was in
include/linux/list.h.  list_del() now zeros prev and next pointer of
list_head, which circumvents is_confirmed() test.

 This didn't cause troubles to most conntrack entries which disappear
by timing out.  But as our cache was bypassing some of the
connections, the machine was seeing only one way stream of packets
(!IPS_SEEN_REPLY).  And when the originating host terminates a
bypassed connection by sending out RST packets, the corresponding
entry is repeatedly removed from hash with death_by_tiemout() and soon
confirmed again adding jiffies to expire time every time.

 Applying the following patch solved the problem.  As I'm not on the
list, please CC to me any comments regarding this problem.  Thank you
a lot for great netfilter.

--- linux-2.4.20-orig/include/linux/netfilter_ipv4/listhelp.h	2003-02-20 16:48:27.000000000 +0900
+++ linux-2.4.20-rmap-pm/include/linux/netfilter_ipv4/listhelp.h	2003-02-20 16:45:30.000000000 +0900
@@ -57,10 +57,13 @@
 	if (!list_inlist(head, oldentry))				\
	printk("LIST_DELETE: %s:%u `%s'(%p) not in %s.\n",	\
	       __FILE__, __LINE__, #oldentry, oldentry, #head);	\
-        else list_del((struct list_head *)oldentry);			\
+        else __list_del(((struct list_head *)oldentry)->prev,		\
		((struct list_head *)oldentry)->next);		\
 } while(0)
-#define LIST_DELETE(head, oldentry) list_del((struct list_head *)oldentry)
+#define LIST_DELETE(head, oldentry)					\
__list_del(((struct list_head *)oldentry)->prev,		\
	   ((struct list_head *)oldentry)->next)
 /* Append. */

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.