diff options
author | Florian Westphal <fw@strlen.de> | 2010-02-06 20:48:47 -0500 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2010-02-16 11:27:05 -0500 |
commit | 49facff9f92508413f3da598f86aaf6c1121ff27 (patch) | |
tree | e4fe80cfd1b19f5fd1e5cc518fb86617e962dd8f /net/bridge | |
parent | 837395aa863142be7c38be0ca780aef21b12b49f (diff) |
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>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 46030dc90845..76b99d3c1eea 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1242,38 +1242,33 @@ void ebt_unregister_table(struct net *net, struct ebt_table *table) | |||
1242 | } | 1242 | } |
1243 | 1243 | ||
1244 | /* userspace just supplied us with counters */ | 1244 | /* userspace just supplied us with counters */ |
1245 | static int update_counters(struct net *net, const void __user *user, | 1245 | static int do_update_counters(struct net *net, const char *name, |
1246 | unsigned int len) | 1246 | struct ebt_counter __user *counters, |
1247 | unsigned int num_counters, | ||
1248 | const void __user *user, unsigned int len) | ||
1247 | { | 1249 | { |
1248 | int i, ret; | 1250 | int i, ret; |
1249 | struct ebt_counter *tmp; | 1251 | struct ebt_counter *tmp; |
1250 | struct ebt_replace hlp; | ||
1251 | struct ebt_table *t; | 1252 | struct ebt_table *t; |
1252 | 1253 | ||
1253 | if (copy_from_user(&hlp, user, sizeof(hlp))) | 1254 | if (num_counters == 0) |
1254 | return -EFAULT; | ||
1255 | |||
1256 | if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter)) | ||
1257 | return -EINVAL; | ||
1258 | if (hlp.num_counters == 0) | ||
1259 | return -EINVAL; | 1255 | return -EINVAL; |
1260 | 1256 | ||
1261 | if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) | 1257 | tmp = vmalloc(num_counters * sizeof(*tmp)); |
1258 | if (!tmp) | ||
1262 | return -ENOMEM; | 1259 | return -ENOMEM; |
1263 | 1260 | ||
1264 | t = find_table_lock(net, hlp.name, &ret, &ebt_mutex); | 1261 | t = find_table_lock(net, name, &ret, &ebt_mutex); |
1265 | if (!t) | 1262 | if (!t) |
1266 | goto free_tmp; | 1263 | goto free_tmp; |
1267 | 1264 | ||
1268 | if (hlp.num_counters != t->private->nentries) { | 1265 | if (num_counters != t->private->nentries) { |
1269 | BUGPRINT("Wrong nr of counters\n"); | 1266 | BUGPRINT("Wrong nr of counters\n"); |
1270 | ret = -EINVAL; | 1267 | ret = -EINVAL; |
1271 | goto unlock_mutex; | 1268 | goto unlock_mutex; |
1272 | } | 1269 | } |
1273 | 1270 | ||
1274 | if ( copy_from_user(tmp, hlp.counters, | 1271 | if (copy_from_user(tmp, counters, num_counters * sizeof(*counters))) { |
1275 | hlp.num_counters * sizeof(struct ebt_counter)) ) { | ||
1276 | BUGPRINT("Updata_counters && !cfu\n"); | ||
1277 | ret = -EFAULT; | 1272 | ret = -EFAULT; |
1278 | goto unlock_mutex; | 1273 | goto unlock_mutex; |
1279 | } | 1274 | } |
@@ -1282,7 +1277,7 @@ static int update_counters(struct net *net, const void __user *user, | |||
1282 | write_lock_bh(&t->lock); | 1277 | write_lock_bh(&t->lock); |
1283 | 1278 | ||
1284 | /* we add to the counters of the first cpu */ | 1279 | /* we add to the counters of the first cpu */ |
1285 | for (i = 0; i < hlp.num_counters; i++) { | 1280 | for (i = 0; i < num_counters; i++) { |
1286 | t->private->counters[i].pcnt += tmp[i].pcnt; | 1281 | t->private->counters[i].pcnt += tmp[i].pcnt; |
1287 | t->private->counters[i].bcnt += tmp[i].bcnt; | 1282 | t->private->counters[i].bcnt += tmp[i].bcnt; |
1288 | } | 1283 | } |
@@ -1296,6 +1291,21 @@ free_tmp: | |||
1296 | return ret; | 1291 | return ret; |
1297 | } | 1292 | } |
1298 | 1293 | ||
1294 | static int update_counters(struct net *net, const void __user *user, | ||
1295 | unsigned int len) | ||
1296 | { | ||
1297 | struct ebt_replace hlp; | ||
1298 | |||
1299 | if (copy_from_user(&hlp, user, sizeof(hlp))) | ||
1300 | return -EFAULT; | ||
1301 | |||
1302 | if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter)) | ||
1303 | return -EINVAL; | ||
1304 | |||
1305 | return do_update_counters(net, hlp.name, hlp.counters, | ||
1306 | hlp.num_counters, user, len); | ||
1307 | } | ||
1308 | |||
1299 | static inline int ebt_make_matchname(const struct ebt_entry_match *m, | 1309 | static inline int ebt_make_matchname(const struct ebt_entry_match *m, |
1300 | const char *base, char __user *ubase) | 1310 | const char *base, char __user *ubase) |
1301 | { | 1311 | { |