diff options
author | Patrick McHardy <kaber@trash.net> | 2007-12-18 00:50:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:58:35 -0500 |
commit | 433665c9d110d783ea4043c59657f0437fcc31dd (patch) | |
tree | ec7f9d9c72dcbcbb9a3ab7d36987e018df97c295 /net/ipv6 | |
parent | ed1a6f5e77441c4020b8541b3f03f03e37d638e1 (diff) |
[NETFILTER]: ip6_tables: move IP6T_SO_GET_INFO handling to seperate function
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 89 |
1 files changed, 47 insertions, 42 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 02be4fcb915b..681316e40c6f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -1037,6 +1037,50 @@ copy_entries_to_user(unsigned int total_size, | |||
1037 | return ret; | 1037 | return ret; |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static int get_info(void __user *user, int *len) | ||
1041 | { | ||
1042 | char name[IP6T_TABLE_MAXNAMELEN]; | ||
1043 | struct xt_table *t; | ||
1044 | int ret; | ||
1045 | |||
1046 | if (*len != sizeof(struct ip6t_getinfo)) { | ||
1047 | duprintf("length %u != %u\n", *len, | ||
1048 | sizeof(struct ip6t_getinfo)); | ||
1049 | return -EINVAL; | ||
1050 | } | ||
1051 | |||
1052 | if (copy_from_user(name, user, sizeof(name)) != 0) | ||
1053 | return -EFAULT; | ||
1054 | |||
1055 | name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; | ||
1056 | |||
1057 | t = try_then_request_module(xt_find_table_lock(AF_INET6, name), | ||
1058 | "ip6table_%s", name); | ||
1059 | if (t && !IS_ERR(t)) { | ||
1060 | struct ip6t_getinfo info; | ||
1061 | struct xt_table_info *private = t->private; | ||
1062 | |||
1063 | info.valid_hooks = t->valid_hooks; | ||
1064 | memcpy(info.hook_entry, private->hook_entry, | ||
1065 | sizeof(info.hook_entry)); | ||
1066 | memcpy(info.underflow, private->underflow, | ||
1067 | sizeof(info.underflow)); | ||
1068 | info.num_entries = private->number; | ||
1069 | info.size = private->size; | ||
1070 | memcpy(info.name, name, sizeof(info.name)); | ||
1071 | |||
1072 | if (copy_to_user(user, &info, *len) != 0) | ||
1073 | ret = -EFAULT; | ||
1074 | else | ||
1075 | ret = 0; | ||
1076 | |||
1077 | xt_table_unlock(t); | ||
1078 | module_put(t->me); | ||
1079 | } else | ||
1080 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
1081 | return ret; | ||
1082 | } | ||
1083 | |||
1040 | static int | 1084 | static int |
1041 | get_entries(const struct ip6t_get_entries *entries, | 1085 | get_entries(const struct ip6t_get_entries *entries, |
1042 | struct ip6t_get_entries __user *uptr) | 1086 | struct ip6t_get_entries __user *uptr) |
@@ -1274,48 +1318,9 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1274 | return -EPERM; | 1318 | return -EPERM; |
1275 | 1319 | ||
1276 | switch (cmd) { | 1320 | switch (cmd) { |
1277 | case IP6T_SO_GET_INFO: { | 1321 | case IP6T_SO_GET_INFO: |
1278 | char name[IP6T_TABLE_MAXNAMELEN]; | 1322 | ret = get_info(user, len); |
1279 | struct xt_table *t; | 1323 | break; |
1280 | |||
1281 | if (*len != sizeof(struct ip6t_getinfo)) { | ||
1282 | duprintf("length %u != %u\n", *len, | ||
1283 | sizeof(struct ip6t_getinfo)); | ||
1284 | ret = -EINVAL; | ||
1285 | break; | ||
1286 | } | ||
1287 | |||
1288 | if (copy_from_user(name, user, sizeof(name)) != 0) { | ||
1289 | ret = -EFAULT; | ||
1290 | break; | ||
1291 | } | ||
1292 | name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; | ||
1293 | |||
1294 | t = try_then_request_module(xt_find_table_lock(AF_INET6, name), | ||
1295 | "ip6table_%s", name); | ||
1296 | if (t && !IS_ERR(t)) { | ||
1297 | struct ip6t_getinfo info; | ||
1298 | struct xt_table_info *private = t->private; | ||
1299 | |||
1300 | info.valid_hooks = t->valid_hooks; | ||
1301 | memcpy(info.hook_entry, private->hook_entry, | ||
1302 | sizeof(info.hook_entry)); | ||
1303 | memcpy(info.underflow, private->underflow, | ||
1304 | sizeof(info.underflow)); | ||
1305 | info.num_entries = private->number; | ||
1306 | info.size = private->size; | ||
1307 | memcpy(info.name, name, sizeof(info.name)); | ||
1308 | |||
1309 | if (copy_to_user(user, &info, *len) != 0) | ||
1310 | ret = -EFAULT; | ||
1311 | else | ||
1312 | ret = 0; | ||
1313 | xt_table_unlock(t); | ||
1314 | module_put(t->me); | ||
1315 | } else | ||
1316 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
1317 | } | ||
1318 | break; | ||
1319 | 1324 | ||
1320 | case IP6T_SO_GET_ENTRIES: { | 1325 | case IP6T_SO_GET_ENTRIES: { |
1321 | struct ip6t_get_entries get; | 1326 | struct ip6t_get_entries get; |