On Wed, 2002-06-12 at 11:10, Martin Josefsson wrote: > On Wed, 2002-06-12 at 00:21, Henrik Nordstrom wrote: > > > Haven't looked at the patch, but one thing to look out for is to make > > sure timer transitions is not lost. > > > > Unlike atime updates, conntrack timers vary in length depending on the > > state. It would not be fun if a TIME_WAIT state got a timeout of > > ESTABLISHED only because the transition was too quick to be noticed > > by the timer update filter.. > > Yes I thought about it yesterday and I'll send Harald a new patch which > will allow us to force an update.
Here's that patch, it's against current cvs. (the patch is a little messy because ip_ct_death_by_timeout isn't separated from ip_ct_refresh in the patch anymore) It adds a new parameter to ip_ct_refresh called force, if set to non-zero a timer update will be forced. I hope the tcp-change is correct, I havn't tested this patch yet but it does compile :) I'm going to test it in a few minutes. ip_ct_refresh(conntrack, tcp_timeouts[newconntrack], newconntrack != oldtcpstate); so if the state changes we force a timer update, otherwise we only update if there's been >HZ jiffies since the last update. Harald, does the tcp change in the patch look like it could work? -- /Martin Never argue with an idiot. They drag you down to their level, then beat you with experience.
--- netfilter/userspace/patch-o-matic/optimizations/ip_ct_refresh_optimization.patch.orig Tue Jun 11 10:02:57 2002 +++ netfilter/userspace/patch-o-matic/optimizations/ip_ct_refresh_optimization.patch + Wed Jun 12 20:45:29 2002 @@ -1,17 +1,20 @@ ---- linux-2.4.19-pre9/include/linux/netfilter_ipv4/ip_conntrack.h.orig Mon Jun 3 21:46:59 2002 -+++ linux-2.4.19-pre9/include/linux/netfilter_ipv4/ip_conntrack.h Mon Jun 3 21:46:37 2002 -@@ -226,6 +226,9 @@ - extern void ip_ct_refresh(struct ip_conntrack *ct, - unsigned long extra_jiffies); +--- linux-2.4.19-pre10/include/linux/netfilter_ipv4/ip_conntrack.h.orig Wed +Jun 12 20:25:54 2002 ++++ linux-2.4.19-pre10/include/linux/netfilter_ipv4/ip_conntrack.h Wed Jun 12 +20:26:20 2002 +@@ -224,7 +224,10 @@ -+/* Kill conntrack */ -+extern void ip_ct_death_by_timeout(unsigned long ul_conntrack); + /* Refresh conntrack for this many jiffies */ + extern void ip_ct_refresh(struct ip_conntrack *ct, +- unsigned long extra_jiffies); ++ unsigned long extra_jiffies, int force); + ++/* Kill conntrack */ ++extern void ip_ct_death_by_timeout(unsigned long ul_conntrack); + /* These are for NAT. Icky. */ /* Call me when a conntrack is destroyed. */ - extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack); ---- linux-2.4.19-pre9/net/ipv4/netfilter/ip_conntrack_core.c.orig Mon Jun 3 20:32:28 2002 -+++ linux-2.4.19-pre9/net/ipv4/netfilter/ip_conntrack_core.c Tue Jun 4 20:56:18 2002 +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_core.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_core.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_core.c Wed Jun 12 +20:22:08 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_core.c Wed Jun 12 20:36:23 +2002 @@ -267,7 +267,7 @@ atomic_dec(&ip_conntrack_count); } @@ -21,7 +24,7 @@ { struct ip_conntrack *ct = (void *)ul_conntrack; -@@ -527,7 +527,7 @@ +@@ -528,7 +528,7 @@ return dropped; if (del_timer(&h->ctrack->timeout)) { @@ -30,7 +33,7 @@ dropped = 1; } ip_conntrack_put(h->ctrack); -@@ -617,7 +617,7 @@ +@@ -618,7 +618,7 @@ /* Don't set timer yet: wait for confirmation */ init_timer(&conntrack->timeout); conntrack->timeout.data = (unsigned long)conntrack; @@ -39,7 +42,29 @@ INIT_LIST_HEAD(&conntrack->sibling_list); -@@ -1198,7 +1189,7 @@ +@@ -1072,7 +1072,7 @@ + } + + /* Refresh conntrack for this many jiffies. */ +-void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies) ++void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies, int force) + { + IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); + +@@ -1081,8 +1081,10 @@ + if (!is_confirmed(ct)) + ct->timeout.expires = extra_jiffies; + else { +- /* Need del_timer for race avoidance (may already be dying). */ +- if (del_timer(&ct->timeout)) { ++ /* Don't update timer for each packet, only if it's been >HZ ++ * ticks since last update or we are forcing. ++ * Need del_timer for race avoidance (may already be dying). */ ++ if ((force || time_after(jiffies, ct->timeout.expires - extra_jiffies ++ HZ)) && del_timer(&ct->timeout)) { + ct->timeout.expires = jiffies + extra_jiffies; + add_timer(&ct->timeout); + } +@@ -1188,7 +1190,7 @@ while ((h = get_next_corpse(kill, data)) != NULL) { /* Time to push up daises... */ if (del_timer(&h->ctrack->timeout)) @@ -48,8 +73,9 @@ /* ... else the timer will get him soon. */ ip_conntrack_put(h->ctrack); ---- linux-2.4.19-pre9/net/ipv4/netfilter/ip_conntrack_standalone.c.orig Mon Jun 3 21:43:04 2002 -+++ linux-2.4.19-pre9/net/ipv4/netfilter/ip_conntrack_standalone.c Mon Jun 3 21:47:43 2002 +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_standalone.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_standalone.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_standalone.c Wed +Jun 12 20:22:08 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_standalone.c Mon Jun 3 +21:47:43 2002 @@ -362,6 +362,7 @@ EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_ct_selective_cleanup); @@ -58,45 +84,92 @@ EXPORT_SYMBOL(ip_ct_find_proto); EXPORT_SYMBOL(ip_ct_find_helper); EXPORT_SYMBOL(ip_conntrack_expect_related); ---- linux-2.4.19-pre9/net/ipv4/netfilter/ip_conntrack_core.c.orig Mon Jun 3 20:32:28 2002 -+++ linux-2.4.19-pre9/net/ipv4/netfilter/ip_conntrack_core.c Mon Jun 3 20:48:13 2002 -@@ -1091,8 +1091,10 @@ - if (!is_confirmed(ct)) - ct->timeout.expires = extra_jiffies; - else { -- /* Need del_timer for race avoidance (may already be dying). */ -- if (del_timer(&ct->timeout)) { -+ /* Don't update timer for each packet, only if it's been >HZ -+ * ticks since last update. -+ * Need del_timer for race avoidance (may already be dying). */ -+ if (time_after(jiffies, ct->timeout.expires - extra_jiffies + HZ) && del_timer(&ct->timeout)) { - ct->timeout.expires = jiffies + extra_jiffies; - add_timer(&ct->timeout); - } ---- netfilter/userspace/patch-o-matic/extra/pptp-conntrack-nat.patch.orig Thu Jun 6 14:03:35 2002 -+++ netfilter/userspace/patch-o-matic/extra/pptp-conntrack-nat.patch Thu Jun 6 14:05:17 2002 -@@ -572,7 +572,7 @@ - diff -Nru --exclude .depend --exclude '*.o' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*~' linux-2.4.18-newnat/net/ipv4/netfilter/ip_conntrack_pptp.c linux-2.4.18-pptp3.01//net/ipv4/netfilter/ip_conntrack_pptp.c - --- linux-2.4.18-newnat/net/ipv4/netfilter/ip_conntrack_pptp.c Thu Jan 1 01:00:00 1970 - +++ linux-2.4.18-pptp3.01//net/ipv4/netfilter/ip_conntrack_pptp.c Mon Apr 8 16:40:37 2002 --@@ -0,0 +1,540 @@ -+@@ -0,0 +1,542 @@ - +/* - + * ip_conntrack_pptp.c - Version $Revision: 1.1 $ - + * -@@ -682,11 +682,13 @@ - + if (!exp->sibling) - + continue; - + --+ DEBUGP("setting timeout of conntrack %p to 0\n", -++ DEBUGP("killing conntrack %p\n", - + exp->sibling); - + exp->sibling->proto.gre.timeout = 0; - + exp->sibling->proto.gre.stream_timeout = 0; --+ ip_ct_refresh(exp->sibling, 0); -++ -++ if (del_timer(&exp->sibling->timeout)) -++ ip_ct_death_by_timeout((unsigned long)exp->sibling); - + } - + - + return 0; +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_pptp.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_pptp.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_pptp.c Wed Jun 12 +20:23:10 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_pptp.c Mon Jun 3 21:48:38 +2002 +@@ -107,11 +107,13 @@ + if (!exp->sibling) + continue; + +- DEBUGP("setting timeout of conntrack %p to 0\n", ++ DEBUGP("killing conntrack %p\n", + exp->sibling); + exp->sibling->proto.gre.timeout = 0; + exp->sibling->proto.gre.stream_timeout = 0; +- ip_ct_refresh(exp->sibling, 0); ++ ++ if (del_timer(&exp->sibling->timeout)) ++ ip_ct_death_by_timeout((unsigned long)exp->sibling); + } + + return 0; +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_generic.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_generic.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_generic.c Sat +Apr 13 19:08:16 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_generic.c Wed Jun 12 +20:32:55 2002 +@@ -43,7 +43,7 @@ + struct iphdr *iph, size_t len, + enum ip_conntrack_info conntrackinfo) + { +- ip_ct_refresh(conntrack, GENERIC_TIMEOUT); ++ ip_ct_refresh(conntrack, GENERIC_TIMEOUT, 0); + return NF_ACCEPT; + } + +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_gre.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_gre.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_gre.c Sat +May 18 23:14:38 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_gre.c Wed Jun 12 +20:33:18 2002 +@@ -232,11 +232,11 @@ + /* If we've seen traffic both ways, this is a GRE connection. + * Extend timeout. */ + if (ct->status & IPS_SEEN_REPLY) { +- ip_ct_refresh(ct, ct->proto.gre.stream_timeout); ++ ip_ct_refresh(ct, ct->proto.gre.stream_timeout, 0); + /* Also, more likely to be important, and not a probe. */ + set_bit(IPS_ASSURED_BIT, &ct->status); + } else +- ip_ct_refresh(ct, ct->proto.gre.timeout); ++ ip_ct_refresh(ct, ct->proto.gre.timeout, 0); + + return NF_ACCEPT; + } +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_icmp.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_icmp.c Sat +Apr 13 19:08:16 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_icmp.c Wed Jun 12 +20:33:34 2002 +@@ -82,7 +82,7 @@ + ct->timeout.function((unsigned long)ct); + } else { + atomic_inc(&ct->proto.icmp.count); +- ip_ct_refresh(ct, ICMP_TIMEOUT); ++ ip_ct_refresh(ct, ICMP_TIMEOUT, 0); + } + + return NF_ACCEPT; +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_tcp.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_tcp.c Wed +May 22 14:55:14 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Wed Jun 12 +20:32:39 2002 +@@ -229,7 +229,7 @@ + && tcph->ack_seq == conntrack->proto.tcp.handshake_ack) + set_bit(IPS_ASSURED_BIT, &conntrack->status); + +- ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]); ++ ip_ct_refresh(conntrack, tcp_timeouts[newconntrack], newconntrack != +oldtcpstate); + } + + return NF_ACCEPT; +diff --exclude=*.orig -ur +linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_udp.c +linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_udp.c +--- linux-2.4.19-pre10/net/ipv4/netfilter.orig/ip_conntrack_proto_udp.c Sat +Apr 13 19:08:16 2002 ++++ linux-2.4.19-pre10/net/ipv4/netfilter/ip_conntrack_proto_udp.c Wed Jun 12 +20:34:39 2002 +@@ -52,11 +52,11 @@ + /* If we've seen traffic both ways, this is some kind of UDP + stream. Extend timeout. */ + if (conntrack->status & IPS_SEEN_REPLY) { +- ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT); ++ ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT, 0); + /* Also, more likely to be important, and not a probe */ + set_bit(IPS_ASSURED_BIT, &conntrack->status); + } else +- ip_ct_refresh(conntrack, UDP_TIMEOUT); ++ ip_ct_refresh(conntrack, UDP_TIMEOUT, 0); + + return NF_ACCEPT; + }