Commit 0f234214 authored by Jan Engelhardt's avatar Jan Engelhardt Committed by Patrick McHardy

netfilter: xtables: reduce arguments to translate_table

Just pass in the entire repl struct. In case of a new table (e.g.
ip6t_register_table), the repldata has been previously filled with
table->name and table->size already (in ip6t_alloc_initial_table).
Signed-off-by: default avatarJan Engelhardt <jengelh@medozas.de>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 6bdb331b
...@@ -622,21 +622,15 @@ static inline void cleanup_entry(struct arpt_entry *e) ...@@ -622,21 +622,15 @@ static inline void cleanup_entry(struct arpt_entry *e)
/* Checks and translates the user-supplied table segment (held in /* Checks and translates the user-supplied table segment (held in
* newinfo). * newinfo).
*/ */
static int translate_table(const char *name, static int translate_table(struct xt_table_info *newinfo, void *entry0,
unsigned int valid_hooks, const struct arpt_replace *repl)
struct xt_table_info *newinfo,
void *entry0,
unsigned int size,
unsigned int number,
const unsigned int *hook_entries,
const unsigned int *underflows)
{ {
struct arpt_entry *iter; struct arpt_entry *iter;
unsigned int i; unsigned int i;
int ret = 0; int ret = 0;
newinfo->size = size; newinfo->size = repl->size;
newinfo->number = number; newinfo->number = repl->num_entries;
/* Init all hooks to impossible value. */ /* Init all hooks to impossible value. */
for (i = 0; i < NF_ARP_NUMHOOKS; i++) { for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
...@@ -650,7 +644,8 @@ static int translate_table(const char *name, ...@@ -650,7 +644,8 @@ static int translate_table(const char *name,
/* Walk through entries, checking offsets. */ /* Walk through entries, checking offsets. */
xt_entry_foreach(iter, entry0, newinfo->size) { xt_entry_foreach(iter, entry0, newinfo->size) {
ret = check_entry_size_and_hooks(iter, newinfo, entry0, ret = check_entry_size_and_hooks(iter, newinfo, entry0,
entry0 + size, hook_entries, underflows, valid_hooks); entry0 + repl->size, repl->hook_entry, repl->underflow,
repl->valid_hooks);
if (ret != 0) if (ret != 0)
break; break;
++i; ++i;
...@@ -659,30 +654,30 @@ static int translate_table(const char *name, ...@@ -659,30 +654,30 @@ static int translate_table(const char *name,
if (ret != 0) if (ret != 0)
return ret; return ret;
if (i != number) { if (i != repl->num_entries) {
duprintf("translate_table: %u not %u entries\n", duprintf("translate_table: %u not %u entries\n",
i, number); i, repl->num_entries);
return -EINVAL; return -EINVAL;
} }
/* Check hooks all assigned */ /* Check hooks all assigned */
for (i = 0; i < NF_ARP_NUMHOOKS; i++) { for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
/* Only hooks which are valid */ /* Only hooks which are valid */
if (!(valid_hooks & (1 << i))) if (!(repl->valid_hooks & (1 << i)))
continue; continue;
if (newinfo->hook_entry[i] == 0xFFFFFFFF) { if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
duprintf("Invalid hook entry %u %u\n", duprintf("Invalid hook entry %u %u\n",
i, hook_entries[i]); i, repl->hook_entry[i]);
return -EINVAL; return -EINVAL;
} }
if (newinfo->underflow[i] == 0xFFFFFFFF) { if (newinfo->underflow[i] == 0xFFFFFFFF) {
duprintf("Invalid underflow %u %u\n", duprintf("Invalid underflow %u %u\n",
i, underflows[i]); i, repl->underflow[i]);
return -EINVAL; return -EINVAL;
} }
} }
if (!mark_source_chains(newinfo, valid_hooks, entry0)) { if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) {
duprintf("Looping hook\n"); duprintf("Looping hook\n");
return -ELOOP; return -ELOOP;
} }
...@@ -690,7 +685,7 @@ static int translate_table(const char *name, ...@@ -690,7 +685,7 @@ static int translate_table(const char *name,
/* Finally, each sanity check must pass */ /* Finally, each sanity check must pass */
i = 0; i = 0;
xt_entry_foreach(iter, entry0, newinfo->size) { xt_entry_foreach(iter, entry0, newinfo->size) {
ret = find_check_entry(iter, name, size); ret = find_check_entry(iter, repl->name, repl->size);
if (ret != 0) if (ret != 0)
break; break;
++i; ++i;
...@@ -1101,9 +1096,7 @@ static int do_replace(struct net *net, const void __user *user, ...@@ -1101,9 +1096,7 @@ static int do_replace(struct net *net, const void __user *user,
goto free_newinfo; goto free_newinfo;
} }
ret = translate_table(tmp.name, tmp.valid_hooks, ret = translate_table(newinfo, loc_cpu_entry, &tmp);
newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
tmp.hook_entry, tmp.underflow);
if (ret != 0) if (ret != 0)
goto free_newinfo; goto free_newinfo;
...@@ -1795,12 +1788,7 @@ struct xt_table *arpt_register_table(struct net *net, ...@@ -1795,12 +1788,7 @@ struct xt_table *arpt_register_table(struct net *net,
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
memcpy(loc_cpu_entry, repl->entries, repl->size); memcpy(loc_cpu_entry, repl->entries, repl->size);
ret = translate_table(table->name, table->valid_hooks, ret = translate_table(newinfo, loc_cpu_entry, repl);
newinfo, loc_cpu_entry, repl->size,
repl->num_entries,
repl->hook_entry,
repl->underflow);
duprintf("arpt_register_table: translate table gives %d\n", ret); duprintf("arpt_register_table: translate table gives %d\n", ret);
if (ret != 0) if (ret != 0)
goto out_free; goto out_free;
......
...@@ -815,22 +815,15 @@ cleanup_entry(struct ipt_entry *e, struct net *net) ...@@ -815,22 +815,15 @@ cleanup_entry(struct ipt_entry *e, struct net *net)
/* Checks and translates the user-supplied table segment (held in /* Checks and translates the user-supplied table segment (held in
newinfo) */ newinfo) */
static int static int
translate_table(struct net *net, translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
const char *name, const struct ipt_replace *repl)
unsigned int valid_hooks,
struct xt_table_info *newinfo,
void *entry0,
unsigned int size,
unsigned int number,
const unsigned int *hook_entries,
const unsigned int *underflows)
{ {
struct ipt_entry *iter; struct ipt_entry *iter;
unsigned int i; unsigned int i;
int ret = 0; int ret = 0;
newinfo->size = size; newinfo->size = repl->size;
newinfo->number = number; newinfo->number = repl->num_entries;
/* Init all hooks to impossible value. */ /* Init all hooks to impossible value. */
for (i = 0; i < NF_INET_NUMHOOKS; i++) { for (i = 0; i < NF_INET_NUMHOOKS; i++) {
...@@ -843,42 +836,43 @@ translate_table(struct net *net, ...@@ -843,42 +836,43 @@ translate_table(struct net *net,
/* Walk through entries, checking offsets. */ /* Walk through entries, checking offsets. */
xt_entry_foreach(iter, entry0, newinfo->size) { xt_entry_foreach(iter, entry0, newinfo->size) {
ret = check_entry_size_and_hooks(iter, newinfo, entry0, ret = check_entry_size_and_hooks(iter, newinfo, entry0,
entry0 + size, hook_entries, underflows, valid_hooks); entry0 + repl->size, repl->hook_entry, repl->underflow,
repl->valid_hooks);
if (ret != 0) if (ret != 0)
return ret; return ret;
++i; ++i;
} }
if (i != number) { if (i != repl->num_entries) {
duprintf("translate_table: %u not %u entries\n", duprintf("translate_table: %u not %u entries\n",
i, number); i, repl->num_entries);
return -EINVAL; return -EINVAL;
} }
/* Check hooks all assigned */ /* Check hooks all assigned */
for (i = 0; i < NF_INET_NUMHOOKS; i++) { for (i = 0; i < NF_INET_NUMHOOKS; i++) {
/* Only hooks which are valid */ /* Only hooks which are valid */
if (!(valid_hooks & (1 << i))) if (!(repl->valid_hooks & (1 << i)))
continue; continue;
if (newinfo->hook_entry[i] == 0xFFFFFFFF) { if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
duprintf("Invalid hook entry %u %u\n", duprintf("Invalid hook entry %u %u\n",
i, hook_entries[i]); i, repl->hook_entry[i]);
return -EINVAL; return -EINVAL;
} }
if (newinfo->underflow[i] == 0xFFFFFFFF) { if (newinfo->underflow[i] == 0xFFFFFFFF) {
duprintf("Invalid underflow %u %u\n", duprintf("Invalid underflow %u %u\n",
i, underflows[i]); i, repl->underflow[i]);
return -EINVAL; return -EINVAL;
} }
} }
if (!mark_source_chains(newinfo, valid_hooks, entry0)) if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
return -ELOOP; return -ELOOP;
/* Finally, each sanity check must pass */ /* Finally, each sanity check must pass */
i = 0; i = 0;
xt_entry_foreach(iter, entry0, newinfo->size) { xt_entry_foreach(iter, entry0, newinfo->size) {
ret = find_check_entry(iter, net, name, size); ret = find_check_entry(iter, net, repl->name, repl->size);
if (ret != 0) if (ret != 0)
break; break;
++i; ++i;
...@@ -1311,9 +1305,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) ...@@ -1311,9 +1305,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
goto free_newinfo; goto free_newinfo;
} }
ret = translate_table(net, tmp.name, tmp.valid_hooks, ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
tmp.hook_entry, tmp.underflow);
if (ret != 0) if (ret != 0)
goto free_newinfo; goto free_newinfo;
...@@ -2112,11 +2104,7 @@ struct xt_table *ipt_register_table(struct net *net, ...@@ -2112,11 +2104,7 @@ struct xt_table *ipt_register_table(struct net *net,
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
memcpy(loc_cpu_entry, repl->entries, repl->size); memcpy(loc_cpu_entry, repl->entries, repl->size);
ret = translate_table(net, table->name, table->valid_hooks, ret = translate_table(net, newinfo, loc_cpu_entry, repl);
newinfo, loc_cpu_entry, repl->size,
repl->num_entries,
repl->hook_entry,
repl->underflow);
if (ret != 0) if (ret != 0)
goto out_free; goto out_free;
......
...@@ -845,22 +845,15 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net) ...@@ -845,22 +845,15 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net)
/* Checks and translates the user-supplied table segment (held in /* Checks and translates the user-supplied table segment (held in
newinfo) */ newinfo) */
static int static int
translate_table(struct net *net, translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
const char *name, const struct ip6t_replace *repl)
unsigned int valid_hooks,
struct xt_table_info *newinfo,
void *entry0,
unsigned int size,
unsigned int number,
const unsigned int *hook_entries,
const unsigned int *underflows)
{ {
struct ip6t_entry *iter; struct ip6t_entry *iter;
unsigned int i; unsigned int i;
int ret = 0; int ret = 0;
newinfo->size = size; newinfo->size = repl->size;
newinfo->number = number; newinfo->number = repl->num_entries;
/* Init all hooks to impossible value. */ /* Init all hooks to impossible value. */
for (i = 0; i < NF_INET_NUMHOOKS; i++) { for (i = 0; i < NF_INET_NUMHOOKS; i++) {
...@@ -873,42 +866,43 @@ translate_table(struct net *net, ...@@ -873,42 +866,43 @@ translate_table(struct net *net,
/* Walk through entries, checking offsets. */ /* Walk through entries, checking offsets. */
xt_entry_foreach(iter, entry0, newinfo->size) { xt_entry_foreach(iter, entry0, newinfo->size) {
ret = check_entry_size_and_hooks(iter, newinfo, entry0, ret = check_entry_size_and_hooks(iter, newinfo, entry0,
entry0 + size, hook_entries, underflows, valid_hooks); entry0 + repl->size, repl->hook_entry, repl->underflow,
repl->valid_hooks);
if (ret != 0) if (ret != 0)
return ret; return ret;
++i; ++i;
} }
if (i != number) { if (i != repl->num_entries) {
duprintf("translate_table: %u not %u entries\n", duprintf("translate_table: %u not %u entries\n",
i, number); i, repl->num_entries);
return -EINVAL; return -EINVAL;
} }
/* Check hooks all assigned */ /* Check hooks all assigned */
for (i = 0; i < NF_INET_NUMHOOKS; i++) { for (i = 0; i < NF_INET_NUMHOOKS; i++) {
/* Only hooks which are valid */ /* Only hooks which are valid */
if (!(valid_hooks & (1 << i))) if (!(repl->valid_hooks & (1 << i)))
continue; continue;
if (newinfo->hook_entry[i] == 0xFFFFFFFF) { if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
duprintf("Invalid hook entry %u %u\n", duprintf("Invalid hook entry %u %u\n",
i, hook_entries[i]); i, repl->hook_entry[i]);
return -EINVAL; return -EINVAL;
} }
if (newinfo->underflow[i] == 0xFFFFFFFF) { if (newinfo->underflow[i] == 0xFFFFFFFF) {
duprintf("Invalid underflow %u %u\n", duprintf("Invalid underflow %u %u\n",
i, underflows[i]); i, repl->underflow[i]);
return -EINVAL; return -EINVAL;
} }
} }
if (!mark_source_chains(newinfo, valid_hooks, entry0)) if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
return -ELOOP; return -ELOOP;
/* Finally, each sanity check must pass */ /* Finally, each sanity check must pass */
i = 0; i = 0;
xt_entry_foreach(iter, entry0, newinfo->size) { xt_entry_foreach(iter, entry0, newinfo->size) {
ret = find_check_entry(iter, net, name, size); ret = find_check_entry(iter, net, repl->name, repl->size);
if (ret != 0) if (ret != 0)
break; break;
++i; ++i;
...@@ -1342,9 +1336,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) ...@@ -1342,9 +1336,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
goto free_newinfo; goto free_newinfo;
} }
ret = translate_table(net, tmp.name, tmp.valid_hooks, ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
tmp.hook_entry, tmp.underflow);
if (ret != 0) if (ret != 0)
goto free_newinfo; goto free_newinfo;
...@@ -2145,11 +2137,7 @@ struct xt_table *ip6t_register_table(struct net *net, ...@@ -2145,11 +2137,7 @@ struct xt_table *ip6t_register_table(struct net *net,
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
memcpy(loc_cpu_entry, repl->entries, repl->size); memcpy(loc_cpu_entry, repl->entries, repl->size);
ret = translate_table(net, table->name, table->valid_hooks, ret = translate_table(net, newinfo, loc_cpu_entry, repl);
newinfo, loc_cpu_entry, repl->size,
repl->num_entries,
repl->hook_entry,
repl->underflow);
if (ret != 0) if (ret != 0)
goto out_free; goto out_free;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment