aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-10-08 05:35:02 -0400
committerPatrick McHardy <kaber@trash.net>2008-10-08 05:35:02 -0400
commit5a1fb391d881905e89623d78858d05b248cbc86a (patch)
tree5a373417064f8792f413b22be37302fe0668966e
parentdfdb8d791877052bbb527d9688d94a064721d8f7 (diff)
netfilter: netns nf_conntrack: add ->ct_net -- pointer from conntrack to netns
Conntrack (struct nf_conn) gets pointer to netns: ->ct_net -- netns in which it was created. It comes from netdevice. ->ct_net is write-once field. Every conntrack in system has ->ct_net initialized, no exceptions. ->ct_net doesn't pin netns: conntracks are recycled after timeouts and pinning background traffic will prevent netns from even starting shutdown sequence. Right now every conntrack is created in init_net. Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/net/netfilter/nf_conntrack.h18
-rw-r--r--net/netfilter/nf_conntrack_core.c17
-rw-r--r--net/netfilter/nf_conntrack_netlink.c2
3 files changed, 30 insertions, 7 deletions
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 0741ad592da..2b8d6efecf3 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -123,7 +123,9 @@ struct nf_conn
123 123
124 /* Extensions */ 124 /* Extensions */
125 struct nf_ct_ext *ext; 125 struct nf_ct_ext *ext;
126 126#ifdef CONFIG_NET_NS
127 struct net *ct_net;
128#endif
127 struct rcu_head rcu; 129 struct rcu_head rcu;
128}; 130};
129 131
@@ -147,6 +149,17 @@ static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
147/* get master conntrack via master expectation */ 149/* get master conntrack via master expectation */
148#define master_ct(conntr) (conntr->master) 150#define master_ct(conntr) (conntr->master)
149 151
152extern struct net init_net;
153
154static inline struct net *nf_ct_net(const struct nf_conn *ct)
155{
156#ifdef CONFIG_NET_NS
157 return ct->ct_net;
158#else
159 return &init_net;
160#endif
161}
162
150/* Alter reply tuple (maybe alter helper). */ 163/* Alter reply tuple (maybe alter helper). */
151extern void 164extern void
152nf_conntrack_alter_reply(struct nf_conn *ct, 165nf_conntrack_alter_reply(struct nf_conn *ct,
@@ -251,7 +264,8 @@ extern void
251nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data); 264nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
252extern void nf_conntrack_free(struct nf_conn *ct); 265extern void nf_conntrack_free(struct nf_conn *ct);
253extern struct nf_conn * 266extern struct nf_conn *
254nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 267nf_conntrack_alloc(struct net *net,
268 const struct nf_conntrack_tuple *orig,
255 const struct nf_conntrack_tuple *repl, 269 const struct nf_conntrack_tuple *repl,
256 gfp_t gfp); 270 gfp_t gfp);
257 271
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ee79e932589..cefc338f6e5 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -464,7 +464,8 @@ static noinline int early_drop(unsigned int hash)
464 return dropped; 464 return dropped;
465} 465}
466 466
467struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 467struct nf_conn *nf_conntrack_alloc(struct net *net,
468 const struct nf_conntrack_tuple *orig,
468 const struct nf_conntrack_tuple *repl, 469 const struct nf_conntrack_tuple *repl,
469 gfp_t gfp) 470 gfp_t gfp)
470{ 471{
@@ -503,6 +504,9 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
503 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; 504 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
504 /* Don't set timer yet: wait for confirmation */ 505 /* Don't set timer yet: wait for confirmation */
505 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); 506 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
507#ifdef CONFIG_NET_NS
508 ct->ct_net = net;
509#endif
506 INIT_RCU_HEAD(&ct->rcu); 510 INIT_RCU_HEAD(&ct->rcu);
507 511
508 return ct; 512 return ct;
@@ -528,7 +532,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free);
528/* Allocate a new conntrack: we return -ENOMEM if classification 532/* Allocate a new conntrack: we return -ENOMEM if classification
529 failed due to stress. Otherwise it really is unclassifiable. */ 533 failed due to stress. Otherwise it really is unclassifiable. */
530static struct nf_conntrack_tuple_hash * 534static struct nf_conntrack_tuple_hash *
531init_conntrack(const struct nf_conntrack_tuple *tuple, 535init_conntrack(struct net *net,
536 const struct nf_conntrack_tuple *tuple,
532 struct nf_conntrack_l3proto *l3proto, 537 struct nf_conntrack_l3proto *l3proto,
533 struct nf_conntrack_l4proto *l4proto, 538 struct nf_conntrack_l4proto *l4proto,
534 struct sk_buff *skb, 539 struct sk_buff *skb,
@@ -544,7 +549,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
544 return NULL; 549 return NULL;
545 } 550 }
546 551
547 ct = nf_conntrack_alloc(tuple, &repl_tuple, GFP_ATOMIC); 552 ct = nf_conntrack_alloc(net, tuple, &repl_tuple, GFP_ATOMIC);
548 if (ct == NULL || IS_ERR(ct)) { 553 if (ct == NULL || IS_ERR(ct)) {
549 pr_debug("Can't allocate conntrack.\n"); 554 pr_debug("Can't allocate conntrack.\n");
550 return (struct nf_conntrack_tuple_hash *)ct; 555 return (struct nf_conntrack_tuple_hash *)ct;
@@ -631,7 +636,8 @@ resolve_normal_ct(struct sk_buff *skb,
631 /* look for tuple match */ 636 /* look for tuple match */
632 h = nf_conntrack_find_get(&tuple); 637 h = nf_conntrack_find_get(&tuple);
633 if (!h) { 638 if (!h) {
634 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff); 639 h = init_conntrack(&init_net, &tuple, l3proto, l4proto, skb,
640 dataoff);
635 if (!h) 641 if (!h)
636 return NULL; 642 return NULL;
637 if (IS_ERR(h)) 643 if (IS_ERR(h))
@@ -1185,6 +1191,9 @@ int nf_conntrack_init(struct net *net)
1185 1191
1186 /* Set up fake conntrack: 1192 /* Set up fake conntrack:
1187 - to never be deleted, not in any hashes */ 1193 - to never be deleted, not in any hashes */
1194#ifdef CONFIG_NET_NS
1195 nf_conntrack_untracked.ct_net = &init_net;
1196#endif
1188 atomic_set(&nf_conntrack_untracked.ct_general.use, 1); 1197 atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1189 /* - and look it like as a confirmed connection */ 1198 /* - and look it like as a confirmed connection */
1190 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status); 1199 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a8752031adc..da3cdc8db70 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1125,7 +1125,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1125 struct nf_conn_help *help; 1125 struct nf_conn_help *help;
1126 struct nf_conntrack_helper *helper; 1126 struct nf_conntrack_helper *helper;
1127 1127
1128 ct = nf_conntrack_alloc(otuple, rtuple, GFP_KERNEL); 1128 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_KERNEL);
1129 if (ct == NULL || IS_ERR(ct)) 1129 if (ct == NULL || IS_ERR(ct))
1130 return -ENOMEM; 1130 return -ENOMEM;
1131 1131