All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6] connection tracking events
@ 2004-10-15 17:54 Harald Welte
  2004-10-16 13:21 ` Patrick McHardy
  0 siblings, 1 reply; 6+ messages in thread
From: Harald Welte @ 2004-10-15 17:54 UTC (permalink / raw)
  To: Netfilter Development Mailinglist; +Cc: Patrick McHardy


[-- Attachment #1.1: Type: text/plain, Size: 747 bytes --]

Hi!

Since we decided at the netfilter developer workshop that we want to
split conntrack events from the rest of ctnetlink, I've now done that
(and ported it to use percpu allocations).  This is needed mostly for 
ct_sync.

Totally untested, but seems to compile.  Comments welcome.

As it is quite non-intrusive, I think we should consider it for
post-2.6.9.


-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #1.2: 2.6.9-rc3-bk9-conntrack_events.patch --]
[-- Type: text/plain, Size: 14558 bytes --]

diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.9-rc3-bk9-test-ctevent/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux-2.6.9-rc3-bk9-test/include/linux/netfilter_ipv4/ip_conntrack.h	2004-10-10 14:00:59.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/include/linux/netfilter_ipv4/ip_conntrack.h	2004-10-15 19:46:19.746327032 +0200
@@ -47,6 +47,10 @@
 	/* Connection is confirmed: originating packet has left box */
 	IPS_CONFIRMED_BIT = 3,
 	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+	/* Connection is destroyed (removed from lists), can not be unset. */
+	IPS_DESTROYED_BIT = 4,
+	IPS_DESTROYED = (1 << IPS_DESTROYED_BIT),
 };
 
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
@@ -290,6 +294,12 @@
 	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
 }
 
+/* It is destroyed after it has been removed from hash table. */
+static inline int is_destroyed(struct ip_conntrack *ct)
+{
+	return test_bit(IPS_DESTROYED_BIT, &ct->status);
+}
+
 extern unsigned int ip_conntrack_htable_size;
  
 struct ip_conntrack_stat
@@ -323,5 +333,69 @@
         extern int needs_ip_conntrack_##name;                           \
         static int *need_ip_conntrack_##name __attribute_used__ = &needs_ip_conntrack_##name
 
+enum ip_conntrack_events
+{
+	IPCT_NEW,
+	IPCT_DESTROY,
+	IPCT_STATUS,
+	IPCT_REFRESH,
+	IPCT_PROTOINFO,
+	IPCT_PROTOINFO_VOLATILE,
+	IPCT_HELPINFO,
+	IPCT_NATINFO,
+};
+
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+#include <linux/notifier.h>
+
+extern struct notifier_block *ip_conntrack_chain;
+DECLARE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+
+/* register notifier for conntrack events */
+static inline int ip_conntrack_notify_register(struct notifier_block *nb)
+{
+	return notifier_chain_register(&ip_conntrack_chain, nb);
+}
+
+static inline int ip_conntrack_notify_unregister(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&ip_conntrack_chain, nb);
+}
+
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+				      struct ip_conntrack *ct)
+{
+	if (is_confirmed(ct) && !is_destroyed(ct))
+		notifier_call_chain(&ip_conntrack_chain, 1 << event, ct);
+}
+
+static inline void ip_conntrack_event_cache_init(void)
+{
+	*per_cpu_ptr(ip_conntrack_event_cache, smp_processor_id()) = 0UL;
+}
+
+static inline void ip_conntrack_cache_event(void)
+{
+	*per_cpu_ptr(ip_conntrack_event_cache, smp_processor_id()) |= 1<<event;
+}
+
+static inline void ip_conntrack_do_cached_events(struct ip_conntrack *ct)
+{
+	unsigned long events = *per_cpu_ptr(ip_conntrack_event_cache,
+					    smp_processor_id());
+
+	if (is_confirmed(ct) && !is_destroyed(ct) && events)
+		notifier_call_chain(&ip_conntrack_chain, events, ct);
+}
+#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+static inline int ip_conntrack_notify_register(void *nb) { return 0; }
+static inline int ip_conntrack_notify_unregister(void *nb) { return 0; }
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+				      struct ip_conntrack *ct) {}
+static inline void ip_conntrack_event_cache_init(void) {}
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event) {}
+static inline void ip_conntrack_do_cached_events(struct ip_conntrack *ct) {}
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+
 #endif /* __KERNEL__ */
 #endif /* _IP_CONNTRACK_H */
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/Kconfig linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/Kconfig
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/Kconfig	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/Kconfig	2004-10-15 19:39:06.483193040 +0200
@@ -20,6 +20,16 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_NF_CONNTRACK_EVENTS
+	bool "Connection tracking events"
+	depends on IP_NF_CONNTRACK
+	help
+	  If this option is enabled, the connection tracking code will
+	  provide a notifier chain that can be used by other kernel code
+	  to get notified about changes in the connection tracking state.
+	  
+	  IF unsure, say `N'.
+
 config IP_NF_CT_ACCT
 	bool "Connection tracking flow accounting"
 	depends on IP_NF_CONNTRACK
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_core.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_core.c	2004-10-15 19:36:24.910755784 +0200
@@ -15,6 +15,10 @@
  * 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
  * 	- add usage/reference counts to ip_conntrack_expect
  *	- export ip_conntrack[_expect]_{find_get,put} functions
+ * 28 May 2003: Patrick McHardy <kaber@trash.net>
+ * 	- event notifications
+ * 15 Oct 2004: Harald Welte <laforge@netfilter.org>
+ * 	- port event notifications to 2.6.x (use percpu allocations)
  * */
 
 #include <linux/config.h>
@@ -78,6 +82,11 @@
 
 DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+struct notifier_block *ip_conntrack_chain = NULL
+DEFINE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+
 inline void 
 ip_conntrack_put(struct ip_conntrack *ct)
 {
@@ -329,9 +338,11 @@
 	struct ip_conntrack *ct = (void *)ul_conntrack;
 
 	CONNTRACK_STAT_INC(delete_list);
+	ip_conntrack_event(IPCT_DESTROY, ct);
 
 	WRITE_LOCK(&ip_conntrack_lock);
 	clean_from_lists(ct);
+	set_bit(IPS_DESTROYED_BIT, &ct->status);
 	WRITE_UNLOCK(&ip_conntrack_lock);
 	ip_conntrack_put(ct);
 }
@@ -437,6 +448,7 @@
 		atomic_inc(&ct->ct_general.use);
 		set_bit(IPS_CONFIRMED_BIT, &ct->status);
 		WRITE_UNLOCK(&ip_conntrack_lock);
+		ip_conntrack_event(IPCT_NEW, ct);
 		CONNTRACK_STAT_INC(insert);
 		return NF_ACCEPT;
 	}
@@ -706,6 +718,8 @@
 	/* FIXME: Do this right please. --RR */
 	(*pskb)->nfcache |= NFC_UNKNOWN;
 
+	ip_conntrack_event_cache_init();
+
 /* Doesn't cover locally-generated broadcast, so not worth it. */
 #if 0
 	/* Ignore broadcast: no `connection'. */
@@ -767,8 +781,12 @@
 			return NF_ACCEPT;
 		}
 	}
-	if (set_reply)
+	if (set_reply && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
 		set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
+		ip_conntrack_cache_event(IPCT_STATUS);
+	}
+	
+	ip_conntrack_do_cached_events(ct);
 
 	return ret;
 }
@@ -1052,6 +1070,7 @@
 		remove_expectations(i->ctrack, 0);
 		/* And *then* set helper to NULL */
 		i->ctrack->helper = NULL;
+		ip_conntrack_event(IPCT_HELPINFO, i->ctrack);
 	}
 	return 0;
 }
@@ -1099,12 +1118,13 @@
 	if (!is_confirmed(ct)) {
 		ct->timeout.expires = extra_jiffies;
 		ct_add_counters(ct, ctinfo, skb);
-	} else {
+	} else if (abs(jiffies + extra_jiffies - ct->timeout.expires >= HZ)) {
 		WRITE_LOCK(&ip_conntrack_lock);
 		/* Need del_timer for race avoidance (may already be dying). */
 		if (del_timer(&ct->timeout)) {
 			ct->timeout.expires = jiffies + extra_jiffies;
 			add_timer(&ct->timeout);
+			ip_conntrack_cache_event(IPCT_REFRESH);
 		}
 		ct_add_counters(ct, ctinfo, skb);
 		WRITE_UNLOCK(&ip_conntrack_lock);
@@ -1303,6 +1323,9 @@
 		goto i_see_dead_people;
 	}
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+	free_percpu(ip_conntrack_event_cache);
+#endif
 	kmem_cache_destroy(ip_conntrack_cachep);
 	kmem_cache_destroy(ip_conntrack_expect_cachep);
 	vfree(ip_conntrack_hash);
@@ -1366,6 +1389,14 @@
 		goto err_free_conntrack_slab;
 	}
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+	ip_conntrack_event_cache = alloc_percpu(unsigned long);
+	if (!ip_conntrack_event_cache) {
+		printk(KERN_ERR "Unable to crate ip_conntrack_event_cache\n");
+		goto err_free_exp_slab;
+	}
+#endif
+
 	/* Don't NEED lock here, but good form anyway. */
 	WRITE_LOCK(&ip_conntrack_lock);
 	for (i = 0; i < MAX_IP_CT_PROTO; i++)
@@ -1390,6 +1421,10 @@
 
 	return ret;
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+err_free_exp_slab:
+	kmem_cache_destroy(ip_conntrack_expect_cachep);
+#endif
 err_free_conntrack_slab:
 	kmem_cache_destroy(ip_conntrack_cachep);
 err_free_hash:
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_ftp.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_ftp.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_ftp.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_ftp.c	2004-10-15 18:53:24.558266576 +0200
@@ -300,6 +300,7 @@
 			ct_ftp_info->seq_aft_nl[dir] = 
 						ntohl(th->seq) + datalen;
 			ct_ftp_info->seq_aft_nl_set[dir] = 1;
+			ip_conntrack_cache_event(IPCT_HELPINFO);
 		}
 	}
 
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_proto_sctp.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_proto_sctp.c	2004-10-15 19:02:20.176840176 +0200
@@ -405,6 +405,9 @@
 		}
 
 		conntrack->proto.sctp.state = newconntrack;
+		if (oldsctpstate != newconntrack)
+			ip_conntrack_cache_event(IPCT_PROTOINFO);
+
 		WRITE_UNLOCK(&sctp_lock);
 	}
 
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2004-10-15 18:59:39.121324336 +0200
@@ -694,6 +694,8 @@
 
 		res = ip_ct_tcp_be_liberal && !tcph->rst;
   	}
+
+	ip_conntrack_cache_event(IPCT_PROTOINFO_VOLATILE);
   
 	DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
 	       "receiver end=%u maxend=%u maxwin=%u\n",
@@ -939,6 +941,9 @@
 		old_state, new_state);
 
 	conntrack->proto.tcp.state = new_state;
+	if (new_state != old_state)
+		ip_conntrack_cache_event(IPCT_PROTOINFO);
+
 	timeout = conntrack->proto.tcp.retrans >= ip_ct_tcp_max_retrans
 		  && *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans
 		  ? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2004-10-15 19:00:07.219052832 +0200
@@ -74,6 +74,7 @@
 				   ip_ct_udp_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+		ip_conntrack_cache_event(IPCT_STATUS);
 	} else
 		ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_udp_timeout);
 
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_conntrack_standalone.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_conntrack_standalone.c	2004-10-15 19:16:16.328488216 +0200
@@ -903,3 +903,7 @@
 EXPORT_SYMBOL(ip_conntrack_untracked);
 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
 EXPORT_SYMBOL_GPL(ip_conntrack_put);
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+EXPORT_SYMBOL_GPL(ip_conntrack_chain);
+EXPORT_PER_CPU_SYMBOL_GPL(ip_conntrack_event_cache);
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
diff -Nru --exclude-from /space/home/laforge/scripts/dontdiff --exclude .depend --exclude '*.o' --exclude '*.ko' --exclude '*.ver' --exclude '.*.flags' --exclude '*.orig' --exclude '*.rej' --exclude '*.cmd' --exclude '*.mod.c' --exclude '*~' linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_nat_core.c linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_nat_core.c
--- linux-2.6.9-rc3-bk9-test/net/ipv4/netfilter/ip_nat_core.c	2004-10-10 14:01:02.000000000 +0200
+++ linux-2.6.9-rc3-bk9-test-ctevent/net/ipv4/netfilter/ip_nat_core.c	2004-10-15 19:00:40.953924352 +0200
@@ -608,6 +608,8 @@
 		IP_NF_ASSERT(info->num_manips <= IP_NAT_MAX_MANIPS);
 	}
 
+	ip_conntrack_event(IPCT_NATINFO, conntrack);
+
 	/* If there's a helper, assign it; based on new tuple. */
 	if (!conntrack->master)
 		info->helper = __ip_nat_find_helper(&reply);

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2.6] connection tracking events
  2004-10-15 17:54 [PATCH 2.6] connection tracking events Harald Welte
@ 2004-10-16 13:21 ` Patrick McHardy
  2004-10-16 15:07   ` Harald Welte
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick McHardy @ 2004-10-16 13:21 UTC (permalink / raw)
  To: Harald Welte; +Cc: Netfilter Development Mailinglist

Hi Harald,

Harald Welte wrote:

>Hi!
>
>Since we decided at the netfilter developer workshop that we want to
>split conntrack events from the rest of ctnetlink, I've now done that
>(and ported it to use percpu allocations).  This is needed mostly for 
>ct_sync.
>  
>
I've already did this in Erlangen. Pablo is currently working with
Krizstian on this patch.

>Totally untested, but seems to compile.  Comments welcome.
>
>As it is quite non-intrusive, I think we should consider it for
>post-2.6.9.
>  
>
Agreed.

Regards
Patrick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2.6] connection tracking events
  2004-10-16 13:21 ` Patrick McHardy
@ 2004-10-16 15:07   ` Harald Welte
  2004-10-16 15:20     ` Patrick McHardy
  0 siblings, 1 reply; 6+ messages in thread
From: Harald Welte @ 2004-10-16 15:07 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 914 bytes --]

Hi Patrick!

On Sat, Oct 16, 2004 at 03:21:06PM +0200, Patrick McHardy wrote:

> >Since we decided at the netfilter developer workshop that we want to
> >split conntrack events from the rest of ctnetlink, I've now done that
> >(and ported it to use percpu allocations).  This is needed mostly for 
> >ct_sync.
> > 
> >
> I've already did this in Erlangen. Pablo is currently working with
> Krizstian on this patch.

mh, did you post this to netfilter-devel?  I must have missed it...

Sorry for replicating your work then :(

-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2.6] connection tracking events
  2004-10-16 15:07   ` Harald Welte
@ 2004-10-16 15:20     ` Patrick McHardy
  2004-10-16 15:32       ` Pablo Neira
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick McHardy @ 2004-10-16 15:20 UTC (permalink / raw)
  To: Harald Welte; +Cc: Netfilter Development Mailinglist, Pablo Neira

Harald Welte wrote:

>Hi Patrick!
>
>On Sat, Oct 16, 2004 at 03:21:06PM +0200, Patrick McHardy wrote:
>
>
>>I've already did this in Erlangen. Pablo is currently working with
>>Krizstian on this patch.
>>
>
>mh, did you post this to netfilter-devel?  I must have missed it...
>
No not yet, I wasn't completely done and Pablo took in on from there.
He introduced some new events for tcp window tracking, I didn't have
time to look at it in detail yet. Pablo, could you post your latest
patch to netfilter-devel ?

>
>Sorry for replicating your work then :(
>

I'm sorry, replicating work sucks.

Regards
Patrick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2.6] connection tracking events
  2004-10-16 15:20     ` Patrick McHardy
@ 2004-10-16 15:32       ` Pablo Neira
  2004-10-16 18:21         ` Pablo Neira
  0 siblings, 1 reply; 6+ messages in thread
From: Pablo Neira @ 2004-10-16 15:32 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Harald Welte, Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 731 bytes --]

Hi Patrick, Hi Harald,

Patrick McHardy wrote:

> Harald Welte wrote:
>
>> Hi Patrick!
>>
>> On Sat, Oct 16, 2004 at 03:21:06PM +0200, Patrick McHardy wrote:
>>
>>
>>> I've already did this in Erlangen. Pablo is currently working with
>>> Krizstian on this patch.
>>>
>>
>> mh, did you post this to netfilter-devel?  I must have missed it...
>>
> No not yet, I wasn't completely done and Pablo took in on from there.
> He introduced some new events for tcp window tracking, I didn't have
> time to look at it in detail yet. Pablo, could you post your latest
> patch to netfilter-devel ?


Attached the lastest version, I'm having a look at Harald's now to see I 
think that I can take something.

Comments welcome.

regards,
Pablo

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 11708 bytes --]

===== include/linux/netfilter_ipv4/ip_conntrack.h 1.27 vs edited =====
--- 1.27/include/linux/netfilter_ipv4/ip_conntrack.h	Sun Oct 10 21:44:23 2004
+++ edited/include/linux/netfilter_ipv4/ip_conntrack.h	Thu Oct 14 19:46:48 2004
@@ -47,6 +47,12 @@
 	/* Connection is confirmed: originating packet has left box */
 	IPS_CONFIRMED_BIT = 3,
 	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+	IPS_DESTROYED_BIT = 4,
+	IPS_DESTROYED = (1 << IPS_DESTROYED_BIT),
+
+	IPS_PICKUP_BIT = 5,
+	IPS_PICKUP = (1 << IPS_PICKUP_BIT),
 };
 
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
@@ -290,6 +296,11 @@
 	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
 }
 
+static inline int is_destroyed(struct ip_conntrack *ct)
+{
+	return test_bit(IPS_DESTROYED_BIT, &ct->status);
+}
+
 extern unsigned int ip_conntrack_htable_size;
  
 struct ip_conntrack_stat
@@ -313,6 +324,68 @@
 
 #define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
 
+enum ip_conntrack_events
+{
+	IPCT_NEW,
+	IPCT_RELATED,
+	IPCT_DESTROY,
+	IPCT_STATUS,
+	IPCT_REFRESH,
+ 	IPCT_PROTOINFO,
+	IPCT_PROTOINFO_SOFT,
+ 	IPCT_HELPINFO,
+	IPCT_NATINFO,
+};
+
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+#include <linux/notifier.h>
+ 
+extern struct notifier_block *ip_conntrack_chain;
+DECLARE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+ 
+static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_register(&ip_conntrack_chain, nb);
+}
+
+static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&ip_conntrack_chain, nb);
+}
+
+static inline void ip_conntrack_event_cache_init(void)
+{
+	__get_cpu_var(ip_conntrack_event_cache) = 0UL;
+}
+
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event)
+{ 
+	__get_cpu_var(ip_conntrack_event_cache) |= 1 << event;
+}
+
+static inline void ip_conntrack_deliver_cached_events(struct ip_conntrack *ct)
+{
+	unsigned long events = __get_cpu_var(ip_conntrack_event_cache);
+ 
+	if (is_confirmed(ct) && !is_destroyed(ct) && events)
+		notifier_call_chain(&ip_conntrack_chain, events, ct);
+}
+ 
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+                                      struct ip_conntrack *ct)
+{
+	if (is_confirmed(ct) && !is_destroyed(ct))
+		notifier_call_chain(&ip_conntrack_chain, 1 << event, ct);
+}
+#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+static inline int ip_conntrack_register_notifier(void *nb) { return 0; }
+static inline int ip_conntrack_unregister_notifier(void *nb) { return 0; }
+static inline void ip_conntrack_event_cache_init(void) {}
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event) {}
+static inline void ip_conntrack_deliver_cached_events(struct ip_conntrack *ct) {}
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+                                      struct ip_conntrack *ct) {}
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
 /* eg. PROVIDES_CONNTRACK(ftp); */
 #define PROVIDES_CONNTRACK(name)                        \
         int needs_ip_conntrack_##name;                  \
===== net/ipv4/netfilter/ip_conntrack_proto_icmp.c 1.16 vs edited =====
--- 1.16/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	Sun Oct 10 21:44:20 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	Thu Oct 14 19:30:24 2004
@@ -102,6 +102,7 @@
 			ct->timeout.function((unsigned long)ct);
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
+		ip_conntrack_cache_event(IPCT_PROTOINFO);
 		ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout);
 	}
 
===== net/ipv4/netfilter/ip_conntrack_core.c 1.72 vs edited =====
--- 1.72/net/ipv4/netfilter/ip_conntrack_core.c	Sun Oct 10 21:44:21 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_core.c	Thu Oct 14 19:44:54 2004
@@ -37,6 +37,7 @@
 #include <linux/err.h>
 #include <linux/percpu.h>
 #include <linux/moduleparam.h>
+#include <linux/notifier.h>
 
 /* This rwlock protects the main hash table, protocol/helper/expected
    registrations, conntrack timers*/
@@ -76,6 +77,11 @@
 struct ip_conntrack ip_conntrack_untracked;
 unsigned int ip_ct_log_invalid;
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+struct notifier_block *ip_conntrack_chain;
+DEFINE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+
 DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
 
 inline void 
@@ -330,6 +336,7 @@
 
 	CONNTRACK_STAT_INC(delete_list);
 
+	ip_conntrack_event(IPCT_DESTROY, ct);
 	WRITE_LOCK(&ip_conntrack_lock);
 	clean_from_lists(ct);
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -437,6 +444,7 @@
 		atomic_inc(&ct->ct_general.use);
 		set_bit(IPS_CONFIRMED_BIT, &ct->status);
 		WRITE_UNLOCK(&ip_conntrack_lock);
+ 		ip_conntrack_event(master_ct(ct)? IPCT_RELATED : IPCT_NEW, ct);
 		CONNTRACK_STAT_INC(insert);
 		return NF_ACCEPT;
 	}
@@ -706,6 +714,8 @@
 	/* FIXME: Do this right please. --RR */
 	(*pskb)->nfcache |= NFC_UNKNOWN;
 
+	ip_conntrack_event_cache_init();
+
 /* Doesn't cover locally-generated broadcast, so not worth it. */
 #if 0
 	/* Ignore broadcast: no `connection'. */
@@ -767,8 +777,11 @@
 			return NF_ACCEPT;
 		}
 	}
-	if (set_reply)
+	if (set_reply && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
 		set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
+		ip_conntrack_cache_event(IPCT_STATUS);
+	}
+	ip_conntrack_deliver_cached_events(ct);
 
 	return ret;
 }
@@ -1052,6 +1065,7 @@
 		remove_expectations(i->ctrack, 0);
 		/* And *then* set helper to NULL */
 		i->ctrack->helper = NULL;
+		ip_conntrack_event(IPCT_HELPINFO, i->ctrack);
 	}
 	return 0;
 }
@@ -1105,6 +1119,7 @@
 		if (del_timer(&ct->timeout)) {
 			ct->timeout.expires = jiffies + extra_jiffies;
 			add_timer(&ct->timeout);
+			ip_conntrack_cache_event(IPCT_REFRESH);
 		}
 		ct_add_counters(ct, ctinfo, skb);
 		WRITE_UNLOCK(&ip_conntrack_lock);
===== net/ipv4/netfilter/ip_conntrack_ftp.c 1.27 vs edited =====
--- 1.27/net/ipv4/netfilter/ip_conntrack_ftp.c	Sun Oct 10 21:44:22 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_ftp.c	Thu Oct 14 19:30:24 2004
@@ -300,6 +300,7 @@
 			ct_ftp_info->seq_aft_nl[dir] = 
 						ntohl(th->seq) + datalen;
 			ct_ftp_info->seq_aft_nl_set[dir] = 1;
+			ip_conntrack_cache_event(IPCT_HELPINFO);
 		}
 	}
 
===== net/ipv4/netfilter/ip_conntrack_standalone.c 1.51 vs edited =====
--- 1.51/net/ipv4/netfilter/ip_conntrack_standalone.c	Thu Oct  7 00:11:17 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_standalone.c	Thu Oct 14 19:30:24 2004
@@ -47,6 +47,9 @@
 
 extern atomic_t ip_conntrack_count;
 DECLARE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+DECLARE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+#endif
 
 static int kill_proto(const struct ip_conntrack *i, void *data)
 {
@@ -875,6 +878,10 @@
 {
 }
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+EXPORT_PER_CPU_SYMBOL(ip_conntrack_event_cache);
+EXPORT_SYMBOL(ip_conntrack_chain);
+#endif
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
 EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
 EXPORT_SYMBOL(invert_tuplepr);
===== net/ipv4/netfilter/ip_conntrack_proto_tcp.c 1.23 vs edited =====
--- 1.23/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Mon Sep 13 02:00:29 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Thu Oct 14 19:30:24 2004
@@ -823,6 +823,32 @@
 	return NF_ACCEPT;
 }
 
+static inline void
+pickup_connection(struct ip_conntrack *conntrack, struct iphdr *iph,
+		  struct tcphdr *th, const struct sk_buff *skb)
+{
+	/*
+	 * We are in the middle of a connection,
+	 * its history is lost for us.
+	 * Let's try to use the data from the packet.
+	 */
+	conntrack->proto.tcp.seen[0].td_end =
+		segment_seq_plus_len(ntohl(th->seq), skb->len, iph, th);
+	conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+	if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
+		conntrack->proto.tcp.seen[0].td_maxwin = 1;
+	conntrack->proto.tcp.seen[0].td_maxend =
+		conntrack->proto.tcp.seen[0].td_end + 
+		conntrack->proto.tcp.seen[0].td_maxwin;
+	conntrack->proto.tcp.seen[0].td_scale = 0;
+
+	/* We assume SACK. Should we assume window scaling too? */
+	conntrack->proto.tcp.seen[0].flags =
+	conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
+	conntrack->proto.tcp.seen[0].loose = 
+	conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
+}
+
 /* Returns verdict for packet, or -1 for invalid. */
 static int tcp_packet(struct ip_conntrack *conntrack,
 		      const struct sk_buff *skb,
@@ -838,6 +864,11 @@
 	th = skb_header_pointer(skb, iph->ihl * 4,
 				sizeof(_tcph), &_tcph);
 	BUG_ON(th == NULL);
+
+	if (test_bit(IPS_PICKUP_BIT, &conntrack->status)) {
+		pickup_connection(conntrack, iph, th, skb);
+		__clear_bit(IPS_PICKUP_BIT, &conntrack->status);
+	}
 	
 	WRITE_LOCK(&tcp_lock);
 	old_state = conntrack->proto.tcp.state;
@@ -944,6 +975,10 @@
 		  ? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
 	WRITE_UNLOCK(&tcp_lock);
 
+	ip_conntrack_cache_event(IPCT_PROTOINFO);
+	if (new_state != old_state)
+		ip_conntrack_cache_event(IPCT_PROTOINFO_SOFT);
+
 	if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
 		/* If only reply is a RST, we can consider ourselves not to
 		   have an established connection: this is a fairly common
@@ -968,7 +1003,7 @@
 
 	return NF_ACCEPT;
 }
- 
+
   /* Called when a new connection for this protocol found. */
 static int tcp_new(struct ip_conntrack *conntrack,
 		   const struct sk_buff *skb)
@@ -1014,29 +1049,8 @@
 	} else if (ip_ct_tcp_loose == 0) {
 		/* Don't try to pick up connections. */
 		return 0;
-	} else {
-		/*
-		 * We are in the middle of a connection,
-		 * its history is lost for us.
-		 * Let's try to use the data from the packet.
-		 */
-		conntrack->proto.tcp.seen[0].td_end =
-			segment_seq_plus_len(ntohl(th->seq), skb->len,
-					     iph, th);
-		conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
-		if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
-			conntrack->proto.tcp.seen[0].td_maxwin = 1;
-		conntrack->proto.tcp.seen[0].td_maxend =
-			conntrack->proto.tcp.seen[0].td_end + 
-			conntrack->proto.tcp.seen[0].td_maxwin;
-		conntrack->proto.tcp.seen[0].td_scale = 0;
-
-		/* We assume SACK. Should we assume window scaling too? */
-		conntrack->proto.tcp.seen[0].flags =
-		conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
-		conntrack->proto.tcp.seen[0].loose = 
-		conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
-	}
+	} else 
+		pickup_connection(conntrack, iph, th, skb);
     
 	conntrack->proto.tcp.seen[1].td_end = 0;
 	conntrack->proto.tcp.seen[1].td_maxend = 0;
===== net/ipv4/netfilter/ip_conntrack_proto_udp.c 1.18 vs edited =====
--- 1.18/net/ipv4/netfilter/ip_conntrack_proto_udp.c	Sun Oct 10 21:44:22 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_udp.c	Thu Oct 14 19:30:24 2004
@@ -73,7 +73,10 @@
 		ip_ct_refresh_acct(conntrack, ctinfo, skb, 
 				   ip_ct_udp_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
-		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+		if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)) {
+			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+			ip_conntrack_cache_event(IPCT_STATUS);
+		}
 	} else
 		ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_udp_timeout);
 
===== net/ipv4/netfilter/ip_nat_core.c 1.48 vs edited =====
--- 1.48/net/ipv4/netfilter/ip_nat_core.c	Sun Oct 10 21:44:22 2004
+++ edited/net/ipv4/netfilter/ip_nat_core.c	Thu Oct 14 19:30:24 2004
@@ -607,6 +607,7 @@
 			   IP_NAT_MANIP_SRC, inv_tuple.src });
 		IP_NF_ASSERT(info->num_manips <= IP_NAT_MAX_MANIPS);
 	}
+	ip_conntrack_event(IPCT_NATINFO, conntrack);
 
 	/* If there's a helper, assign it; based on new tuple. */
 	if (!conntrack->master)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2.6] connection tracking events
  2004-10-16 15:32       ` Pablo Neira
@ 2004-10-16 18:21         ` Pablo Neira
  0 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira @ 2004-10-16 18:21 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Harald Welte, Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 531 bytes --]

Pablo Neira wrote:

> Attached the lastest version, I'm having a look at Harald's now to see 
> I think that I can take something.


Based on Harald's patch, I've:

- renamed PROTOINFO/PROTOINFO_SOFT for PROTOINFO_VOLATILE/PROTOINFO, I 
like it.
- added SCTP events
- added some comments to the source code

Harald's patch is similar to mine but I've also added a new event for 
confirmed expectations (IPCT_RELATED) and the pickup bit which is useful 
for tcp connections to make them pick up missing information.

regards,
Pablo

[-- Attachment #2: notifier.patch --]
[-- Type: text/x-patch, Size: 12691 bytes --]

===== include/linux/netfilter_ipv4/ip_conntrack.h 1.27 vs edited =====
--- 1.27/include/linux/netfilter_ipv4/ip_conntrack.h	Sun Oct 10 21:44:23 2004
+++ edited/include/linux/netfilter_ipv4/ip_conntrack.h	Sat Oct 16 18:42:42 2004
@@ -47,6 +47,14 @@
 	/* Connection is confirmed: originating packet has left box */
 	IPS_CONFIRMED_BIT = 3,
 	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+	/* Connection is destroyed (removed from lists), can not be unset. */
+	IPS_DESTROYED_BIT = 4,
+	IPS_DESTROYED = (1 << IPS_DESTROYED_BIT),
+
+	/* Some protocol information is missing, pick it up. */
+	IPS_PICKUP_BIT = 5,
+	IPS_PICKUP = (1 << IPS_PICKUP_BIT),
 };
 
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
@@ -290,6 +298,11 @@
 	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
 }
 
+static inline int is_destroyed(struct ip_conntrack *ct)
+{
+	return test_bit(IPS_DESTROYED_BIT, &ct->status);
+}
+
 extern unsigned int ip_conntrack_htable_size;
  
 struct ip_conntrack_stat
@@ -313,6 +326,68 @@
 
 #define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
 
+enum ip_conntrack_events
+{
+	IPCT_NEW,
+	IPCT_RELATED,
+	IPCT_DESTROY,
+	IPCT_STATUS,
+	IPCT_REFRESH,
+ 	IPCT_PROTOINFO,
+	IPCT_PROTOINFO_VOLATILE,
+ 	IPCT_HELPINFO,
+	IPCT_NATINFO,
+};
+
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+#include <linux/notifier.h>
+ 
+extern struct notifier_block *ip_conntrack_chain;
+DECLARE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+ 
+static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_register(&ip_conntrack_chain, nb);
+}
+
+static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&ip_conntrack_chain, nb);
+}
+
+static inline void ip_conntrack_event_cache_init(void)
+{
+	__get_cpu_var(ip_conntrack_event_cache) = 0UL;
+}
+
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event)
+{ 
+	__get_cpu_var(ip_conntrack_event_cache) |= 1 << event;
+}
+
+static inline void ip_conntrack_deliver_cached_events(struct ip_conntrack *ct)
+{
+	unsigned long events = __get_cpu_var(ip_conntrack_event_cache);
+ 
+	if (is_confirmed(ct) && !is_destroyed(ct) && events)
+		notifier_call_chain(&ip_conntrack_chain, events, ct);
+}
+ 
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+                                      struct ip_conntrack *ct)
+{
+	if (is_confirmed(ct) && !is_destroyed(ct))
+		notifier_call_chain(&ip_conntrack_chain, 1 << event, ct);
+}
+#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+static inline int ip_conntrack_register_notifier(void *nb) { return 0; }
+static inline int ip_conntrack_unregister_notifier(void *nb) { return 0; }
+static inline void ip_conntrack_event_cache_init(void) {}
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event) {}
+static inline void ip_conntrack_deliver_cached_events(struct ip_conntrack *ct) {}
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+                                      struct ip_conntrack *ct) {}
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
 /* eg. PROVIDES_CONNTRACK(ftp); */
 #define PROVIDES_CONNTRACK(name)                        \
         int needs_ip_conntrack_##name;                  \
===== net/ipv4/netfilter/Kconfig 1.32 vs edited =====
--- 1.32/net/ipv4/netfilter/Kconfig	Sat Oct 16 17:53:47 2004
+++ edited/net/ipv4/netfilter/Kconfig	Sat Oct 16 18:56:12 2004
@@ -677,5 +677,15 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_NF_CONNTRACK_EVENTS
+	bool "Connection tracking events"
+	depends on IP_NF_CONNTRACK
+	help
+	  If this option is enabled, the connection tracking code will
+	  provide a notifier chain that can be used by other kernel code
+	  to get notified about changes in the connection tracking state.
+	  
+	  IF unsure, say `N'.
+
 endmenu
 
===== net/ipv4/netfilter/ip_conntrack_proto_icmp.c 1.16 vs edited =====
--- 1.16/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	Sun Oct 10 21:44:20 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	Sat Oct 16 18:43:07 2004
@@ -102,6 +102,7 @@
 			ct->timeout.function((unsigned long)ct);
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
+		ip_conntrack_cache_event(IPCT_PROTOINFO_VOLATILE);
 		ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout);
 	}
 
===== net/ipv4/netfilter/ip_conntrack_proto_sctp.c 1.8 vs edited =====
--- 1.8/net/ipv4/netfilter/ip_conntrack_proto_sctp.c	Sun Sep 26 23:17:15 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_sctp.c	Sat Oct 16 18:55:30 2004
@@ -405,6 +405,8 @@
 		}
 
 		conntrack->proto.sctp.state = newconntrack;
+		if (oldsctpstate != newconntrack)
+			ip_conntrack_cache_event(IPCT_PROTOINFO);
 		WRITE_UNLOCK(&sctp_lock);
 	}
 
===== net/ipv4/netfilter/ip_conntrack_core.c 1.72 vs edited =====
--- 1.72/net/ipv4/netfilter/ip_conntrack_core.c	Sun Oct 10 21:44:21 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_core.c	Sat Oct 16 18:41:37 2004
@@ -37,6 +37,7 @@
 #include <linux/err.h>
 #include <linux/percpu.h>
 #include <linux/moduleparam.h>
+#include <linux/notifier.h>
 
 /* This rwlock protects the main hash table, protocol/helper/expected
    registrations, conntrack timers*/
@@ -76,6 +77,11 @@
 struct ip_conntrack ip_conntrack_untracked;
 unsigned int ip_ct_log_invalid;
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+struct notifier_block *ip_conntrack_chain;
+DEFINE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+
 DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
 
 inline void 
@@ -330,6 +336,7 @@
 
 	CONNTRACK_STAT_INC(delete_list);
 
+	ip_conntrack_event(IPCT_DESTROY, ct);
 	WRITE_LOCK(&ip_conntrack_lock);
 	clean_from_lists(ct);
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -437,6 +444,7 @@
 		atomic_inc(&ct->ct_general.use);
 		set_bit(IPS_CONFIRMED_BIT, &ct->status);
 		WRITE_UNLOCK(&ip_conntrack_lock);
+ 		ip_conntrack_event(master_ct(ct)? IPCT_RELATED : IPCT_NEW, ct);
 		CONNTRACK_STAT_INC(insert);
 		return NF_ACCEPT;
 	}
@@ -706,6 +714,8 @@
 	/* FIXME: Do this right please. --RR */
 	(*pskb)->nfcache |= NFC_UNKNOWN;
 
+	ip_conntrack_event_cache_init();
+
 /* Doesn't cover locally-generated broadcast, so not worth it. */
 #if 0
 	/* Ignore broadcast: no `connection'. */
@@ -767,8 +777,11 @@
 			return NF_ACCEPT;
 		}
 	}
-	if (set_reply)
+	if (set_reply && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
 		set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
+		ip_conntrack_cache_event(IPCT_STATUS);
+	}
+	ip_conntrack_deliver_cached_events(ct);
 
 	return ret;
 }
@@ -1052,6 +1065,7 @@
 		remove_expectations(i->ctrack, 0);
 		/* And *then* set helper to NULL */
 		i->ctrack->helper = NULL;
+		ip_conntrack_event(IPCT_HELPINFO, i->ctrack);
 	}
 	return 0;
 }
@@ -1105,6 +1119,7 @@
 		if (del_timer(&ct->timeout)) {
 			ct->timeout.expires = jiffies + extra_jiffies;
 			add_timer(&ct->timeout);
+			ip_conntrack_cache_event(IPCT_REFRESH);
 		}
 		ct_add_counters(ct, ctinfo, skb);
 		WRITE_UNLOCK(&ip_conntrack_lock);
===== net/ipv4/netfilter/ip_conntrack_ftp.c 1.27 vs edited =====
--- 1.27/net/ipv4/netfilter/ip_conntrack_ftp.c	Sun Oct 10 21:44:22 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_ftp.c	Sat Oct 16 18:41:37 2004
@@ -300,6 +300,7 @@
 			ct_ftp_info->seq_aft_nl[dir] = 
 						ntohl(th->seq) + datalen;
 			ct_ftp_info->seq_aft_nl_set[dir] = 1;
+			ip_conntrack_cache_event(IPCT_HELPINFO);
 		}
 	}
 
===== net/ipv4/netfilter/ip_conntrack_standalone.c 1.51 vs edited =====
--- 1.51/net/ipv4/netfilter/ip_conntrack_standalone.c	Thu Oct  7 00:11:17 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_standalone.c	Sat Oct 16 18:41:37 2004
@@ -47,6 +47,9 @@
 
 extern atomic_t ip_conntrack_count;
 DECLARE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+DECLARE_PER_CPU(unsigned long, ip_conntrack_event_cache);
+#endif
 
 static int kill_proto(const struct ip_conntrack *i, void *data)
 {
@@ -875,6 +878,10 @@
 {
 }
 
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+EXPORT_PER_CPU_SYMBOL(ip_conntrack_event_cache);
+EXPORT_SYMBOL(ip_conntrack_chain);
+#endif
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
 EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
 EXPORT_SYMBOL(invert_tuplepr);
===== net/ipv4/netfilter/ip_conntrack_proto_tcp.c 1.23 vs edited =====
--- 1.23/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Mon Sep 13 02:00:29 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Sat Oct 16 18:42:58 2004
@@ -823,6 +823,32 @@
 	return NF_ACCEPT;
 }
 
+static inline void
+pickup_connection(struct ip_conntrack *conntrack, struct iphdr *iph,
+		  struct tcphdr *th, const struct sk_buff *skb)
+{
+	/*
+	 * We are in the middle of a connection,
+	 * its history is lost for us.
+	 * Let's try to use the data from the packet.
+	 */
+	conntrack->proto.tcp.seen[0].td_end =
+		segment_seq_plus_len(ntohl(th->seq), skb->len, iph, th);
+	conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+	if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
+		conntrack->proto.tcp.seen[0].td_maxwin = 1;
+	conntrack->proto.tcp.seen[0].td_maxend =
+		conntrack->proto.tcp.seen[0].td_end + 
+		conntrack->proto.tcp.seen[0].td_maxwin;
+	conntrack->proto.tcp.seen[0].td_scale = 0;
+
+	/* We assume SACK. Should we assume window scaling too? */
+	conntrack->proto.tcp.seen[0].flags =
+	conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
+	conntrack->proto.tcp.seen[0].loose = 
+	conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
+}
+
 /* Returns verdict for packet, or -1 for invalid. */
 static int tcp_packet(struct ip_conntrack *conntrack,
 		      const struct sk_buff *skb,
@@ -838,6 +864,11 @@
 	th = skb_header_pointer(skb, iph->ihl * 4,
 				sizeof(_tcph), &_tcph);
 	BUG_ON(th == NULL);
+
+	if (test_bit(IPS_PICKUP_BIT, &conntrack->status)) {
+		pickup_connection(conntrack, iph, th, skb);
+		__clear_bit(IPS_PICKUP_BIT, &conntrack->status);
+	}
 	
 	WRITE_LOCK(&tcp_lock);
 	old_state = conntrack->proto.tcp.state;
@@ -944,6 +975,10 @@
 		  ? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
 	WRITE_UNLOCK(&tcp_lock);
 
+	ip_conntrack_cache_event(IPCT_PROTOINFO_VOLATILE);
+	if (new_state != old_state)
+		ip_conntrack_cache_event(IPCT_PROTOINFO);
+
 	if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
 		/* If only reply is a RST, we can consider ourselves not to
 		   have an established connection: this is a fairly common
@@ -1014,29 +1049,8 @@
 	} else if (ip_ct_tcp_loose == 0) {
 		/* Don't try to pick up connections. */
 		return 0;
-	} else {
-		/*
-		 * We are in the middle of a connection,
-		 * its history is lost for us.
-		 * Let's try to use the data from the packet.
-		 */
-		conntrack->proto.tcp.seen[0].td_end =
-			segment_seq_plus_len(ntohl(th->seq), skb->len,
-					     iph, th);
-		conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
-		if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
-			conntrack->proto.tcp.seen[0].td_maxwin = 1;
-		conntrack->proto.tcp.seen[0].td_maxend =
-			conntrack->proto.tcp.seen[0].td_end + 
-			conntrack->proto.tcp.seen[0].td_maxwin;
-		conntrack->proto.tcp.seen[0].td_scale = 0;
-
-		/* We assume SACK. Should we assume window scaling too? */
-		conntrack->proto.tcp.seen[0].flags =
-		conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
-		conntrack->proto.tcp.seen[0].loose = 
-		conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose;
-	}
+	} else 
+		pickup_connection(conntrack, iph, th, skb);
     
 	conntrack->proto.tcp.seen[1].td_end = 0;
 	conntrack->proto.tcp.seen[1].td_maxend = 0;
===== net/ipv4/netfilter/ip_conntrack_proto_udp.c 1.18 vs edited =====
--- 1.18/net/ipv4/netfilter/ip_conntrack_proto_udp.c	Sun Oct 10 21:44:22 2004
+++ edited/net/ipv4/netfilter/ip_conntrack_proto_udp.c	Sat Oct 16 18:41:37 2004
@@ -73,7 +73,10 @@
 		ip_ct_refresh_acct(conntrack, ctinfo, skb, 
 				   ip_ct_udp_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
-		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+		if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)) {
+			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+			ip_conntrack_cache_event(IPCT_STATUS);
+		}
 	} else
 		ip_ct_refresh_acct(conntrack, ctinfo, skb, ip_ct_udp_timeout);
 
===== net/ipv4/netfilter/ip_nat_core.c 1.48 vs edited =====
--- 1.48/net/ipv4/netfilter/ip_nat_core.c	Sun Oct 10 21:44:22 2004
+++ edited/net/ipv4/netfilter/ip_nat_core.c	Sat Oct 16 18:41:37 2004
@@ -607,6 +607,7 @@
 			   IP_NAT_MANIP_SRC, inv_tuple.src });
 		IP_NF_ASSERT(info->num_manips <= IP_NAT_MAX_MANIPS);
 	}
+	ip_conntrack_event(IPCT_NATINFO, conntrack);
 
 	/* If there's a helper, assign it; based on new tuple. */
 	if (!conntrack->master)

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-10-16 18:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-15 17:54 [PATCH 2.6] connection tracking events Harald Welte
2004-10-16 13:21 ` Patrick McHardy
2004-10-16 15:07   ` Harald Welte
2004-10-16 15:20     ` Patrick McHardy
2004-10-16 15:32       ` Pablo Neira
2004-10-16 18:21         ` Pablo Neira

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.