aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2007-04-20 18:57:15 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:29:12 -0400
commit334901700f9f58993ebd7f6136d3f9062460d34d (patch)
treeaf1887c408d6757debd73d2e56d45039943e413b
parent49ed67a9eee3c756263feed4474e4fcf5c8eaed2 (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.h3
-rw-r--r--net/ipv4/af_inet.c59
-rw-r--r--net/ipv4/proc.c25
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
169extern int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
170extern void snmp_mib_free(void *ptr[2]);
171
169extern int sysctl_local_port_range[2]; 172extern int sysctl_local_port_range[2];
170extern int sysctl_ip_default_ttl; 173extern int sysctl_ip_default_ttl;
171extern int sysctl_ip_nonlocal_bind; 174extern 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
1246static int __init init_ipv4_mibs(void) 1246static 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
1277err_udplite_mib:
1278 snmp_mib_free((void **)udp_statistics);
1279err_udp_mib:
1280 snmp_mib_free((void **)tcp_statistics);
1281err_tcp_mib:
1282 snmp_mib_free((void **)icmp_statistics);
1283err_icmp_mib:
1284 snmp_mib_free((void **)ip_statistics);
1285err_ip_mib:
1286 snmp_mib_free((void **)net_statistics);
1287err_net_mib:
1288 return -ENOMEM;
1270} 1289}
1271 1290
1272static int ipv4_proc_init(void); 1291static 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
394int 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;
404err1:
405 free_percpu(ptr[0]);
406 ptr[0] = NULL;
407err0:
408 return -ENOMEM;
409}
410
411void 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