diff options
Diffstat (limited to 'net/ipv4/proc.c')
| -rw-r--r-- | net/ipv4/proc.c | 102 | 
1 files changed, 63 insertions, 39 deletions
| diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1ed015e4bc79..7143ca1a6af9 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -46,6 +46,8 @@  #include <net/sock.h>  #include <net/raw.h> +#define TCPUDP_MIB_MAX max_t(u32, UDP_MIB_MAX, TCP_MIB_MAX) +  /*   *	Report socket allocation statistics [mea@utu.fi]   */ @@ -356,22 +358,22 @@ static void icmp_put(struct seq_file *seq)  	atomic_long_t *ptr = net->mib.icmpmsg_statistics->mibs;  	seq_puts(seq, "\nIcmp: InMsgs InErrors InCsumErrors"); -	for (i = 0; icmpmibmap[i].name != NULL; i++) +	for (i = 0; icmpmibmap[i].name; i++)  		seq_printf(seq, " In%s", icmpmibmap[i].name);  	seq_puts(seq, " OutMsgs OutErrors"); -	for (i = 0; icmpmibmap[i].name != NULL; i++) +	for (i = 0; icmpmibmap[i].name; i++)  		seq_printf(seq, " Out%s", icmpmibmap[i].name);  	seq_printf(seq, "\nIcmp: %lu %lu %lu",  		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_INMSGS),  		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_INERRORS),  		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_CSUMERRORS)); -	for (i = 0; icmpmibmap[i].name != NULL; i++) +	for (i = 0; icmpmibmap[i].name; i++)  		seq_printf(seq, " %lu",  			   atomic_long_read(ptr + icmpmibmap[i].index));  	seq_printf(seq, " %lu %lu",  		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_OUTMSGS),  		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_OUTERRORS)); -	for (i = 0; icmpmibmap[i].name != NULL; i++) +	for (i = 0; icmpmibmap[i].name; i++)  		seq_printf(seq, " %lu",  			   atomic_long_read(ptr + (icmpmibmap[i].index | 0x100)));  } @@ -379,14 +381,16 @@ static void icmp_put(struct seq_file *seq)  /*   *	Called from the PROCfs module. This outputs /proc/net/snmp.   */ -static int snmp_seq_show(struct seq_file *seq, void *v) +static int snmp_seq_show_ipstats(struct seq_file *seq, void *v)  { -	int i;  	struct net *net = seq->private; +	u64 buff64[IPSTATS_MIB_MAX]; +	int i; -	seq_puts(seq, "Ip: Forwarding DefaultTTL"); +	memset(buff64, 0, IPSTATS_MIB_MAX * sizeof(u64)); -	for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) +	seq_puts(seq, "Ip: Forwarding DefaultTTL"); +	for (i = 0; snmp4_ipstats_list[i].name; i++)  		seq_printf(seq, " %s", snmp4_ipstats_list[i].name);  	seq_printf(seq, "\nIp: %d %d", @@ -394,57 +398,77 @@ static int snmp_seq_show(struct seq_file *seq, void *v)  		   net->ipv4.sysctl_ip_default_ttl);  	BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0); -	for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) -		seq_printf(seq, " %llu", -			   snmp_fold_field64(net->mib.ip_statistics, -					     snmp4_ipstats_list[i].entry, -					     offsetof(struct ipstats_mib, syncp))); +	snmp_get_cpu_field64_batch(buff64, snmp4_ipstats_list, +				   net->mib.ip_statistics, +				   offsetof(struct ipstats_mib, syncp)); +	for (i = 0; snmp4_ipstats_list[i].name; i++) +		seq_printf(seq, " %llu", buff64[i]); -	icmp_put(seq);	/* RFC 2011 compatibility */ -	icmpmsg_put(seq); +	return 0; +} + +static int snmp_seq_show_tcp_udp(struct seq_file *seq, void *v) +{ +	unsigned long buff[TCPUDP_MIB_MAX]; +	struct net *net = seq->private; +	int i; + +	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));  	seq_puts(seq, "\nTcp:"); -	for (i = 0; snmp4_tcp_list[i].name != NULL; i++) +	for (i = 0; snmp4_tcp_list[i].name; i++)  		seq_printf(seq, " %s", snmp4_tcp_list[i].name);  	seq_puts(seq, "\nTcp:"); -	for (i = 0; snmp4_tcp_list[i].name != NULL; i++) { +	snmp_get_cpu_field_batch(buff, snmp4_tcp_list, +				 net->mib.tcp_statistics); +	for (i = 0; snmp4_tcp_list[i].name; i++) {  		/* MaxConn field is signed, RFC 2012 */  		if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN) -			seq_printf(seq, " %ld", -				   snmp_fold_field(net->mib.tcp_statistics, -						   snmp4_tcp_list[i].entry)); +			seq_printf(seq, " %ld", buff[i]);  		else -			seq_printf(seq, " %lu", -				   snmp_fold_field(net->mib.tcp_statistics, -						   snmp4_tcp_list[i].entry)); +			seq_printf(seq, " %lu", buff[i]);  	} +	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long)); + +	snmp_get_cpu_field_batch(buff, snmp4_udp_list, +				 net->mib.udp_statistics);  	seq_puts(seq, "\nUdp:"); -	for (i = 0; snmp4_udp_list[i].name != NULL; i++) +	for (i = 0; snmp4_udp_list[i].name; i++)  		seq_printf(seq, " %s", snmp4_udp_list[i].name); -  	seq_puts(seq, "\nUdp:"); -	for (i = 0; snmp4_udp_list[i].name != NULL; i++) -		seq_printf(seq, " %lu", -			   snmp_fold_field(net->mib.udp_statistics, -					   snmp4_udp_list[i].entry)); +	for (i = 0; snmp4_udp_list[i].name; i++) +		seq_printf(seq, " %lu", buff[i]); + +	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));  	/* the UDP and UDP-Lite MIBs are the same */  	seq_puts(seq, "\nUdpLite:"); -	for (i = 0; snmp4_udp_list[i].name != NULL; i++) +	snmp_get_cpu_field_batch(buff, snmp4_udp_list, +				 net->mib.udplite_statistics); +	for (i = 0; snmp4_udp_list[i].name; i++)  		seq_printf(seq, " %s", snmp4_udp_list[i].name); -  	seq_puts(seq, "\nUdpLite:"); -	for (i = 0; snmp4_udp_list[i].name != NULL; i++) -		seq_printf(seq, " %lu", -			   snmp_fold_field(net->mib.udplite_statistics, -					   snmp4_udp_list[i].entry)); +	for (i = 0; snmp4_udp_list[i].name; i++) +		seq_printf(seq, " %lu", buff[i]);  	seq_putc(seq, '\n');  	return 0;  } +static int snmp_seq_show(struct seq_file *seq, void *v) +{ +	snmp_seq_show_ipstats(seq, v); + +	icmp_put(seq);	/* RFC 2011 compatibility */ +	icmpmsg_put(seq); + +	snmp_seq_show_tcp_udp(seq, v); + +	return 0; +} +  static int snmp_seq_open(struct inode *inode, struct file *file)  {  	return single_open_net(inode, file, snmp_seq_show); @@ -469,21 +493,21 @@ static int netstat_seq_show(struct seq_file *seq, void *v)  	struct net *net = seq->private;  	seq_puts(seq, "TcpExt:"); -	for (i = 0; snmp4_net_list[i].name != NULL; i++) +	for (i = 0; snmp4_net_list[i].name; i++)  		seq_printf(seq, " %s", snmp4_net_list[i].name);  	seq_puts(seq, "\nTcpExt:"); -	for (i = 0; snmp4_net_list[i].name != NULL; i++) +	for (i = 0; snmp4_net_list[i].name; i++)  		seq_printf(seq, " %lu",  			   snmp_fold_field(net->mib.net_statistics,  					   snmp4_net_list[i].entry));  	seq_puts(seq, "\nIpExt:"); -	for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) +	for (i = 0; snmp4_ipextstats_list[i].name; i++)  		seq_printf(seq, " %s", snmp4_ipextstats_list[i].name);  	seq_puts(seq, "\nIpExt:"); -	for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) +	for (i = 0; snmp4_ipextstats_list[i].name; i++)  		seq_printf(seq, " %llu",  			   snmp_fold_field64(net->mib.ip_statistics,  					     snmp4_ipextstats_list[i].entry, | 
