diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2010-01-18 02:21:13 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-01-18 02:21:13 -0500 |
commit | a83d8e8d099fc373a5ca7112ad08c553bb2c180f (patch) | |
tree | 19b7bbeb34ae718f5bac20d1ab42d6280bb20665 | |
parent | a1004d8e3d463012f231bab104325ecb15637f78 (diff) |
netfilter: xtables: add struct xt_mtchk_param::net
Some complex match modules (like xt_hashlimit/xt_recent) want netns
information at constructor and destructor time. We propably can play
games at match destruction time, because netns can be passed in object,
but I think it's cleaner to explicitly pass netns.
Add ->net, make sure it's set from ebtables/iptables/ip6tables code.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/linux/netfilter/x_tables.h | 1 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 14 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 24 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 14 |
4 files changed, 32 insertions, 21 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 378f27ae7772..88261b9829a7 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -205,6 +205,7 @@ struct xt_match_param { | |||
205 | * @hook_mask: via which hooks the new rule is reachable | 205 | * @hook_mask: via which hooks the new rule is reachable |
206 | */ | 206 | */ |
207 | struct xt_mtchk_param { | 207 | struct xt_mtchk_param { |
208 | struct net *net; | ||
208 | const char *table; | 209 | const char *table; |
209 | const void *entryinfo; | 210 | const void *entryinfo; |
210 | const struct xt_match *match; | 211 | const struct xt_match *match; |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bd1c65425d4f..c77bab986696 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -619,7 +619,9 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) | |||
619 | } | 619 | } |
620 | 620 | ||
621 | static inline int | 621 | static inline int |
622 | ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | 622 | ebt_check_entry(struct ebt_entry *e, |
623 | struct net *net, | ||
624 | struct ebt_table_info *newinfo, | ||
623 | const char *name, unsigned int *cnt, | 625 | const char *name, unsigned int *cnt, |
624 | struct ebt_cl_stack *cl_s, unsigned int udc_cnt) | 626 | struct ebt_cl_stack *cl_s, unsigned int udc_cnt) |
625 | { | 627 | { |
@@ -671,6 +673,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
671 | } | 673 | } |
672 | i = 0; | 674 | i = 0; |
673 | 675 | ||
676 | mtpar.net = net; | ||
674 | mtpar.table = tgpar.table = name; | 677 | mtpar.table = tgpar.table = name; |
675 | mtpar.entryinfo = tgpar.entryinfo = e; | 678 | mtpar.entryinfo = tgpar.entryinfo = e; |
676 | mtpar.hook_mask = tgpar.hook_mask = hookmask; | 679 | mtpar.hook_mask = tgpar.hook_mask = hookmask; |
@@ -808,7 +811,8 @@ letscontinue: | |||
808 | } | 811 | } |
809 | 812 | ||
810 | /* do the parsing of the table/chains/entries/matches/watchers/targets, heh */ | 813 | /* do the parsing of the table/chains/entries/matches/watchers/targets, heh */ |
811 | static int translate_table(char *name, struct ebt_table_info *newinfo) | 814 | static int translate_table(struct net *net, char *name, |
815 | struct ebt_table_info *newinfo) | ||
812 | { | 816 | { |
813 | unsigned int i, j, k, udc_cnt; | 817 | unsigned int i, j, k, udc_cnt; |
814 | int ret; | 818 | int ret; |
@@ -917,7 +921,7 @@ static int translate_table(char *name, struct ebt_table_info *newinfo) | |||
917 | /* used to know what we need to clean up if something goes wrong */ | 921 | /* used to know what we need to clean up if something goes wrong */ |
918 | i = 0; | 922 | i = 0; |
919 | ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, | 923 | ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, |
920 | ebt_check_entry, newinfo, name, &i, cl_s, udc_cnt); | 924 | ebt_check_entry, net, newinfo, name, &i, cl_s, udc_cnt); |
921 | if (ret != 0) { | 925 | if (ret != 0) { |
922 | EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, | 926 | EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, |
923 | ebt_cleanup_entry, &i); | 927 | ebt_cleanup_entry, &i); |
@@ -1017,7 +1021,7 @@ static int do_replace(struct net *net, void __user *user, unsigned int len) | |||
1017 | if (ret != 0) | 1021 | if (ret != 0) |
1018 | goto free_counterstmp; | 1022 | goto free_counterstmp; |
1019 | 1023 | ||
1020 | ret = translate_table(tmp.name, newinfo); | 1024 | ret = translate_table(net, tmp.name, newinfo); |
1021 | 1025 | ||
1022 | if (ret != 0) | 1026 | if (ret != 0) |
1023 | goto free_counterstmp; | 1027 | goto free_counterstmp; |
@@ -1154,7 +1158,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) | |||
1154 | newinfo->hook_entry[i] = p + | 1158 | newinfo->hook_entry[i] = p + |
1155 | ((char *)repl->hook_entry[i] - repl->entries); | 1159 | ((char *)repl->hook_entry[i] - repl->entries); |
1156 | } | 1160 | } |
1157 | ret = translate_table(repl->name, newinfo); | 1161 | ret = translate_table(net, repl->name, newinfo); |
1158 | if (ret != 0) { | 1162 | if (ret != 0) { |
1159 | BUGPRINT("Translate_table failed\n"); | 1163 | BUGPRINT("Translate_table failed\n"); |
1160 | goto free_chainstack; | 1164 | goto free_chainstack; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 572330a552ef..a069d72d9482 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -661,8 +661,8 @@ static int check_target(struct ipt_entry *e, const char *name) | |||
661 | } | 661 | } |
662 | 662 | ||
663 | static int | 663 | static int |
664 | find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, | 664 | find_check_entry(struct ipt_entry *e, struct net *net, const char *name, |
665 | unsigned int *i) | 665 | unsigned int size, unsigned int *i) |
666 | { | 666 | { |
667 | struct ipt_entry_target *t; | 667 | struct ipt_entry_target *t; |
668 | struct xt_target *target; | 668 | struct xt_target *target; |
@@ -675,6 +675,7 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
675 | return ret; | 675 | return ret; |
676 | 676 | ||
677 | j = 0; | 677 | j = 0; |
678 | mtpar.net = net; | ||
678 | mtpar.table = name; | 679 | mtpar.table = name; |
679 | mtpar.entryinfo = &e->ip; | 680 | mtpar.entryinfo = &e->ip; |
680 | mtpar.hook_mask = e->comefrom; | 681 | mtpar.hook_mask = e->comefrom; |
@@ -798,7 +799,8 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) | |||
798 | /* Checks and translates the user-supplied table segment (held in | 799 | /* Checks and translates the user-supplied table segment (held in |
799 | newinfo) */ | 800 | newinfo) */ |
800 | static int | 801 | static int |
801 | translate_table(const char *name, | 802 | translate_table(struct net *net, |
803 | const char *name, | ||
802 | unsigned int valid_hooks, | 804 | unsigned int valid_hooks, |
803 | struct xt_table_info *newinfo, | 805 | struct xt_table_info *newinfo, |
804 | void *entry0, | 806 | void *entry0, |
@@ -860,7 +862,7 @@ translate_table(const char *name, | |||
860 | /* Finally, each sanity check must pass */ | 862 | /* Finally, each sanity check must pass */ |
861 | i = 0; | 863 | i = 0; |
862 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, | 864 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, |
863 | find_check_entry, name, size, &i); | 865 | find_check_entry, net, name, size, &i); |
864 | 866 | ||
865 | if (ret != 0) { | 867 | if (ret != 0) { |
866 | IPT_ENTRY_ITERATE(entry0, newinfo->size, | 868 | IPT_ENTRY_ITERATE(entry0, newinfo->size, |
@@ -1303,7 +1305,7 @@ do_replace(struct net *net, void __user *user, unsigned int len) | |||
1303 | goto free_newinfo; | 1305 | goto free_newinfo; |
1304 | } | 1306 | } |
1305 | 1307 | ||
1306 | ret = translate_table(tmp.name, tmp.valid_hooks, | 1308 | ret = translate_table(net, tmp.name, tmp.valid_hooks, |
1307 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, | 1309 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, |
1308 | tmp.hook_entry, tmp.underflow); | 1310 | tmp.hook_entry, tmp.underflow); |
1309 | if (ret != 0) | 1311 | if (ret != 0) |
@@ -1655,7 +1657,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, | |||
1655 | } | 1657 | } |
1656 | 1658 | ||
1657 | static int | 1659 | static int |
1658 | compat_check_entry(struct ipt_entry *e, const char *name, | 1660 | compat_check_entry(struct ipt_entry *e, struct net *net, const char *name, |
1659 | unsigned int *i) | 1661 | unsigned int *i) |
1660 | { | 1662 | { |
1661 | struct xt_mtchk_param mtpar; | 1663 | struct xt_mtchk_param mtpar; |
@@ -1663,6 +1665,7 @@ compat_check_entry(struct ipt_entry *e, const char *name, | |||
1663 | int ret; | 1665 | int ret; |
1664 | 1666 | ||
1665 | j = 0; | 1667 | j = 0; |
1668 | mtpar.net = net; | ||
1666 | mtpar.table = name; | 1669 | mtpar.table = name; |
1667 | mtpar.entryinfo = &e->ip; | 1670 | mtpar.entryinfo = &e->ip; |
1668 | mtpar.hook_mask = e->comefrom; | 1671 | mtpar.hook_mask = e->comefrom; |
@@ -1684,7 +1687,8 @@ compat_check_entry(struct ipt_entry *e, const char *name, | |||
1684 | } | 1687 | } |
1685 | 1688 | ||
1686 | static int | 1689 | static int |
1687 | translate_compat_table(const char *name, | 1690 | translate_compat_table(struct net *net, |
1691 | const char *name, | ||
1688 | unsigned int valid_hooks, | 1692 | unsigned int valid_hooks, |
1689 | struct xt_table_info **pinfo, | 1693 | struct xt_table_info **pinfo, |
1690 | void **pentry0, | 1694 | void **pentry0, |
@@ -1773,7 +1777,7 @@ translate_compat_table(const char *name, | |||
1773 | 1777 | ||
1774 | i = 0; | 1778 | i = 0; |
1775 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | 1779 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, |
1776 | name, &i); | 1780 | net, name, &i); |
1777 | if (ret) { | 1781 | if (ret) { |
1778 | j -= i; | 1782 | j -= i; |
1779 | COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, | 1783 | COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, |
@@ -1833,7 +1837,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) | |||
1833 | goto free_newinfo; | 1837 | goto free_newinfo; |
1834 | } | 1838 | } |
1835 | 1839 | ||
1836 | ret = translate_compat_table(tmp.name, tmp.valid_hooks, | 1840 | ret = translate_compat_table(net, tmp.name, tmp.valid_hooks, |
1837 | &newinfo, &loc_cpu_entry, tmp.size, | 1841 | &newinfo, &loc_cpu_entry, tmp.size, |
1838 | tmp.num_entries, tmp.hook_entry, | 1842 | tmp.num_entries, tmp.hook_entry, |
1839 | tmp.underflow); | 1843 | tmp.underflow); |
@@ -2086,7 +2090,7 @@ struct xt_table *ipt_register_table(struct net *net, | |||
2086 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | 2090 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; |
2087 | memcpy(loc_cpu_entry, repl->entries, repl->size); | 2091 | memcpy(loc_cpu_entry, repl->entries, repl->size); |
2088 | 2092 | ||
2089 | ret = translate_table(table->name, table->valid_hooks, | 2093 | ret = translate_table(net, table->name, table->valid_hooks, |
2090 | newinfo, loc_cpu_entry, repl->size, | 2094 | newinfo, loc_cpu_entry, repl->size, |
2091 | repl->num_entries, | 2095 | repl->num_entries, |
2092 | repl->hook_entry, | 2096 | repl->hook_entry, |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 480d7f8c9802..a825940a92ef 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -693,8 +693,8 @@ static int check_target(struct ip6t_entry *e, const char *name) | |||
693 | } | 693 | } |
694 | 694 | ||
695 | static int | 695 | static int |
696 | find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | 696 | find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, |
697 | unsigned int *i) | 697 | unsigned int size, unsigned int *i) |
698 | { | 698 | { |
699 | struct ip6t_entry_target *t; | 699 | struct ip6t_entry_target *t; |
700 | struct xt_target *target; | 700 | struct xt_target *target; |
@@ -707,6 +707,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
707 | return ret; | 707 | return ret; |
708 | 708 | ||
709 | j = 0; | 709 | j = 0; |
710 | mtpar.net = net; | ||
710 | mtpar.table = name; | 711 | mtpar.table = name; |
711 | mtpar.entryinfo = &e->ipv6; | 712 | mtpar.entryinfo = &e->ipv6; |
712 | mtpar.hook_mask = e->comefrom; | 713 | mtpar.hook_mask = e->comefrom; |
@@ -830,7 +831,8 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i) | |||
830 | /* Checks and translates the user-supplied table segment (held in | 831 | /* Checks and translates the user-supplied table segment (held in |
831 | newinfo) */ | 832 | newinfo) */ |
832 | static int | 833 | static int |
833 | translate_table(const char *name, | 834 | translate_table(struct net *net, |
835 | const char *name, | ||
834 | unsigned int valid_hooks, | 836 | unsigned int valid_hooks, |
835 | struct xt_table_info *newinfo, | 837 | struct xt_table_info *newinfo, |
836 | void *entry0, | 838 | void *entry0, |
@@ -892,7 +894,7 @@ translate_table(const char *name, | |||
892 | /* Finally, each sanity check must pass */ | 894 | /* Finally, each sanity check must pass */ |
893 | i = 0; | 895 | i = 0; |
894 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 896 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
895 | find_check_entry, name, size, &i); | 897 | find_check_entry, net, name, size, &i); |
896 | 898 | ||
897 | if (ret != 0) { | 899 | if (ret != 0) { |
898 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 900 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
@@ -1336,7 +1338,7 @@ do_replace(struct net *net, void __user *user, unsigned int len) | |||
1336 | goto free_newinfo; | 1338 | goto free_newinfo; |
1337 | } | 1339 | } |
1338 | 1340 | ||
1339 | ret = translate_table(tmp.name, tmp.valid_hooks, | 1341 | ret = translate_table(net, tmp.name, tmp.valid_hooks, |
1340 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, | 1342 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, |
1341 | tmp.hook_entry, tmp.underflow); | 1343 | tmp.hook_entry, tmp.underflow); |
1342 | if (ret != 0) | 1344 | if (ret != 0) |
@@ -2121,7 +2123,7 @@ struct xt_table *ip6t_register_table(struct net *net, | |||
2121 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | 2123 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; |
2122 | memcpy(loc_cpu_entry, repl->entries, repl->size); | 2124 | memcpy(loc_cpu_entry, repl->entries, repl->size); |
2123 | 2125 | ||
2124 | ret = translate_table(table->name, table->valid_hooks, | 2126 | ret = translate_table(net, table->name, table->valid_hooks, |
2125 | newinfo, loc_cpu_entry, repl->size, | 2127 | newinfo, loc_cpu_entry, repl->size, |
2126 | repl->num_entries, | 2128 | repl->num_entries, |
2127 | repl->hook_entry, | 2129 | repl->hook_entry, |