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))
next 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).