Merge branch 'master' of /repos/git/net-next-2.6
[safe/jmp/linux-2.6] / net / ipv6 / netfilter / ip6_tables.c
index cc9f8ef..4332f45 100644 (file)
@@ -105,9 +105,9 @@ ip6_packet_match(const struct sk_buff *skb,
 #define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg)))
 
        if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk,
-                                      &ip6info->src), IP6T_INV_SRCIP)
-           || FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk,
-                                         &ip6info->dst), IP6T_INV_DSTIP)) {
+                                      &ip6info->src), IP6T_INV_SRCIP) ||
+           FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk,
+                                      &ip6info->dst), IP6T_INV_DSTIP)) {
                dprintf("Source or dest mismatch.\n");
 /*
                dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
@@ -277,11 +277,11 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
        } else if (s == e) {
                (*rulenum)++;
 
-               if (s->target_offset == sizeof(struct ip6t_entry)
-                  && strcmp(t->target.u.kernel.target->name,
-                            IP6T_STANDARD_TARGET) == 0
-                  && t->verdict < 0
-                  && unconditional(&s->ipv6)) {
+               if (s->target_offset == sizeof(struct ip6t_entry) &&
+                   strcmp(t->target.u.kernel.target->name,
+                          IP6T_STANDARD_TARGET) == 0 &&
+                   t->verdict < 0 &&
+                   unconditional(&s->ipv6)) {
                        /* Tail of chains: STANDARD target (return/policy) */
                        *comment = *chainname == hookname
                                ? comments[NF_IP6_TRACE_COMMENT_POLICY]
@@ -418,8 +418,8 @@ ip6t_do_table(struct sk_buff *skb,
                                back = get_entry(table_base, back->comefrom);
                                continue;
                        }
-                       if (table_base + v != ip6t_next_entry(e)
-                           && !(e->ipv6.flags & IP6T_F_GOTO)) {
+                       if (table_base + v != ip6t_next_entry(e) &&
+                           !(e->ipv6.flags & IP6T_F_GOTO)) {
                                /* Save old back ptr in next entry */
                                struct ip6t_entry *next = ip6t_next_entry(e);
                                next->comefrom = (void *)back - table_base;
@@ -505,11 +505,11 @@ mark_source_chains(struct xt_table_info *newinfo,
                        e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
                        /* Unconditional return/END. */
-                       if ((e->target_offset == sizeof(struct ip6t_entry)
-                           && (strcmp(t->target.u.user.name,
-                                      IP6T_STANDARD_TARGET) == 0)
-                           && t->verdict < 0
-                           && unconditional(&e->ipv6)) || visited) {
+                       if ((e->target_offset == sizeof(struct ip6t_entry) &&
+                            (strcmp(t->target.u.user.name,
+                                    IP6T_STANDARD_TARGET) == 0) &&
+                            t->verdict < 0 &&
+                            unconditional(&e->ipv6)) || visited) {
                                unsigned int oldpos, size;
 
                                if ((strcmp(t->target.u.user.name,
@@ -556,8 +556,8 @@ mark_source_chains(struct xt_table_info *newinfo,
                                int newpos = t->verdict;
 
                                if (strcmp(t->target.u.user.name,
-                                          IP6T_STANDARD_TARGET) == 0
-                                   && newpos >= 0) {
+                                          IP6T_STANDARD_TARGET) == 0 &&
+                                   newpos >= 0) {
                                        if (newpos > newinfo->size -
                                                sizeof(struct ip6t_entry)) {
                                                duprintf("mark_source_chains: "
@@ -585,13 +585,14 @@ mark_source_chains(struct xt_table_info *newinfo,
 }
 
 static int
-cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
+cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i)
 {
        struct xt_mtdtor_param par;
 
        if (i && (*i)-- == 0)
                return 1;
 
+       par.net       = net;
        par.match     = m->u.kernel.match;
        par.matchinfo = m->data;
        par.family    = NFPROTO_IPV6;
@@ -668,10 +669,11 @@ err:
        return ret;
 }
 
-static int check_target(struct ip6t_entry *e, const char *name)
+static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
 {
        struct ip6t_entry_target *t = ip6t_get_target(e);
        struct xt_tgchk_param par = {
+               .net       = net,
                .table     = name,
                .entryinfo = e,
                .target    = t->u.kernel.target,
@@ -693,8 +695,8 @@ static int check_target(struct ip6t_entry *e, const char *name)
 }
 
 static int
-find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
-                unsigned int *i)
+find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
+                unsigned int size, unsigned int *i)
 {
        struct ip6t_entry_target *t;
        struct xt_target *target;
@@ -707,6 +709,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
                return ret;
 
        j = 0;
+       mtpar.net       = net;
        mtpar.table     = name;
        mtpar.entryinfo = &e->ipv6;
        mtpar.hook_mask = e->comefrom;
@@ -727,7 +730,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
        }
        t->u.kernel.target = target;
 
-       ret = check_target(e, name);
+       ret = check_target(e, net, name);
        if (ret)
                goto err;
 
@@ -736,7 +739,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
  err:
        module_put(t->u.kernel.target->me);
  cleanup_matches:
-       IP6T_MATCH_ITERATE(e, cleanup_match, &j);
+       IP6T_MATCH_ITERATE(e, cleanup_match, net, &j);
        return ret;
 }
 
@@ -767,8 +770,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 {
        unsigned int h;
 
-       if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0
-           || (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
+       if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
+           (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
                duprintf("Bad offset %p\n", e);
                return -EINVAL;
        }
@@ -806,7 +809,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 }
 
 static int
-cleanup_entry(struct ip6t_entry *e, unsigned int *i)
+cleanup_entry(struct ip6t_entry *e, struct net *net, unsigned int *i)
 {
        struct xt_tgdtor_param par;
        struct ip6t_entry_target *t;
@@ -815,9 +818,10 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
                return 1;
 
        /* Cleanup all matches */
-       IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
+       IP6T_MATCH_ITERATE(e, cleanup_match, net, NULL);
        t = ip6t_get_target(e);
 
+       par.net      = net;
        par.target   = t->u.kernel.target;
        par.targinfo = t->data;
        par.family   = NFPROTO_IPV6;
@@ -830,7 +834,8 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
 /* Checks and translates the user-supplied table segment (held in
    newinfo) */
 static int
-translate_table(const char *name,
+translate_table(struct net *net,
+               const char *name,
                unsigned int valid_hooks,
                struct xt_table_info *newinfo,
                void *entry0,
@@ -892,11 +897,11 @@ translate_table(const char *name,
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-                               find_check_entry, name, size, &i);
+                               find_check_entry, net, name, size, &i);
 
        if (ret != 0) {
                IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-                                  cleanup_entry, &i);
+                                  cleanup_entry, net, &i);
                return ret;
        }
 
@@ -1164,10 +1169,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
        if (t && !IS_ERR(t)) {
                struct ip6t_getinfo info;
                const struct xt_table_info *private = t->private;
-
 #ifdef CONFIG_COMPAT
+               struct xt_table_info tmp;
+
                if (compat) {
-                       struct xt_table_info tmp;
                        ret = compat_table_info(private, &tmp);
                        xt_compat_flush_offsets(AF_INET6);
                        private = &tmp;
@@ -1291,7 +1296,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
        /* Decrease module usage counts and free resource */
        loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
        IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,
-                          NULL);
+                          net, NULL);
        xt_free_table_info(oldinfo);
        if (copy_to_user(counters_ptr, counters,
                         sizeof(struct xt_counters) * num_counters) != 0)
@@ -1336,7 +1341,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
                goto free_newinfo;
        }
 
-       ret = translate_table(tmp.name, tmp.valid_hooks,
+       ret = translate_table(net, tmp.name, tmp.valid_hooks,
                              newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
                              tmp.hook_entry, tmp.underflow);
        if (ret != 0)
@@ -1351,7 +1356,7 @@ do_replace(struct net *net, void __user *user, unsigned int len)
        return 0;
 
  free_newinfo_untrans:
-       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL);
  free_newinfo:
        xt_free_table_info(newinfo);
        return ret;
@@ -1584,8 +1589,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
        int ret, off, h;
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
-       if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0
-           || (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) {
+       if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
+           (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) {
                duprintf("Bad offset %p, limit = %p\n", e, limit);
                return -EINVAL;
        }
@@ -1690,14 +1695,15 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
        return ret;
 }
 
-static int compat_check_entry(struct ip6t_entry *e, const char *name,
-                                    unsigned int *i)
+static int compat_check_entry(struct ip6t_entry *e, struct net *net,
+                             const char *name, unsigned int *i)
 {
        unsigned int j;
        int ret;
        struct xt_mtchk_param mtpar;
 
        j = 0;
+       mtpar.net       = net;
        mtpar.table     = name;
        mtpar.entryinfo = &e->ipv6;
        mtpar.hook_mask = e->comefrom;
@@ -1706,7 +1712,7 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
        if (ret)
                goto cleanup_matches;
 
-       ret = check_target(e, name);
+       ret = check_target(e, net, name);
        if (ret)
                goto cleanup_matches;
 
@@ -1714,12 +1720,13 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
        return 0;
 
  cleanup_matches:
-       IP6T_MATCH_ITERATE(e, cleanup_match, &j);
+       IP6T_MATCH_ITERATE(e, cleanup_match, net, &j);
        return ret;
 }
 
 static int
-translate_compat_table(const char *name,
+translate_compat_table(struct net *net,
+                      const char *name,
                       unsigned int valid_hooks,
                       struct xt_table_info **pinfo,
                       void **pentry0,
@@ -1808,12 +1815,12 @@ translate_compat_table(const char *name,
 
        i = 0;
        ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
-                                name, &i);
+                                net, name, &i);
        if (ret) {
                j -= i;
                COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
                                                   compat_release_entry, &j);
-               IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
+               IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i);
                xt_free_table_info(newinfo);
                return ret;
        }
@@ -1868,7 +1875,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
                goto free_newinfo;
        }
 
-       ret = translate_compat_table(tmp.name, tmp.valid_hooks,
+       ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
                                     &newinfo, &loc_cpu_entry, tmp.size,
                                     tmp.num_entries, tmp.hook_entry,
                                     tmp.underflow);
@@ -1884,7 +1891,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
        return 0;
 
  free_newinfo_untrans:
-       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL);
  free_newinfo:
        xt_free_table_info(newinfo);
        return ret;
@@ -2121,7 +2128,7 @@ struct xt_table *ip6t_register_table(struct net *net,
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
        memcpy(loc_cpu_entry, repl->entries, repl->size);
 
-       ret = translate_table(table->name, table->valid_hooks,
+       ret = translate_table(net, table->name, table->valid_hooks,
                              newinfo, loc_cpu_entry, repl->size,
                              repl->num_entries,
                              repl->hook_entry,
@@ -2142,7 +2149,7 @@ out:
        return ERR_PTR(ret);
 }
 
-void ip6t_unregister_table(struct xt_table *table)
+void ip6t_unregister_table(struct net *net, struct xt_table *table)
 {
        struct xt_table_info *private;
        void *loc_cpu_entry;
@@ -2152,7 +2159,7 @@ void ip6t_unregister_table(struct xt_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);
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL);
        if (private->number > private->initial_entries)
                module_put(table_owner);
        xt_free_table_info(private);