]> err.no Git - linux-2.6/blobdiff - net/bridge/netfilter/ebtables.c
[EBTABLES]: translate_table(): switch direct uses of repl->hook_info to newinfo
[linux-2.6] / net / bridge / netfilter / ebtables.c
index 2eba40f54233a5917b2120778a85c1a1d76664ed..3e1bf716509a99117400dc3ad25758acf9eff9d3 100644 (file)
@@ -401,6 +401,12 @@ static int ebt_verify_pointers(struct ebt_replace *repl,
        unsigned int offset = 0;
        int i;
 
+       for (i = 0; i < NF_BR_NUMHOOKS; i++)
+               newinfo->hook_entry[i] = NULL;
+
+       newinfo->entries_size = repl->entries_size;
+       newinfo->nentries = repl->nentries;
+
        while (offset < limit) {
                size_t left = limit - offset;
                struct ebt_entry *e = (void *)newinfo->entries + offset;
@@ -440,6 +446,15 @@ static int ebt_verify_pointers(struct ebt_replace *repl,
                BUGPRINT("entries_size too small\n");
                return -EINVAL;
        }
+
+       /* check if all valid hooks have a chain */
+       for (i = 0; i < NF_BR_NUMHOOKS; i++) {
+               if (!newinfo->hook_entry[i] &&
+                  (valid_hooks & (1 << i))) {
+                       BUGPRINT("Valid hook without chain\n");
+                       return -EINVAL;
+               }
+       }
        return 0;
 }
 
@@ -772,39 +787,33 @@ static int translate_table(struct ebt_replace *repl,
        int ret;
        struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
 
+       ret = ebt_verify_pointers(repl, newinfo);
+       if (ret != 0)
+               return ret;
+
        i = 0;
-       while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i)))
+       while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i])
                i++;
        if (i == NF_BR_NUMHOOKS) {
                BUGPRINT("No valid hooks specified\n");
                return -EINVAL;
        }
-       if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) {
+       if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) {
                BUGPRINT("Chains don't start at beginning\n");
                return -EINVAL;
        }
        /* make sure chains are ordered after each other in same order
           as their corresponding hooks */
        for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
-               if (!(repl->valid_hooks & (1 << j)))
+               if (!newinfo->hook_entry[j])
                        continue;
-               if ( repl->hook_entry[j] <= repl->hook_entry[i] ) {
+               if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) {
                        BUGPRINT("Hook order must be followed\n");
                        return -EINVAL;
                }
                i = j;
        }
 
-       for (i = 0; i < NF_BR_NUMHOOKS; i++)
-               newinfo->hook_entry[i] = NULL;
-
-       newinfo->entries_size = repl->entries_size;
-       newinfo->nentries = repl->nentries;
-
-       ret = ebt_verify_pointers(repl, newinfo);
-       if (ret != 0)
-               return ret;
-
        /* do some early checkings and initialize some things */
        i = 0; /* holds the expected nr. of entries for the chain */
        j = 0; /* holds the up to now counted entries for the chain */
@@ -829,15 +838,6 @@ static int translate_table(struct ebt_replace *repl,
                return -EINVAL;
        }
 
-       /* check if all valid hooks have a chain */
-       for (i = 0; i < NF_BR_NUMHOOKS; i++) {
-               if (newinfo->hook_entry[i] == NULL &&
-                  (repl->valid_hooks & (1 << i))) {
-                       BUGPRINT("Valid hook without chain\n");
-                       return -EINVAL;
-               }
-       }
-
        /* get the location of the udc, put them in an array
           while we're at it, allocate the chainstack */
        if (udc_cnt) {
@@ -877,7 +877,7 @@ static int translate_table(struct ebt_replace *repl,
 
        /* Check for loops */
        for (i = 0; i < NF_BR_NUMHOOKS; i++)
-               if (repl->valid_hooks & (1 << i))
+               if (newinfo->hook_entry[i])
                        if (check_chainloops(newinfo->hook_entry[i],
                           cl_s, udc_cnt, i, newinfo->entries)) {
                                vfree(cl_s);