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

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.