diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-10-08 05:35:02 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2008-10-08 05:35:02 -0400 |
commit | 5a1fb391d881905e89623d78858d05b248cbc86a (patch) | |
tree | 5a373417064f8792f413b22be37302fe0668966e /net | |
parent | dfdb8d791877052bbb527d9688d94a064721d8f7 (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>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 17 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 2 |
2 files changed, 14 insertions, 5 deletions
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 | ||
467 | struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, | 467 | struct 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. */ |
530 | static struct nf_conntrack_tuple_hash * | 534 | static struct nf_conntrack_tuple_hash * |
531 | init_conntrack(const struct nf_conntrack_tuple *tuple, | 535 | init_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 | ||