Commit f6f2e580 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: conntrack: move expect counter to net_generic data

Creation of a new conntrack entry isn't a frequent operation (compared
to 'ct entry already exists').  Creation of a new entry that is also an
expected (related) connection even less so.

Place this counter in net_generic data.

A followup patch will also move the conntrack count -- this will make
netns_ct a read-mostly structure.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 67f28216
...@@ -45,6 +45,7 @@ union nf_conntrack_expect_proto { ...@@ -45,6 +45,7 @@ union nf_conntrack_expect_proto {
struct nf_conntrack_net { struct nf_conntrack_net {
/* only used when new connection is allocated: */ /* only used when new connection is allocated: */
unsigned int expect_count;
u8 sysctl_auto_assign_helper; u8 sysctl_auto_assign_helper;
bool auto_assign_helper_warned; bool auto_assign_helper_warned;
......
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#include "nf_internals.h" #include "nf_internals.h"
extern unsigned int nf_conntrack_net_id;
__cacheline_aligned_in_smp spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS]; __cacheline_aligned_in_smp spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS];
EXPORT_SYMBOL_GPL(nf_conntrack_locks); EXPORT_SYMBOL_GPL(nf_conntrack_locks);
...@@ -1570,6 +1572,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, ...@@ -1570,6 +1572,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
const struct nf_conntrack_zone *zone; const struct nf_conntrack_zone *zone;
struct nf_conn_timeout *timeout_ext; struct nf_conn_timeout *timeout_ext;
struct nf_conntrack_zone tmp; struct nf_conntrack_zone tmp;
struct nf_conntrack_net *cnet;
if (!nf_ct_invert_tuple(&repl_tuple, tuple)) { if (!nf_ct_invert_tuple(&repl_tuple, tuple)) {
pr_debug("Can't invert tuple.\n"); pr_debug("Can't invert tuple.\n");
...@@ -1603,7 +1606,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, ...@@ -1603,7 +1606,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
GFP_ATOMIC); GFP_ATOMIC);
local_bh_disable(); local_bh_disable();
if (net->ct.expect_count) { cnet = net_generic(net, nf_conntrack_net_id);
if (cnet->expect_count) {
spin_lock(&nf_conntrack_expect_lock); spin_lock(&nf_conntrack_expect_lock);
exp = nf_ct_find_expectation(net, zone, tuple); exp = nf_ct_find_expectation(net, zone, tuple);
if (exp) { if (exp) {
......
...@@ -43,18 +43,23 @@ unsigned int nf_ct_expect_max __read_mostly; ...@@ -43,18 +43,23 @@ unsigned int nf_ct_expect_max __read_mostly;
static struct kmem_cache *nf_ct_expect_cachep __read_mostly; static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
static unsigned int nf_ct_expect_hashrnd __read_mostly; static unsigned int nf_ct_expect_hashrnd __read_mostly;
extern unsigned int nf_conntrack_net_id;
/* nf_conntrack_expect helper functions */ /* nf_conntrack_expect helper functions */
void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
u32 portid, int report) u32 portid, int report)
{ {
struct nf_conn_help *master_help = nfct_help(exp->master); struct nf_conn_help *master_help = nfct_help(exp->master);
struct net *net = nf_ct_exp_net(exp); struct net *net = nf_ct_exp_net(exp);
struct nf_conntrack_net *cnet;
WARN_ON(!master_help); WARN_ON(!master_help);
WARN_ON(timer_pending(&exp->timeout)); WARN_ON(timer_pending(&exp->timeout));
hlist_del_rcu(&exp->hnode); hlist_del_rcu(&exp->hnode);
net->ct.expect_count--;
cnet = net_generic(net, nf_conntrack_net_id);
cnet->expect_count--;
hlist_del_rcu(&exp->lnode); hlist_del_rcu(&exp->lnode);
master_help->expecting[exp->class]--; master_help->expecting[exp->class]--;
...@@ -118,10 +123,11 @@ __nf_ct_expect_find(struct net *net, ...@@ -118,10 +123,11 @@ __nf_ct_expect_find(struct net *net,
const struct nf_conntrack_zone *zone, const struct nf_conntrack_zone *zone,
const struct nf_conntrack_tuple *tuple) const struct nf_conntrack_tuple *tuple)
{ {
struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id);
struct nf_conntrack_expect *i; struct nf_conntrack_expect *i;
unsigned int h; unsigned int h;
if (!net->ct.expect_count) if (!cnet->expect_count)
return NULL; return NULL;
h = nf_ct_expect_dst_hash(net, tuple); h = nf_ct_expect_dst_hash(net, tuple);
...@@ -158,10 +164,11 @@ nf_ct_find_expectation(struct net *net, ...@@ -158,10 +164,11 @@ nf_ct_find_expectation(struct net *net,
const struct nf_conntrack_zone *zone, const struct nf_conntrack_zone *zone,
const struct nf_conntrack_tuple *tuple) const struct nf_conntrack_tuple *tuple)
{ {
struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id);
struct nf_conntrack_expect *i, *exp = NULL; struct nf_conntrack_expect *i, *exp = NULL;
unsigned int h; unsigned int h;
if (!net->ct.expect_count) if (!cnet->expect_count)
return NULL; return NULL;
h = nf_ct_expect_dst_hash(net, tuple); h = nf_ct_expect_dst_hash(net, tuple);
...@@ -368,6 +375,7 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_put); ...@@ -368,6 +375,7 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_put);
static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
{ {
struct nf_conntrack_net *cnet;
struct nf_conn_help *master_help = nfct_help(exp->master); struct nf_conn_help *master_help = nfct_help(exp->master);
struct nf_conntrack_helper *helper; struct nf_conntrack_helper *helper;
struct net *net = nf_ct_exp_net(exp); struct net *net = nf_ct_exp_net(exp);
...@@ -389,7 +397,8 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) ...@@ -389,7 +397,8 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
master_help->expecting[exp->class]++; master_help->expecting[exp->class]++;
hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]);
net->ct.expect_count++; cnet = net_generic(net, nf_conntrack_net_id);
cnet->expect_count++;
NF_CT_STAT_INC(net, expect_create); NF_CT_STAT_INC(net, expect_create);
} }
...@@ -415,6 +424,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect, ...@@ -415,6 +424,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect,
{ {
const struct nf_conntrack_expect_policy *p; const struct nf_conntrack_expect_policy *p;
struct nf_conntrack_expect *i; struct nf_conntrack_expect *i;
struct nf_conntrack_net *cnet;
struct nf_conn *master = expect->master; struct nf_conn *master = expect->master;
struct nf_conn_help *master_help = nfct_help(master); struct nf_conn_help *master_help = nfct_help(master);
struct nf_conntrack_helper *helper; struct nf_conntrack_helper *helper;
...@@ -458,7 +468,8 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect, ...@@ -458,7 +468,8 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect,
} }
} }
if (net->ct.expect_count >= nf_ct_expect_max) { cnet = net_generic(net, nf_conntrack_net_id);
if (cnet->expect_count >= nf_ct_expect_max) {
net_warn_ratelimited("nf_conntrack: expectation table full\n"); net_warn_ratelimited("nf_conntrack: expectation table full\n");
ret = -EMFILE; ret = -EMFILE;
} }
...@@ -686,7 +697,6 @@ module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400); ...@@ -686,7 +697,6 @@ module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400);
int nf_conntrack_expect_pernet_init(struct net *net) int nf_conntrack_expect_pernet_init(struct net *net)
{ {
net->ct.expect_count = 0;
return exp_proc_init(net); return exp_proc_init(net);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment