[NETFILTER]: x_tables: create per-netns /proc/net/*_tables_*
[powerpc.git] / net / ipv6 / netfilter / ip6_tables.c
index 2453dfd..bf9bb6e 100644 (file)
@@ -1457,7 +1457,7 @@ struct compat_ip6t_replace {
 
 static int
 compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
-                         compat_uint_t *size, struct xt_counters *counters,
+                         unsigned int *size, struct xt_counters *counters,
                          unsigned int *i)
 {
        struct ip6t_entry_target *t;
@@ -1504,7 +1504,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
                       const char *name,
                       const struct ip6t_ip6 *ipv6,
                       unsigned int hookmask,
-                      int *size, int *i)
+                      int *size, unsigned int *i)
 {
        struct xt_match *match;
 
@@ -1562,7 +1562,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
        struct ip6t_entry_target *t;
        struct xt_target *target;
        unsigned int entry_offset;
-       int ret, off, h, j;
+       unsigned int j;
+       int ret, off, h;
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
        if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0
@@ -1674,7 +1675,8 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 static int compat_check_entry(struct ip6t_entry *e, const char *name,
                                     unsigned int *i)
 {
-       int j, ret;
+       unsigned int j;
+       int ret;
 
        j = 0;
        ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6,
@@ -2121,12 +2123,15 @@ void ip6t_unregister_table(struct xt_table *table)
 {
        struct xt_table_info *private;
        void *loc_cpu_entry;
+       struct module *table_owner = table->me;
 
        private = xt_unregister_table(table);
 
        /* Decrease module usage counts and free resources */
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
        IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
+       if (private->number > private->initial_entries)
+               module_put(table_owner);
        xt_free_table_info(private);
 }
 
@@ -2233,11 +2238,26 @@ static struct xt_match icmp6_matchstruct __read_mostly = {
        .family         = AF_INET6,
 };
 
+static int __net_init ip6_tables_net_init(struct net *net)
+{
+       return xt_proto_init(net, AF_INET6);
+}
+
+static void __net_exit ip6_tables_net_exit(struct net *net)
+{
+       xt_proto_fini(net, AF_INET6);
+}
+
+static struct pernet_operations ip6_tables_net_ops = {
+       .init = ip6_tables_net_init,
+       .exit = ip6_tables_net_exit,
+};
+
 static int __init ip6_tables_init(void)
 {
        int ret;
 
-       ret = xt_proto_init(AF_INET6);
+       ret = register_pernet_subsys(&ip6_tables_net_ops);
        if (ret < 0)
                goto err1;
 
@@ -2267,7 +2287,7 @@ err4:
 err3:
        xt_unregister_target(&ip6t_standard_target);
 err2:
-       xt_proto_fini(AF_INET6);
+       unregister_pernet_subsys(&ip6_tables_net_ops);
 err1:
        return ret;
 }
@@ -2279,7 +2299,8 @@ static void __exit ip6_tables_fini(void)
        xt_unregister_match(&icmp6_matchstruct);
        xt_unregister_target(&ip6t_error_target);
        xt_unregister_target(&ip6t_standard_target);
-       xt_proto_fini(AF_INET6);
+
+       unregister_pernet_subsys(&ip6_tables_net_ops);
 }
 
 /*