[EBTABLES]: Pull the loop doing __ebt_verify_pointers() into a separate function.

It's easier to expand the iterator here *and* we'll be able to move all
uses of ebt_replace from translate_table() into this one.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index e79c0fb..2eba40f 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -393,48 +393,54 @@
 	return 0;
 }
 
-static inline int
-__ebt_verify_pointers(struct ebt_entry *e,
-   struct ebt_table_info *newinfo, char *base, char *limit,
-   struct ebt_entries **hook_entries,
-   unsigned int valid_hooks)
+static int ebt_verify_pointers(struct ebt_replace *repl,
+			       struct ebt_table_info *newinfo)
 {
-	unsigned int offset = (char *)e - newinfo->entries;
-	size_t left = (limit - base) - offset;
+	unsigned int limit = repl->entries_size;
+	unsigned int valid_hooks = repl->valid_hooks;
+	unsigned int offset = 0;
 	int i;
 
-	if (left < sizeof(unsigned int))
-		goto Esmall;
+	while (offset < limit) {
+		size_t left = limit - offset;
+		struct ebt_entry *e = (void *)newinfo->entries + offset;
 
-	for (i = 0; i < NF_BR_NUMHOOKS; i++) {
-		if ((valid_hooks & (1 << i)) == 0)
-			continue;
-		if ((char *)hook_entries[i] == base + offset)
+		if (left < sizeof(unsigned int))
 			break;
-	}
-	if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
-		if (e->bitmask != 0) {
-			/* we make userspace set this right,
-			   so there is no misunderstanding */
-			BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
-			         "in distinguisher\n");
-			return -EINVAL;
-		}
-		if (left < sizeof(struct ebt_entries))
-			goto Esmall;
-		if (i != NF_BR_NUMHOOKS)
-			newinfo->hook_entry[i] = (struct ebt_entries *)e;
-		return 0;
-	}
-	if (left < sizeof(struct ebt_entry))
-		goto Esmall;
-	if (left < e->next_offset)
-		goto Esmall;
-	return 0;
 
-Esmall:
-	BUGPRINT("entries_size too small\n");
-	return -EINVAL;
+		for (i = 0; i < NF_BR_NUMHOOKS; i++) {
+			if ((valid_hooks & (1 << i)) == 0)
+				continue;
+			if ((char *)repl->hook_entry[i] == repl->entries + offset)
+				break;
+		}
+
+		if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
+			if (e->bitmask != 0) {
+				/* we make userspace set this right,
+				   so there is no misunderstanding */
+				BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
+					 "in distinguisher\n");
+				return -EINVAL;
+			}
+			if (i != NF_BR_NUMHOOKS)
+				newinfo->hook_entry[i] = (struct ebt_entries *)e;
+			if (left < sizeof(struct ebt_entries))
+				break;
+			offset += sizeof(struct ebt_entries);
+		} else {
+			if (left < sizeof(struct ebt_entry))
+				break;
+			if (left < e->next_offset)
+				break;
+			offset += e->next_offset;
+		}
+	}
+	if (offset != limit) {
+		BUGPRINT("entries_size too small\n");
+		return -EINVAL;
+	}
+	return 0;
 }
 
 /*
@@ -795,9 +801,7 @@
 	newinfo->entries_size = repl->entries_size;
 	newinfo->nentries = repl->nentries;
 
-	ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
-	   __ebt_verify_pointers, newinfo, repl->entries,
-	   repl->entries + repl->entries_size, repl->hook_entry, repl->valid_hooks);
+	ret = ebt_verify_pointers(repl, newinfo);
 	if (ret != 0)
 		return ret;