diff options
author | Alexey Dobriyan <adobriyan@sw.ru> | 2008-01-31 07:02:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:27:35 -0500 |
commit | 8d870052079d255917ec4f8431f5ec102707b7af (patch) | |
tree | 77ab4f07ef4980d179c4e47d3a6e034c055f9bdf /net/netfilter | |
parent | a98da11d88dbec1d5cebe2c6dbe9939ed8d13f69 (diff) |
[NETFILTER]: x_tables: per-netns xt_tables
In fact all we want is per-netns set of rules, however doing that will
unnecessary complicate routines such as ipt_hook()/ipt_do_table, so
make full xt_table array per-netns.
Every user stubbed with init_net for a while.
Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/x_tables.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index d8d8637739ba..d62f722ccccb 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -44,7 +44,6 @@ struct xt_af { | |||
44 | struct mutex mutex; | 44 | struct mutex mutex; |
45 | struct list_head match; | 45 | struct list_head match; |
46 | struct list_head target; | 46 | struct list_head target; |
47 | struct list_head tables; | ||
48 | #ifdef CONFIG_COMPAT | 47 | #ifdef CONFIG_COMPAT |
49 | struct mutex compat_mutex; | 48 | struct mutex compat_mutex; |
50 | struct compat_delta *compat_offsets; | 49 | struct compat_delta *compat_offsets; |
@@ -597,14 +596,14 @@ void xt_free_table_info(struct xt_table_info *info) | |||
597 | EXPORT_SYMBOL(xt_free_table_info); | 596 | EXPORT_SYMBOL(xt_free_table_info); |
598 | 597 | ||
599 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | 598 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ |
600 | struct xt_table *xt_find_table_lock(int af, const char *name) | 599 | struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name) |
601 | { | 600 | { |
602 | struct xt_table *t; | 601 | struct xt_table *t; |
603 | 602 | ||
604 | if (mutex_lock_interruptible(&xt[af].mutex) != 0) | 603 | if (mutex_lock_interruptible(&xt[af].mutex) != 0) |
605 | return ERR_PTR(-EINTR); | 604 | return ERR_PTR(-EINTR); |
606 | 605 | ||
607 | list_for_each_entry(t, &xt[af].tables, list) | 606 | list_for_each_entry(t, &net->xt.tables[af], list) |
608 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | 607 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) |
609 | return t; | 608 | return t; |
610 | mutex_unlock(&xt[af].mutex); | 609 | mutex_unlock(&xt[af].mutex); |
@@ -660,7 +659,7 @@ xt_replace_table(struct xt_table *table, | |||
660 | } | 659 | } |
661 | EXPORT_SYMBOL_GPL(xt_replace_table); | 660 | EXPORT_SYMBOL_GPL(xt_replace_table); |
662 | 661 | ||
663 | struct xt_table *xt_register_table(struct xt_table *table, | 662 | struct xt_table *xt_register_table(struct net *net, struct xt_table *table, |
664 | struct xt_table_info *bootstrap, | 663 | struct xt_table_info *bootstrap, |
665 | struct xt_table_info *newinfo) | 664 | struct xt_table_info *newinfo) |
666 | { | 665 | { |
@@ -673,7 +672,7 @@ struct xt_table *xt_register_table(struct xt_table *table, | |||
673 | goto out; | 672 | goto out; |
674 | 673 | ||
675 | /* Don't autoload: we'd eat our tail... */ | 674 | /* Don't autoload: we'd eat our tail... */ |
676 | list_for_each_entry(t, &xt[table->af].tables, list) { | 675 | list_for_each_entry(t, &net->xt.tables[table->af], list) { |
677 | if (strcmp(t->name, table->name) == 0) { | 676 | if (strcmp(t->name, table->name) == 0) { |
678 | ret = -EEXIST; | 677 | ret = -EEXIST; |
679 | goto unlock; | 678 | goto unlock; |
@@ -692,7 +691,7 @@ struct xt_table *xt_register_table(struct xt_table *table, | |||
692 | /* save number of initial entries */ | 691 | /* save number of initial entries */ |
693 | private->initial_entries = private->number; | 692 | private->initial_entries = private->number; |
694 | 693 | ||
695 | list_add(&table->list, &xt[table->af].tables); | 694 | list_add(&table->list, &net->xt.tables[table->af]); |
696 | mutex_unlock(&xt[table->af].mutex); | 695 | mutex_unlock(&xt[table->af].mutex); |
697 | return table; | 696 | return table; |
698 | 697 | ||
@@ -744,7 +743,7 @@ static struct list_head *type2list(u_int16_t af, u_int16_t type) | |||
744 | list = &xt[af].match; | 743 | list = &xt[af].match; |
745 | break; | 744 | break; |
746 | case TABLE: | 745 | case TABLE: |
747 | list = &xt[af].tables; | 746 | list = &init_net.xt.tables[af]; |
748 | break; | 747 | break; |
749 | default: | 748 | default: |
750 | list = NULL; | 749 | list = NULL; |
@@ -919,10 +918,22 @@ void xt_proto_fini(int af) | |||
919 | } | 918 | } |
920 | EXPORT_SYMBOL_GPL(xt_proto_fini); | 919 | EXPORT_SYMBOL_GPL(xt_proto_fini); |
921 | 920 | ||
921 | static int __net_init xt_net_init(struct net *net) | ||
922 | { | ||
923 | int i; | ||
924 | |||
925 | for (i = 0; i < NPROTO; i++) | ||
926 | INIT_LIST_HEAD(&net->xt.tables[i]); | ||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | static struct pernet_operations xt_net_ops = { | ||
931 | .init = xt_net_init, | ||
932 | }; | ||
922 | 933 | ||
923 | static int __init xt_init(void) | 934 | static int __init xt_init(void) |
924 | { | 935 | { |
925 | int i; | 936 | int i, rv; |
926 | 937 | ||
927 | xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); | 938 | xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); |
928 | if (!xt) | 939 | if (!xt) |
@@ -936,13 +947,16 @@ static int __init xt_init(void) | |||
936 | #endif | 947 | #endif |
937 | INIT_LIST_HEAD(&xt[i].target); | 948 | INIT_LIST_HEAD(&xt[i].target); |
938 | INIT_LIST_HEAD(&xt[i].match); | 949 | INIT_LIST_HEAD(&xt[i].match); |
939 | INIT_LIST_HEAD(&xt[i].tables); | ||
940 | } | 950 | } |
941 | return 0; | 951 | rv = register_pernet_subsys(&xt_net_ops); |
952 | if (rv < 0) | ||
953 | kfree(xt); | ||
954 | return rv; | ||
942 | } | 955 | } |
943 | 956 | ||
944 | static void __exit xt_fini(void) | 957 | static void __exit xt_fini(void) |
945 | { | 958 | { |
959 | unregister_pernet_subsys(&xt_net_ops); | ||
946 | kfree(xt); | 960 | kfree(xt); |
947 | } | 961 | } |
948 | 962 | ||