Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: xtables: add struct xt_mtdtor_param::net

Add ->net to match destructor list like ->net in constructor list.

Make sure it's set in ebtables/iptables/ip6tables, this requires to
propagate netns up to *_unregister_table().

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>

authored by

Alexey Dobriyan and committed by
Patrick McHardy
f54e9367 a83d8e8d

+59 -53
+1
include/linux/netfilter/x_tables.h
··· 216 216 217 217 /* Match destructor parameters */ 218 218 struct xt_mtdtor_param { 219 + struct net *net; 219 220 const struct xt_match *match; 220 221 void *matchinfo; 221 222 u_int8_t family;
+1 -1
include/linux/netfilter_bridge/ebtables.h
··· 289 289 ~(__alignof__(struct ebt_replace)-1)) 290 290 extern struct ebt_table *ebt_register_table(struct net *net, 291 291 const struct ebt_table *table); 292 - extern void ebt_unregister_table(struct ebt_table *table); 292 + extern void ebt_unregister_table(struct net *net, struct ebt_table *table); 293 293 extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb, 294 294 const struct net_device *in, const struct net_device *out, 295 295 struct ebt_table *table);
+1 -1
include/linux/netfilter_ipv4/ip_tables.h
··· 242 242 extern struct xt_table *ipt_register_table(struct net *net, 243 243 const struct xt_table *table, 244 244 const struct ipt_replace *repl); 245 - extern void ipt_unregister_table(struct xt_table *table); 245 + extern void ipt_unregister_table(struct net *net, struct xt_table *table); 246 246 247 247 /* Standard entry. */ 248 248 struct ipt_standard {
+1 -1
include/linux/netfilter_ipv6/ip6_tables.h
··· 300 300 extern struct xt_table *ip6t_register_table(struct net *net, 301 301 const struct xt_table *table, 302 302 const struct ip6t_replace *repl); 303 - extern void ip6t_unregister_table(struct xt_table *table); 303 + extern void ip6t_unregister_table(struct net *net, struct xt_table *table); 304 304 extern unsigned int ip6t_do_table(struct sk_buff *skb, 305 305 unsigned int hook, 306 306 const struct net_device *in,
+1 -1
net/bridge/netfilter/ebtable_broute.c
··· 71 71 72 72 static void __net_exit broute_net_exit(struct net *net) 73 73 { 74 - ebt_unregister_table(net->xt.broute_table); 74 + ebt_unregister_table(net, net->xt.broute_table); 75 75 } 76 76 77 77 static struct pernet_operations broute_net_ops = {
+1 -1
net/bridge/netfilter/ebtable_filter.c
··· 107 107 108 108 static void __net_exit frame_filter_net_exit(struct net *net) 109 109 { 110 - ebt_unregister_table(net->xt.frame_filter); 110 + ebt_unregister_table(net, net->xt.frame_filter); 111 111 } 112 112 113 113 static struct pernet_operations frame_filter_net_ops = {
+1 -1
net/bridge/netfilter/ebtable_nat.c
··· 107 107 108 108 static void __net_exit frame_nat_net_exit(struct net *net) 109 109 { 110 - ebt_unregister_table(net->xt.frame_nat); 110 + ebt_unregister_table(net, net->xt.frame_nat); 111 111 } 112 112 113 113 static struct pernet_operations frame_nat_net_ops = {
+10 -9
net/bridge/netfilter/ebtables.c
··· 561 561 } 562 562 563 563 static inline int 564 - ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) 564 + ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i) 565 565 { 566 566 struct xt_mtdtor_param par; 567 567 568 568 if (i && (*i)-- == 0) 569 569 return 1; 570 570 571 + par.net = net; 571 572 par.match = m->u.match; 572 573 par.matchinfo = m->data; 573 574 par.family = NFPROTO_BRIDGE; ··· 596 595 } 597 596 598 597 static inline int 599 - ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) 598 + ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt) 600 599 { 601 600 struct xt_tgdtor_param par; 602 601 struct ebt_entry_target *t; ··· 607 606 if (cnt && (*cnt)-- == 0) 608 607 return 1; 609 608 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); 610 - EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); 609 + EBT_MATCH_ITERATE(e, ebt_cleanup_match, net, NULL); 611 610 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 612 611 613 612 par.target = t->u.target; ··· 732 731 cleanup_watchers: 733 732 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j); 734 733 cleanup_matches: 735 - EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i); 734 + EBT_MATCH_ITERATE(e, ebt_cleanup_match, net, &i); 736 735 return ret; 737 736 } 738 737 ··· 925 924 ebt_check_entry, net, newinfo, name, &i, cl_s, udc_cnt); 926 925 if (ret != 0) { 927 926 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 928 - ebt_cleanup_entry, &i); 927 + ebt_cleanup_entry, net, &i); 929 928 } 930 929 vfree(cl_s); 931 930 return ret; ··· 1075 1074 1076 1075 /* decrease module count and free resources */ 1077 1076 EBT_ENTRY_ITERATE(table->entries, table->entries_size, 1078 - ebt_cleanup_entry, NULL); 1077 + ebt_cleanup_entry, net, NULL); 1079 1078 1080 1079 vfree(table->entries); 1081 1080 if (table->chainstack) { ··· 1092 1091 mutex_unlock(&ebt_mutex); 1093 1092 free_iterate: 1094 1093 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 1095 - ebt_cleanup_entry, NULL); 1094 + ebt_cleanup_entry, net, NULL); 1096 1095 free_counterstmp: 1097 1096 vfree(counterstmp); 1098 1097 /* can be initialized in translate_table() */ ··· 1209 1208 return ERR_PTR(ret); 1210 1209 } 1211 1210 1212 - void ebt_unregister_table(struct ebt_table *table) 1211 + void ebt_unregister_table(struct net *net, struct ebt_table *table) 1213 1212 { 1214 1213 int i; 1215 1214 ··· 1221 1220 list_del(&table->list); 1222 1221 mutex_unlock(&ebt_mutex); 1223 1222 EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size, 1224 - ebt_cleanup_entry, NULL); 1223 + ebt_cleanup_entry, net, NULL); 1225 1224 if (table->private->nentries) 1226 1225 module_put(table->me); 1227 1226 vfree(table->private->entries);
+13 -12
net/ipv4/netfilter/ip_tables.c
··· 553 553 } 554 554 555 555 static int 556 - cleanup_match(struct ipt_entry_match *m, unsigned int *i) 556 + cleanup_match(struct ipt_entry_match *m, struct net *net, unsigned int *i) 557 557 { 558 558 struct xt_mtdtor_param par; 559 559 560 560 if (i && (*i)-- == 0) 561 561 return 1; 562 562 563 + par.net = net; 563 564 par.match = m->u.kernel.match; 564 565 par.matchinfo = m->data; 565 566 par.family = NFPROTO_IPV4; ··· 706 705 err: 707 706 module_put(t->u.kernel.target->me); 708 707 cleanup_matches: 709 - IPT_MATCH_ITERATE(e, cleanup_match, &j); 708 + IPT_MATCH_ITERATE(e, cleanup_match, net, &j); 710 709 return ret; 711 710 } 712 711 ··· 776 775 } 777 776 778 777 static int 779 - cleanup_entry(struct ipt_entry *e, unsigned int *i) 778 + cleanup_entry(struct ipt_entry *e, struct net *net, unsigned int *i) 780 779 { 781 780 struct xt_tgdtor_param par; 782 781 struct ipt_entry_target *t; ··· 785 784 return 1; 786 785 787 786 /* Cleanup all matches */ 788 - IPT_MATCH_ITERATE(e, cleanup_match, NULL); 787 + IPT_MATCH_ITERATE(e, cleanup_match, net, NULL); 789 788 t = ipt_get_target(e); 790 789 791 790 par.target = t->u.kernel.target; ··· 867 866 868 867 if (ret != 0) { 869 868 IPT_ENTRY_ITERATE(entry0, newinfo->size, 870 - cleanup_entry, &i); 869 + cleanup_entry, net, &i); 871 870 return ret; 872 871 } 873 872 ··· 1261 1260 /* Decrease module usage counts and free resource */ 1262 1261 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1263 1262 IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1264 - NULL); 1263 + net, NULL); 1265 1264 xt_free_table_info(oldinfo); 1266 1265 if (copy_to_user(counters_ptr, counters, 1267 1266 sizeof(struct xt_counters) * num_counters) != 0) ··· 1321 1320 return 0; 1322 1321 1323 1322 free_newinfo_untrans: 1324 - IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1323 + IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1325 1324 free_newinfo: 1326 1325 xt_free_table_info(newinfo); 1327 1326 return ret; ··· 1683 1682 return 0; 1684 1683 1685 1684 cleanup_matches: 1686 - IPT_MATCH_ITERATE(e, cleanup_match, &j); 1685 + IPT_MATCH_ITERATE(e, cleanup_match, net, &j); 1687 1686 return ret; 1688 1687 } 1689 1688 ··· 1783 1782 j -= i; 1784 1783 COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1785 1784 compat_release_entry, &j); 1786 - IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); 1785 + IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i); 1787 1786 xt_free_table_info(newinfo); 1788 1787 return ret; 1789 1788 } ··· 1854 1853 return 0; 1855 1854 1856 1855 free_newinfo_untrans: 1857 - IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1856 + IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1858 1857 free_newinfo: 1859 1858 xt_free_table_info(newinfo); 1860 1859 return ret; ··· 2113 2112 return ERR_PTR(ret); 2114 2113 } 2115 2114 2116 - void ipt_unregister_table(struct xt_table *table) 2115 + void ipt_unregister_table(struct net *net, struct xt_table *table) 2117 2116 { 2118 2117 struct xt_table_info *private; 2119 2118 void *loc_cpu_entry; ··· 2123 2122 2124 2123 /* Decrease module usage counts and free resources */ 2125 2124 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 2126 - IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 2125 + IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL); 2127 2126 if (private->number > private->initial_entries) 2128 2127 module_put(table_owner); 2129 2128 xt_free_table_info(private);
+1 -1
net/ipv4/netfilter/iptable_filter.c
··· 138 138 139 139 static void __net_exit iptable_filter_net_exit(struct net *net) 140 140 { 141 - ipt_unregister_table(net->ipv4.iptable_filter); 141 + ipt_unregister_table(net, net->ipv4.iptable_filter); 142 142 } 143 143 144 144 static struct pernet_operations iptable_filter_net_ops = {
+1 -1
net/ipv4/netfilter/iptable_mangle.c
··· 208 208 209 209 static void __net_exit iptable_mangle_net_exit(struct net *net) 210 210 { 211 - ipt_unregister_table(net->ipv4.iptable_mangle); 211 + ipt_unregister_table(net, net->ipv4.iptable_mangle); 212 212 } 213 213 214 214 static struct pernet_operations iptable_mangle_net_ops = {
+1 -1
net/ipv4/netfilter/iptable_raw.c
··· 100 100 101 101 static void __net_exit iptable_raw_net_exit(struct net *net) 102 102 { 103 - ipt_unregister_table(net->ipv4.iptable_raw); 103 + ipt_unregister_table(net, net->ipv4.iptable_raw); 104 104 } 105 105 106 106 static struct pernet_operations iptable_raw_net_ops = {
+1 -1
net/ipv4/netfilter/iptable_security.c
··· 138 138 139 139 static void __net_exit iptable_security_net_exit(struct net *net) 140 140 { 141 - ipt_unregister_table(net->ipv4.iptable_security); 141 + ipt_unregister_table(net, net->ipv4.iptable_security); 142 142 } 143 143 144 144 static struct pernet_operations iptable_security_net_ops = {
+1 -1
net/ipv4/netfilter/nf_nat_rule.c
··· 195 195 196 196 static void __net_exit nf_nat_rule_net_exit(struct net *net) 197 197 { 198 - ipt_unregister_table(net->ipv4.nat_table); 198 + ipt_unregister_table(net, net->ipv4.nat_table); 199 199 } 200 200 201 201 static struct pernet_operations nf_nat_rule_net_ops = {
+20 -17
net/ipv6/netfilter/ip6_tables.c
··· 585 585 } 586 586 587 587 static int 588 - cleanup_match(struct ip6t_entry_match *m, unsigned int *i) 588 + cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i) 589 589 { 590 590 struct xt_mtdtor_param par; 591 591 592 592 if (i && (*i)-- == 0) 593 593 return 1; 594 594 595 + par.net = net; 595 596 par.match = m->u.kernel.match; 596 597 par.matchinfo = m->data; 597 598 par.family = NFPROTO_IPV6; ··· 738 737 err: 739 738 module_put(t->u.kernel.target->me); 740 739 cleanup_matches: 741 - IP6T_MATCH_ITERATE(e, cleanup_match, &j); 740 + IP6T_MATCH_ITERATE(e, cleanup_match, net, &j); 742 741 return ret; 743 742 } 744 743 ··· 808 807 } 809 808 810 809 static int 811 - cleanup_entry(struct ip6t_entry *e, unsigned int *i) 810 + cleanup_entry(struct ip6t_entry *e, struct net *net, unsigned int *i) 812 811 { 813 812 struct xt_tgdtor_param par; 814 813 struct ip6t_entry_target *t; ··· 817 816 return 1; 818 817 819 818 /* Cleanup all matches */ 820 - IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 819 + IP6T_MATCH_ITERATE(e, cleanup_match, net, NULL); 821 820 t = ip6t_get_target(e); 822 821 823 822 par.target = t->u.kernel.target; ··· 899 898 900 899 if (ret != 0) { 901 900 IP6T_ENTRY_ITERATE(entry0, newinfo->size, 902 - cleanup_entry, &i); 901 + cleanup_entry, net, &i); 903 902 return ret; 904 903 } 905 904 ··· 1294 1293 /* Decrease module usage counts and free resource */ 1295 1294 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1296 1295 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1297 - NULL); 1296 + net, NULL); 1298 1297 xt_free_table_info(oldinfo); 1299 1298 if (copy_to_user(counters_ptr, counters, 1300 1299 sizeof(struct xt_counters) * num_counters) != 0) ··· 1354 1353 return 0; 1355 1354 1356 1355 free_newinfo_untrans: 1357 - IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1356 + IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1358 1357 free_newinfo: 1359 1358 xt_free_table_info(newinfo); 1360 1359 return ret; ··· 1693 1692 return ret; 1694 1693 } 1695 1694 1696 - static int compat_check_entry(struct ip6t_entry *e, const char *name, 1697 - unsigned int *i) 1695 + static int compat_check_entry(struct ip6t_entry *e, struct net *net, 1696 + const char *name, unsigned int *i) 1698 1697 { 1699 1698 unsigned int j; 1700 1699 int ret; 1701 1700 struct xt_mtchk_param mtpar; 1702 1701 1703 1702 j = 0; 1703 + mtpar.net = net; 1704 1704 mtpar.table = name; 1705 1705 mtpar.entryinfo = &e->ipv6; 1706 1706 mtpar.hook_mask = e->comefrom; ··· 1718 1716 return 0; 1719 1717 1720 1718 cleanup_matches: 1721 - IP6T_MATCH_ITERATE(e, cleanup_match, &j); 1719 + IP6T_MATCH_ITERATE(e, cleanup_match, net, &j); 1722 1720 return ret; 1723 1721 } 1724 1722 1725 1723 static int 1726 - translate_compat_table(const char *name, 1724 + translate_compat_table(struct net *net, 1725 + const char *name, 1727 1726 unsigned int valid_hooks, 1728 1727 struct xt_table_info **pinfo, 1729 1728 void **pentry0, ··· 1813 1810 1814 1811 i = 0; 1815 1812 ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1816 - name, &i); 1813 + net, name, &i); 1817 1814 if (ret) { 1818 1815 j -= i; 1819 1816 COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1820 1817 compat_release_entry, &j); 1821 - IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); 1818 + IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i); 1822 1819 xt_free_table_info(newinfo); 1823 1820 return ret; 1824 1821 } ··· 1873 1870 goto free_newinfo; 1874 1871 } 1875 1872 1876 - ret = translate_compat_table(tmp.name, tmp.valid_hooks, 1873 + ret = translate_compat_table(net, tmp.name, tmp.valid_hooks, 1877 1874 &newinfo, &loc_cpu_entry, tmp.size, 1878 1875 tmp.num_entries, tmp.hook_entry, 1879 1876 tmp.underflow); ··· 1889 1886 return 0; 1890 1887 1891 1888 free_newinfo_untrans: 1892 - IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1889 + IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1893 1890 free_newinfo: 1894 1891 xt_free_table_info(newinfo); 1895 1892 return ret; ··· 2147 2144 return ERR_PTR(ret); 2148 2145 } 2149 2146 2150 - void ip6t_unregister_table(struct xt_table *table) 2147 + void ip6t_unregister_table(struct net *net, struct xt_table *table) 2151 2148 { 2152 2149 struct xt_table_info *private; 2153 2150 void *loc_cpu_entry; ··· 2157 2154 2158 2155 /* Decrease module usage counts and free resources */ 2159 2156 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 2160 - IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 2157 + IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL); 2161 2158 if (private->number > private->initial_entries) 2162 2159 module_put(table_owner); 2163 2160 xt_free_table_info(private);
+1 -1
net/ipv6/netfilter/ip6table_filter.c
··· 131 131 132 132 static void __net_exit ip6table_filter_net_exit(struct net *net) 133 133 { 134 - ip6t_unregister_table(net->ipv6.ip6table_filter); 134 + ip6t_unregister_table(net, net->ipv6.ip6table_filter); 135 135 } 136 136 137 137 static struct pernet_operations ip6table_filter_net_ops = {
+1 -1
net/ipv6/netfilter/ip6table_mangle.c
··· 182 182 183 183 static void __net_exit ip6table_mangle_net_exit(struct net *net) 184 184 { 185 - ip6t_unregister_table(net->ipv6.ip6table_mangle); 185 + ip6t_unregister_table(net, net->ipv6.ip6table_mangle); 186 186 } 187 187 188 188 static struct pernet_operations ip6table_mangle_net_ops = {
+1 -1
net/ipv6/netfilter/ip6table_raw.c
··· 94 94 95 95 static void __net_exit ip6table_raw_net_exit(struct net *net) 96 96 { 97 - ip6t_unregister_table(net->ipv6.ip6table_raw); 97 + ip6t_unregister_table(net, net->ipv6.ip6table_raw); 98 98 } 99 99 100 100 static struct pernet_operations ip6table_raw_net_ops = {
+1 -1
net/ipv6/netfilter/ip6table_security.c
··· 134 134 135 135 static void __net_exit ip6table_security_net_exit(struct net *net) 136 136 { 137 - ip6t_unregister_table(net->ipv6.ip6table_security); 137 + ip6t_unregister_table(net, net->ipv6.ip6table_security); 138 138 } 139 139 140 140 static struct pernet_operations ip6table_security_net_ops = {