X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv6%2Fnetfilter%2Fip6_tables.c;h=0b4557e03431fa05fae2037d4d0248950bcd3a2d;hb=3859069bc3358772b08bd91efe9edec39a746ea8;hp=b89f133f41d054fdf88e5ac677b6b169bbc1cf37;hpb=44d34e721e2c81ccdfb13cf34996309247ae2981;p=linux-2.6 diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index b89f133f41..0b4557e034 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -55,7 +55,7 @@ MODULE_DESCRIPTION("IPv6 packet filter"); do { \ if (!(x)) \ printk("IP_NF_ASSERT: %s:%s:%u\n", \ - __FUNCTION__, __FILE__, __LINE__); \ + __func__, __FILE__, __LINE__); \ } while(0) #else #define IP_NF_ASSERT(x) @@ -325,7 +325,7 @@ static void trace_packet(struct sk_buff *skb, struct ip6t_entry *e) { void *table_base; - struct ip6t_entry *root; + const struct ip6t_entry *root; char *hookname, *chainname, *comment; unsigned int rulenum = 0; @@ -952,7 +952,7 @@ static struct xt_counters *alloc_counters(struct xt_table *table) { unsigned int countersize; struct xt_counters *counters; - struct xt_table_info *private = table->private; + const struct xt_table_info *private = table->private; /* We need atomic snapshot of counters: rest doesn't change (other than comefrom, which userspace doesn't care @@ -979,9 +979,9 @@ copy_entries_to_user(unsigned int total_size, unsigned int off, num; struct ip6t_entry *e; struct xt_counters *counters; - struct xt_table_info *private = table->private; + const struct xt_table_info *private = table->private; int ret = 0; - void *loc_cpu_entry; + const void *loc_cpu_entry; counters = alloc_counters(table); if (IS_ERR(counters)) @@ -1001,8 +1001,8 @@ copy_entries_to_user(unsigned int total_size, /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ unsigned int i; - struct ip6t_entry_match *m; - struct ip6t_entry_target *t; + const struct ip6t_entry_match *m; + const struct ip6t_entry_target *t; e = (struct ip6t_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -1118,7 +1118,7 @@ static int compat_table_info(const struct xt_table_info *info, } #endif -static int get_info(void __user *user, int *len, int compat) +static int get_info(struct net *net, void __user *user, int *len, int compat) { char name[IP6T_TABLE_MAXNAMELEN]; struct xt_table *t; @@ -1138,11 +1138,11 @@ static int get_info(void __user *user, int *len, int compat) if (compat) xt_compat_lock(AF_INET6); #endif - t = try_then_request_module(xt_find_table_lock(&init_net, AF_INET6, name), + t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name), "ip6table_%s", name); if (t && !IS_ERR(t)) { struct ip6t_getinfo info; - struct xt_table_info *private = t->private; + const struct xt_table_info *private = t->private; #ifdef CONFIG_COMPAT if (compat) { @@ -1178,7 +1178,7 @@ static int get_info(void __user *user, int *len, int compat) } static int -get_entries(struct ip6t_get_entries __user *uptr, int *len) +get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len) { int ret; struct ip6t_get_entries get; @@ -1196,7 +1196,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len) return -EINVAL; } - t = xt_find_table_lock(&init_net, AF_INET6, get.name); + t = xt_find_table_lock(net, AF_INET6, get.name); if (t && !IS_ERR(t)) { struct xt_table_info *private = t->private; duprintf("t->private->number = %u\n", private->number); @@ -1206,7 +1206,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len) else { duprintf("get_entries: I've got %u not %u!\n", private->size, get.size); - ret = -EINVAL; + ret = -EAGAIN; } module_put(t->me); xt_table_unlock(t); @@ -1217,7 +1217,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len) } static int -__do_replace(const char *name, unsigned int valid_hooks, +__do_replace(struct net *net, const char *name, unsigned int valid_hooks, struct xt_table_info *newinfo, unsigned int num_counters, void __user *counters_ptr) { @@ -1225,7 +1225,7 @@ __do_replace(const char *name, unsigned int valid_hooks, struct xt_table *t; struct xt_table_info *oldinfo; struct xt_counters *counters; - void *loc_cpu_old_entry; + const void *loc_cpu_old_entry; ret = 0; counters = vmalloc_node(num_counters * sizeof(struct xt_counters), @@ -1235,7 +1235,7 @@ __do_replace(const char *name, unsigned int valid_hooks, goto out; } - t = try_then_request_module(xt_find_table_lock(&init_net, AF_INET6, name), + t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name), "ip6table_%s", name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; @@ -1288,7 +1288,7 @@ __do_replace(const char *name, unsigned int valid_hooks, } static int -do_replace(void __user *user, unsigned int len) +do_replace(struct net *net, void __user *user, unsigned int len) { int ret; struct ip6t_replace tmp; @@ -1322,7 +1322,7 @@ do_replace(void __user *user, unsigned int len) duprintf("ip_tables: Translated table\n"); - ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo, + ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, tmp.num_counters, tmp.counters); if (ret) goto free_newinfo_untrans; @@ -1358,7 +1358,8 @@ add_counter_to_entry(struct ip6t_entry *e, } static int -do_add_counters(void __user *user, unsigned int len, int compat) +do_add_counters(struct net *net, void __user *user, unsigned int len, + int compat) { unsigned int i; struct xt_counters_info tmp; @@ -1368,9 +1369,9 @@ do_add_counters(void __user *user, unsigned int len, int compat) int size; void *ptmp; struct xt_table *t; - struct xt_table_info *private; + const struct xt_table_info *private; int ret = 0; - void *loc_cpu_entry; + const void *loc_cpu_entry; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1410,7 +1411,7 @@ do_add_counters(void __user *user, unsigned int len, int compat) goto free; } - t = xt_find_table_lock(&init_net, AF_INET6, name); + t = xt_find_table_lock(net, AF_INET6, name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; goto free; @@ -1456,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; @@ -1503,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; @@ -1561,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 @@ -1673,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, @@ -1815,7 +1818,7 @@ out_unlock: } static int -compat_do_replace(void __user *user, unsigned int len) +compat_do_replace(struct net *net, void __user *user, unsigned int len) { int ret; struct compat_ip6t_replace tmp; @@ -1852,7 +1855,7 @@ compat_do_replace(void __user *user, unsigned int len) duprintf("compat_do_replace: Translated table\n"); - ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo, + ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, tmp.num_counters, compat_ptr(tmp.counters)); if (ret) goto free_newinfo_untrans; @@ -1876,11 +1879,11 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, switch (cmd) { case IP6T_SO_SET_REPLACE: - ret = compat_do_replace(user, len); + ret = compat_do_replace(sock_net(sk), user, len); break; case IP6T_SO_SET_ADD_COUNTERS: - ret = do_add_counters(user, len, 1); + ret = do_add_counters(sock_net(sk), user, len, 1); break; default: @@ -1902,11 +1905,11 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, void __user *userptr) { struct xt_counters *counters; - struct xt_table_info *private = table->private; + const struct xt_table_info *private = table->private; void __user *pos; unsigned int size; int ret = 0; - void *loc_cpu_entry; + const void *loc_cpu_entry; unsigned int i = 0; counters = alloc_counters(table); @@ -1929,7 +1932,8 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, } static int -compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len) +compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, + int *len) { int ret; struct compat_ip6t_get_entries get; @@ -1950,9 +1954,9 @@ compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len) } xt_compat_lock(AF_INET6); - t = xt_find_table_lock(&init_net, AF_INET6, get.name); + t = xt_find_table_lock(net, AF_INET6, get.name); if (t && !IS_ERR(t)) { - struct xt_table_info *private = t->private; + const struct xt_table_info *private = t->private; struct xt_table_info info; duprintf("t->private->number = %u\n", private->number); ret = compat_table_info(private, &info); @@ -1962,7 +1966,7 @@ compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len) } else if (!ret) { duprintf("compat_get_entries: I've got %u not %u!\n", private->size, get.size); - ret = -EINVAL; + ret = -EAGAIN; } xt_compat_flush_offsets(AF_INET6); module_put(t->me); @@ -1986,10 +1990,10 @@ compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: - ret = get_info(user, len, 1); + ret = get_info(sock_net(sk), user, len, 1); break; case IP6T_SO_GET_ENTRIES: - ret = compat_get_entries(user, len); + ret = compat_get_entries(sock_net(sk), user, len); break; default: ret = do_ip6t_get_ctl(sk, cmd, user, len); @@ -2008,11 +2012,11 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) switch (cmd) { case IP6T_SO_SET_REPLACE: - ret = do_replace(user, len); + ret = do_replace(sock_net(sk), user, len); break; case IP6T_SO_SET_ADD_COUNTERS: - ret = do_add_counters(user, len, 0); + ret = do_add_counters(sock_net(sk), user, len, 0); break; default: @@ -2033,11 +2037,11 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: - ret = get_info(user, len, 0); + ret = get_info(sock_net(sk), user, len, 0); break; case IP6T_SO_GET_ENTRIES: - ret = get_entries(user, len); + ret = get_entries(sock_net(sk), user, len); break; case IP6T_SO_GET_REVISION_MATCH: @@ -2074,7 +2078,8 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) return ret; } -struct xt_table *ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl) +struct xt_table *ip6t_register_table(struct net *net, struct xt_table *table, + const struct ip6t_replace *repl) { int ret; struct xt_table_info *newinfo; @@ -2101,7 +2106,7 @@ struct xt_table *ip6t_register_table(struct xt_table *table, const struct ip6t_r if (ret != 0) goto out_free; - new_table = xt_register_table(&init_net, table, &bootstrap, newinfo); + new_table = xt_register_table(net, table, &bootstrap, newinfo); if (IS_ERR(new_table)) { ret = PTR_ERR(new_table); goto out_free; @@ -2118,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); } @@ -2147,7 +2155,8 @@ icmp6_match(const struct sk_buff *skb, unsigned int protoff, bool *hotdrop) { - struct icmp6hdr _icmph, *ic; + const struct icmp6hdr *ic; + struct icmp6hdr _icmph; const struct ip6t_icmp *icmpinfo = matchinfo; /* Must not be a fragment. */ @@ -2230,11 +2239,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; @@ -2264,7 +2288,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; } @@ -2276,7 +2300,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); } /*