diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2007-04-20 18:57:15 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:29:12 -0400 |
commit | 334901700f9f58993ebd7f6136d3f9062460d34d (patch) | |
tree | af1887c408d6757debd73d2e56d45039943e413b | |
parent | 49ed67a9eee3c756263feed4474e4fcf5c8eaed2 (diff) |
[IPV4] SNMP: Move some statistic bits to net/ipv4/proc.c.
This also fixes memory leak in error path.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/ip.h | 3 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 59 | ||||
-rw-r--r-- | net/ipv4/proc.c | 25 |
3 files changed, 67 insertions, 20 deletions
diff --git a/include/net/ip.h b/include/net/ip.h index 75f226d26e0d..f41ce07f6700 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -166,6 +166,9 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics); | |||
166 | #define NET_ADD_STATS_BH(field, adnd) SNMP_ADD_STATS_BH(net_statistics, field, adnd) | 166 | #define NET_ADD_STATS_BH(field, adnd) SNMP_ADD_STATS_BH(net_statistics, field, adnd) |
167 | #define NET_ADD_STATS_USER(field, adnd) SNMP_ADD_STATS_USER(net_statistics, field, adnd) | 167 | #define NET_ADD_STATS_USER(field, adnd) SNMP_ADD_STATS_USER(net_statistics, field, adnd) |
168 | 168 | ||
169 | extern int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign); | ||
170 | extern void snmp_mib_free(void *ptr[2]); | ||
171 | |||
169 | extern int sysctl_local_port_range[2]; | 172 | extern int sysctl_local_port_range[2]; |
170 | extern int sysctl_ip_default_ttl; | 173 | extern int sysctl_ip_default_ttl; |
171 | extern int sysctl_ip_nonlocal_bind; | 174 | extern int sysctl_ip_nonlocal_bind; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 45ced52c03d4..a33ca7e7e8f8 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1245,28 +1245,47 @@ static struct net_protocol icmp_protocol = { | |||
1245 | 1245 | ||
1246 | static int __init init_ipv4_mibs(void) | 1246 | static int __init init_ipv4_mibs(void) |
1247 | { | 1247 | { |
1248 | net_statistics[0] = alloc_percpu(struct linux_mib); | 1248 | if (snmp_mib_init((void **)net_statistics, |
1249 | net_statistics[1] = alloc_percpu(struct linux_mib); | 1249 | sizeof(struct linux_mib), |
1250 | ip_statistics[0] = alloc_percpu(struct ipstats_mib); | 1250 | __alignof__(struct linux_mib)) < 0) |
1251 | ip_statistics[1] = alloc_percpu(struct ipstats_mib); | 1251 | goto err_net_mib; |
1252 | icmp_statistics[0] = alloc_percpu(struct icmp_mib); | 1252 | if (snmp_mib_init((void **)ip_statistics, |
1253 | icmp_statistics[1] = alloc_percpu(struct icmp_mib); | 1253 | sizeof(struct ipstats_mib), |
1254 | tcp_statistics[0] = alloc_percpu(struct tcp_mib); | 1254 | __alignof__(struct ipstats_mib)) < 0) |
1255 | tcp_statistics[1] = alloc_percpu(struct tcp_mib); | 1255 | goto err_ip_mib; |
1256 | udp_statistics[0] = alloc_percpu(struct udp_mib); | 1256 | if (snmp_mib_init((void **)icmp_statistics, |
1257 | udp_statistics[1] = alloc_percpu(struct udp_mib); | 1257 | sizeof(struct icmp_mib), |
1258 | udplite_statistics[0] = alloc_percpu(struct udp_mib); | 1258 | __alignof__(struct icmp_mib)) < 0) |
1259 | udplite_statistics[1] = alloc_percpu(struct udp_mib); | 1259 | goto err_icmp_mib; |
1260 | if (! | 1260 | if (snmp_mib_init((void **)tcp_statistics, |
1261 | (net_statistics[0] && net_statistics[1] && ip_statistics[0] | 1261 | sizeof(struct tcp_mib), |
1262 | && ip_statistics[1] && tcp_statistics[0] && tcp_statistics[1] | 1262 | __alignof__(struct tcp_mib)) < 0) |
1263 | && udp_statistics[0] && udp_statistics[1] | 1263 | goto err_tcp_mib; |
1264 | && udplite_statistics[0] && udplite_statistics[1] ) ) | 1264 | if (snmp_mib_init((void **)udp_statistics, |
1265 | return -ENOMEM; | 1265 | sizeof(struct udp_mib), |
1266 | 1266 | __alignof__(struct udp_mib)) < 0) | |
1267 | (void) tcp_mib_init(); | 1267 | goto err_udp_mib; |
1268 | if (snmp_mib_init((void **)udplite_statistics, | ||
1269 | sizeof(struct udp_mib), | ||
1270 | __alignof__(struct udp_mib)) < 0) | ||
1271 | goto err_udplite_mib; | ||
1272 | |||
1273 | tcp_mib_init(); | ||
1268 | 1274 | ||
1269 | return 0; | 1275 | return 0; |
1276 | |||
1277 | err_udplite_mib: | ||
1278 | snmp_mib_free((void **)udp_statistics); | ||
1279 | err_udp_mib: | ||
1280 | snmp_mib_free((void **)tcp_statistics); | ||
1281 | err_tcp_mib: | ||
1282 | snmp_mib_free((void **)icmp_statistics); | ||
1283 | err_icmp_mib: | ||
1284 | snmp_mib_free((void **)ip_statistics); | ||
1285 | err_ip_mib: | ||
1286 | snmp_mib_free((void **)net_statistics); | ||
1287 | err_net_mib: | ||
1288 | return -ENOMEM; | ||
1270 | } | 1289 | } |
1271 | 1290 | ||
1272 | static int ipv4_proc_init(void); | 1291 | static int ipv4_proc_init(void); |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index ae68a691e8cd..97952d54ae84 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -391,3 +391,28 @@ out_netstat: | |||
391 | goto out; | 391 | goto out; |
392 | } | 392 | } |
393 | 393 | ||
394 | int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign) | ||
395 | { | ||
396 | BUG_ON(ptr == NULL); | ||
397 | ptr[0] = __alloc_percpu(mibsize); | ||
398 | if (!ptr[0]) | ||
399 | goto err0; | ||
400 | ptr[1] = __alloc_percpu(mibsize); | ||
401 | if (!ptr[1]) | ||
402 | goto err1; | ||
403 | return 0; | ||
404 | err1: | ||
405 | free_percpu(ptr[0]); | ||
406 | ptr[0] = NULL; | ||
407 | err0: | ||
408 | return -ENOMEM; | ||
409 | } | ||
410 | |||
411 | void snmp_mib_free(void *ptr[2]) | ||
412 | { | ||
413 | BUG_ON(ptr == NULL); | ||
414 | free_percpu(ptr[0]); | ||
415 | free_percpu(ptr[1]); | ||
416 | ptr[0] = ptr[1] = NULL; | ||
417 | } | ||
418 | |||