patch-2.4.4 linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c

Next file: linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
Previous file: linux/net/ipv4/netfilter/ip_conntrack_proto_generic.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -72,22 +72,25 @@
 		       struct iphdr *iph, size_t len,
 		       enum ip_conntrack_info ctinfo)
 {
-	/* FIXME: Should keep count of orig - reply packets: if == 0,
-           destroy --RR */
-	/* Delete connection immediately on reply: won't actually
-           vanish as we still have skb */
+	/* Try to delete connection immediately after all replies:
+           won't actually vanish as we still have skb, and del_timer
+           means this will only run once even if count hits zero twice
+           (theoretically possible with SMP) */
 	if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
-		if (del_timer(&ct->timeout))
+		if (atomic_dec_and_test(&ct->proto.icmp.count)
+		    && del_timer(&ct->timeout))
 			ct->timeout.function((unsigned long)ct);
-	} else
+	} else {
+		atomic_inc(&ct->proto.icmp.count);
 		ip_ct_refresh(ct, ICMP_TIMEOUT);
+	}
 
 	return NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static unsigned long icmp_new(struct ip_conntrack *conntrack,
-			      struct iphdr *iph, size_t len)
+static int icmp_new(struct ip_conntrack *conntrack,
+		    struct iphdr *iph, size_t len)
 {
 	static u_int8_t valid_new[]
 		= { [ICMP_ECHO] = 1,
@@ -103,7 +106,8 @@
 		DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
 		return 0;
 	}
-	return ICMP_TIMEOUT;
+	atomic_set(&conntrack->proto.icmp.count, 0);
+	return 1;
 }
 
 struct ip_conntrack_protocol ip_conntrack_protocol_icmp

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)