netfilter: ebtables: split update_counters into two functions

allows to call do_update_counters() from upcoming CONFIG_COMPAT
code instead of copy&pasting the same code.

Signed-off-by: Florian Westphal <fw@strlen.de>
This commit is contained in:
Florian Westphal 2010-02-07 02:48:47 +01:00
parent 837395aa86
commit 49facff9f9
1 changed files with 26 additions and 16 deletions

View File

@ -1242,38 +1242,33 @@ void ebt_unregister_table(struct net *net, struct ebt_table *table)
} }
/* userspace just supplied us with counters */ /* userspace just supplied us with counters */
static int update_counters(struct net *net, const void __user *user, static int do_update_counters(struct net *net, const char *name,
unsigned int len) struct ebt_counter __user *counters,
unsigned int num_counters,
const void __user *user, unsigned int len)
{ {
int i, ret; int i, ret;
struct ebt_counter *tmp; struct ebt_counter *tmp;
struct ebt_replace hlp;
struct ebt_table *t; struct ebt_table *t;
if (copy_from_user(&hlp, user, sizeof(hlp))) if (num_counters == 0)
return -EFAULT;
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
return -EINVAL;
if (hlp.num_counters == 0)
return -EINVAL; return -EINVAL;
if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) tmp = vmalloc(num_counters * sizeof(*tmp));
if (!tmp)
return -ENOMEM; return -ENOMEM;
t = find_table_lock(net, hlp.name, &ret, &ebt_mutex); t = find_table_lock(net, name, &ret, &ebt_mutex);
if (!t) if (!t)
goto free_tmp; goto free_tmp;
if (hlp.num_counters != t->private->nentries) { if (num_counters != t->private->nentries) {
BUGPRINT("Wrong nr of counters\n"); BUGPRINT("Wrong nr of counters\n");
ret = -EINVAL; ret = -EINVAL;
goto unlock_mutex; goto unlock_mutex;
} }
if ( copy_from_user(tmp, hlp.counters, if (copy_from_user(tmp, counters, num_counters * sizeof(*counters))) {
hlp.num_counters * sizeof(struct ebt_counter)) ) {
BUGPRINT("Updata_counters && !cfu\n");
ret = -EFAULT; ret = -EFAULT;
goto unlock_mutex; goto unlock_mutex;
} }
@ -1282,7 +1277,7 @@ static int update_counters(struct net *net, const void __user *user,
write_lock_bh(&t->lock); write_lock_bh(&t->lock);
/* we add to the counters of the first cpu */ /* we add to the counters of the first cpu */
for (i = 0; i < hlp.num_counters; i++) { for (i = 0; i < num_counters; i++) {
t->private->counters[i].pcnt += tmp[i].pcnt; t->private->counters[i].pcnt += tmp[i].pcnt;
t->private->counters[i].bcnt += tmp[i].bcnt; t->private->counters[i].bcnt += tmp[i].bcnt;
} }
@ -1296,6 +1291,21 @@ free_tmp:
return ret; return ret;
} }
static int update_counters(struct net *net, const void __user *user,
unsigned int len)
{
struct ebt_replace hlp;
if (copy_from_user(&hlp, user, sizeof(hlp)))
return -EFAULT;
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
return -EINVAL;
return do_update_counters(net, hlp.name, hlp.counters,
hlp.num_counters, user, len);
}
static inline int ebt_make_matchname(const struct ebt_entry_match *m, static inline int ebt_make_matchname(const struct ebt_entry_match *m,
const char *base, char __user *ubase) const char *base, char __user *ubase)
{ {