[NETFILTER]: ip6_tables: move entry, match and target checks to seperate functions
authorPatrick McHardy <kaber@trash.net>
Tue, 18 Dec 2007 05:48:17 +0000 (21:48 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 22:58:32 +0000 (14:58 -0800)
Resync with ip_tables.c as preparation for compat support.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/netfilter/ip6_tables.c

index b73e6b6..655c221 100644 (file)
@@ -607,11 +607,55 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
 }
 
 static inline int
-check_match(struct ip6t_entry_match *m,
-           const char *name,
-           const struct ip6t_ip6 *ipv6,
-           unsigned int hookmask,
-           unsigned int *i)
+check_entry(struct ip6t_entry *e, const char *name)
+{
+       struct ip6t_entry_target *t;
+
+       if (!ip6_checkentry(&e->ipv6)) {
+               duprintf("ip_tables: ip check failed %p %s.\n", e, name);
+               return -EINVAL;
+       }
+
+       if (e->target_offset + sizeof(struct ip6t_entry_target) >
+           e->next_offset)
+               return -EINVAL;
+
+       t = ip6t_get_target(e);
+       if (e->target_offset + t->u.target_size > e->next_offset)
+               return -EINVAL;
+
+       return 0;
+}
+
+static inline int check_match(struct ip6t_entry_match *m, const char *name,
+                             const struct ip6t_ip6 *ipv6,
+                             unsigned int hookmask, unsigned int *i)
+{
+       struct xt_match *match;
+       int ret;
+
+       match = m->u.kernel.match;
+       ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
+                            name, hookmask, ipv6->proto,
+                            ipv6->invflags & IP6T_INV_PROTO);
+       if (!ret && m->u.kernel.match->checkentry
+           && !m->u.kernel.match->checkentry(name, ipv6, match, m->data,
+                                             hookmask)) {
+               duprintf("ip_tables: check failed for `%s'.\n",
+                        m->u.kernel.match->name);
+               ret = -EINVAL;
+       }
+       if (!ret)
+               (*i)++;
+       return ret;
+}
+
+static inline int
+find_check_match(struct ip6t_entry_match *m,
+                const char *name,
+                const struct ip6t_ip6 *ipv6,
+                unsigned int hookmask,
+                unsigned int *i)
 {
        struct xt_match *match;
        int ret;
@@ -620,86 +664,77 @@ check_match(struct ip6t_entry_match *m,
                                        m->u.user.revision),
                                        "ip6t_%s", m->u.user.name);
        if (IS_ERR(match) || !match) {
-               duprintf("check_match: `%s' not found\n", m->u.user.name);
+               duprintf("find_check_match: `%s' not found\n", m->u.user.name);
                return match ? PTR_ERR(match) : -ENOENT;
        }
        m->u.kernel.match = match;
 
-       ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
-                            name, hookmask, ipv6->proto,
-                            ipv6->invflags & IP6T_INV_PROTO);
+       ret = check_match(m, name, ipv6, hookmask, i);
        if (ret)
                goto err;
 
-       if (m->u.kernel.match->checkentry
-           && !m->u.kernel.match->checkentry(name, ipv6, match,  m->data,
-                                             hookmask)) {
-               duprintf("ip_tables: check failed for `%s'.\n",
-                        m->u.kernel.match->name);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       (*i)++;
        return 0;
 err:
        module_put(m->u.kernel.match->me);
        return ret;
 }
 
-static inline int
-check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
-           unsigned int *i)
+static inline int check_target(struct ip6t_entry *e, const char *name)
 {
        struct ip6t_entry_target *t;
        struct xt_target *target;
        int ret;
-       unsigned int j;
 
-       if (!ip6_checkentry(&e->ipv6)) {
-               duprintf("ip_tables: ip check failed %p %s.\n", e, name);
-               return -EINVAL;
+       t = ip6t_get_target(e);
+       target = t->u.kernel.target;
+       ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
+                             name, e->comefrom, e->ipv6.proto,
+                             e->ipv6.invflags & IP6T_INV_PROTO);
+       if (!ret && t->u.kernel.target->checkentry
+           && !t->u.kernel.target->checkentry(name, e, target, t->data,
+                                              e->comefrom)) {
+               duprintf("ip_tables: check failed for `%s'.\n",
+                        t->u.kernel.target->name);
+               ret = -EINVAL;
        }
+       return ret;
+}
 
-       if (e->target_offset + sizeof(struct ip6t_entry_target) >
-                                                               e->next_offset)
-               return -EINVAL;
+static inline int
+find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
+                unsigned int *i)
+{
+       struct ip6t_entry_target *t;
+       struct xt_target *target;
+       int ret;
+       unsigned int j;
+
+       ret = check_entry(e, name);
+       if (ret)
+               return ret;
 
        j = 0;
-       ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j);
+       ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6,
+                                e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ip6t_get_target(e);
-       ret = -EINVAL;
-       if (e->target_offset + t->u.target_size > e->next_offset)
-                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET6,
                                                        t->u.user.name,
                                                        t->u.user.revision),
                                         "ip6t_%s", t->u.user.name);
        if (IS_ERR(target) || !target) {
-               duprintf("check_entry: `%s' not found\n", t->u.user.name);
+               duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
                ret = target ? PTR_ERR(target) : -ENOENT;
                goto cleanup_matches;
        }
        t->u.kernel.target = target;
 
-       ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
-                             name, e->comefrom, e->ipv6.proto,
-                             e->ipv6.invflags & IP6T_INV_PROTO);
+       ret = check_target(e, name);
        if (ret)
                goto err;
 
-       if (t->u.kernel.target->checkentry
-                  && !t->u.kernel.target->checkentry(name, e, target, t->data,
-                                                     e->comefrom)) {
-               duprintf("ip_tables: check failed for `%s'.\n",
-                        t->u.kernel.target->name);
-               ret = -EINVAL;
-               goto err;
-       }
-
        (*i)++;
        return 0;
  err:
@@ -834,7 +869,7 @@ translate_table(const char *name,
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-                               check_entry, name, size, &i);
+                               find_check_entry, name, size, &i);
 
        if (ret != 0) {
                IP6T_ENTRY_ITERATE(entry0, newinfo->size,