All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vitaly E. Lavrov" <lve@guap.ru>
To: netfilter-devel@vger.kernel.org
Subject: [RFC PATCH nf_conntrack_extend] new extensions without changes kernel source
Date: Wed, 16 Oct 2013 23:36:23 +0400	[thread overview]
Message-ID: <525EEAB7.4090901@guap.ru> (raw)

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

How to add additional data to the conntrack? This is needed to
the implementation of ndpi-netfilter.

Now it is possible to add data to a struct "nf_conn-> ext" through
nf_conntrack_extend, but it requires a change in the kernel code.

I have developed a patch to register custom extensions in nf_conn->ext.
In the kernel configuration, you can specify the maximum number of additional
extensions (0..8). When registering a custom extension to specify an
additional unique identifier extension (u32). In the extension properties
seq_print added optional method to display data in "/proc/net/nf_conntrack".

What lacks is in this patch?


[-- Attachment #2: nf_conntrack_custom_extend.diff --]
[-- Type: text/plain, Size: 5906 bytes --]

diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
index 977bc8a..720f699 100644
--- a/include/net/netfilter/nf_conntrack_extend.h
+++ b/include/net/netfilter/nf_conntrack_extend.h
@@ -26,7 +26,8 @@ enum nf_ct_ext_id {
 #ifdef CONFIG_NF_CONNTRACK_LABELS
 	NF_CT_EXT_LABELS,
 #endif
-	NF_CT_EXT_NUM,
+	NF_CT_EXT_CUSTOM,
+	NF_CT_EXT_NUM=NF_CT_EXT_CUSTOM+CONFIG_NF_CONNTRACK_CUSTOM,
 };
 
 #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
@@ -94,12 +95,16 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
 
 #define NF_CT_EXT_F_PREALLOC	0x0001
 
+struct seq_file;
+
 struct nf_ct_ext_type {
 	/* Destroys relationships (can be NULL). */
 	void (*destroy)(struct nf_conn *ct);
 	/* Called when realloacted (can be NULL).
 	   Contents has already been moved. */
 	void (*move)(void *new, void *old);
+	/* Print custom info (can be NULL) */
+	unsigned int (*seq_print)(struct seq_file *s, const struct nf_conn *ct, int dir);
 
 	enum nf_ct_ext_id id;
 
@@ -112,6 +117,8 @@ struct nf_ct_ext_type {
 	u8 alloc_size;
 };
 
+unsigned int nf_ct_ext_seq_print(struct seq_file *s, const struct nf_conn *ct, int dir);
 int nf_ct_extend_register(struct nf_ct_ext_type *type);
+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type,unsigned long int cid);
 void nf_ct_extend_unregister(struct nf_ct_ext_type *type);
 #endif /* _NF_CONNTRACK_EXTEND_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9e7732d..75c8a5d 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -70,6 +70,16 @@ config NF_CONNTRACK_SECMARK
 
 	  If unsure, say 'N'.
 
+config NF_CONNTRACK_CUSTOM
+	int "Number of custom extend"
+	range 0 8
+	depends on NETFILTER_ADVANCED
+	default "4"
+	help
+	  This parameter specifies how many custom extensions can be registered.
+
+	  The default value is 4.
+
 config NF_CONNTRACK_ZONES
 	bool  'Connection tracking zones'
 	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 2d3030a..7f97126 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -52,6 +52,7 @@ seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir)
 EXPORT_SYMBOL_GPL(seq_print_acct);
 
 static struct nf_ct_ext_type acct_extend __read_mostly = {
+	.seq_print = seq_print_acct,
 	.len	= sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]),
 	.align	= __alignof__(struct nf_conn_counter[IP_CT_DIR_MAX]),
 	.id	= NF_CT_EXT_ACCT,
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index 1a95459..28499ae 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -43,6 +43,30 @@ void __nf_ct_ext_destroy(struct nf_conn *ct)
 }
 EXPORT_SYMBOL(__nf_ct_ext_destroy);
 
+struct seq_file;
+
+unsigned int nf_ct_ext_seq_print(struct seq_file *s, const struct nf_conn *ct, int dir)
+{
+	unsigned int i,ret=0;
+	struct nf_ct_ext_type *t;
+	struct nf_ct_ext *ext = ct->ext;
+
+	for (i = 0; i < NF_CT_EXT_NUM; i++) {
+		if (!__nf_ct_ext_exist(ext, i))
+			continue;
+
+		rcu_read_lock(); // FIXME
+		t = rcu_dereference(nf_ct_ext_types[i]);
+		if (t && t->seq_print)
+			ret = t->seq_print(s,ct,dir);
+		rcu_read_unlock();
+		if(ret)
+			return ret;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(nf_ct_ext_seq_print);
+
 static void *
 nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id,
 		 size_t var_alloc_len, gfp_t gfp)
@@ -156,6 +180,24 @@ static void update_alloc_size(struct nf_ct_ext_type *type)
 	}
 }
 
+static unsigned long int nf_ct_ext_cust_id[CONFIG_NF_CONNTRACK_CUSTOM];
+static enum nf_ct_ext_id 
+nf_ct_extend_get_custom_id(unsigned long int ext_id)
+{
+	enum nf_ct_ext_id ret = 0;
+	int i;
+	mutex_lock(&nf_ct_ext_type_mutex);
+	for(i = 0; i < CONFIG_NF_CONNTRACK_CUSTOM; i++) {
+		if(!nf_ct_ext_cust_id[i]) {
+			nf_ct_ext_cust_id[i] = ext_id;
+			ret = i+NF_CT_EXT_CUSTOM;
+			break;
+		}
+	}
+	mutex_unlock(&nf_ct_ext_type_mutex);
+	return ret;
+}
+
 /* This MUST be called in process context. */
 int nf_ct_extend_register(struct nf_ct_ext_type *type)
 {
@@ -179,12 +221,32 @@ out:
 }
 EXPORT_SYMBOL_GPL(nf_ct_extend_register);
 
+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type,
+				 unsigned long int cid)
+{
+	int ret;
+	enum nf_ct_ext_id new_id = nf_ct_extend_get_custom_id(cid);
+	if(!new_id)
+		return -EBUSY;
+	type->id = new_id;
+	ret = nf_ct_extend_register(type);
+	if(ret < 0) {
+		mutex_lock(&nf_ct_ext_type_mutex);
+		nf_ct_ext_cust_id[new_id - NF_CT_EXT_CUSTOM] = 0;
+		mutex_unlock(&nf_ct_ext_type_mutex);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(nf_ct_extend_custom_register);
+
 /* This MUST be called in process context. */
 void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
 {
 	mutex_lock(&nf_ct_ext_type_mutex);
 	RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL);
 	update_alloc_size(type);
+	if(type->id >= NF_CT_EXT_CUSTOM && type->id < NF_CT_EXT_NUM)
+		nf_ct_ext_cust_id[type->id-NF_CT_EXT_CUSTOM] = 0;
 	mutex_unlock(&nf_ct_ext_type_mutex);
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
 }
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 63bad61..1d5b311 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -206,7 +206,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
 			l3proto, l4proto))
 		goto release;
 
-	if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
+	if (nf_ct_ext_seq_print(s,ct,IP_CT_DIR_ORIGINAL))
 		goto release;
 
 	if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
@@ -217,7 +217,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
 			l3proto, l4proto))
 		goto release;
 
-	if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
+	if (nf_ct_ext_seq_print(s,ct,IP_CT_DIR_REPLY))
 		goto release;
 
 	if (test_bit(IPS_ASSURED_BIT, &ct->status))

             reply	other threads:[~2013-10-16 19:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-16 19:36 Vitaly E. Lavrov [this message]
2013-10-29 12:22 ` [RFC PATCH nf_conntrack_extend] new extensions without changes kernel source Pablo Neira Ayuso
2013-10-31  9:22   ` Dirk
2013-11-02 14:30   ` Vitaly E. Lavrov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=525EEAB7.4090901@guap.ru \
    --to=lve@guap.ru \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.