From 719f0efb5a355adc04653d12d946901c8a051177 Mon Sep 17 00:00:00 2001 From: Vitaly Lavrov Date: Mon, 10 Dec 2018 12:34:10 +0300 Subject: [PATCH] Add NF_CUSTOM --- include/net/netfilter/nf_conntrack_extend.h | 4 ++- net/netfilter/Kconfig | 10 +++++++ net/netfilter/nf_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_extend.c | 45 +++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 112a6f4..6146689 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -28,7 +28,8 @@ enum nf_ct_ext_id { #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) NF_CT_EXT_SYNPROXY, #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 @@ -96,5 +97,6 @@ struct nf_ct_ext_type { }; int nf_ct_extend_register(const 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(const struct nf_ct_ext_type *type); #endif /* _NF_CONNTRACK_EXTEND_H */ diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index d374a93..2ca93aa 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -104,6 +104,16 @@ config NF_CONNTRACK_SECMARK If unsure, say 'N'. +config NF_CONNTRACK_CUSTOM + int "Number of custom extend" + range 0 4 + depends on NETFILTER_ADVANCED + default "2" + help + This parameter specifies how many custom extensions can be registered. + + The default value is 2. + config NF_CONNTRACK_ZONES bool 'Connection tracking zones' depends on NETFILTER_ADVANCED diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 9a40312..83e9379 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -2409,7 +2409,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); static __always_inline unsigned int total_extension_size(void) { /* remember to add new extensions below */ - BUILD_BUG_ON(NF_CT_EXT_NUM > 9); + BUILD_BUG_ON(NF_CT_EXT_NUM > 12); return sizeof(struct nf_ct_ext) + sizeof(struct nf_conn_help) diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index d4ed1e1..00d7fc6 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -106,11 +106,56 @@ int nf_ct_extend_register(const struct nf_ct_ext_type *type) } EXPORT_SYMBOL_GPL(nf_ct_extend_register); +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); + +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); + +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; + } + if(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. */ void nf_ct_extend_unregister(const struct nf_ct_ext_type *type) { mutex_lock(&nf_ct_ext_type_mutex); RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); + 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); synchronize_rcu(); } -- 2.9.0