[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180301020101.3975-1-sthemmin@microsoft.com>
Date: Wed, 28 Feb 2018 18:01:01 -0800
From: Stephen Hemminger <stephen@...workplumber.org>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, Stephen Hemminger <sthemmin@...rosoft.com>,
Stephen Hemminger <stephen@...workplumber.org>
Subject: [PATCH] inet: add bound ports statistic
This adds a number of bound ports in a network namespace which is
a useful for socket summary (ss) command. It adds one additional
field onto /proc/net/sockstat.
Since collecting these kind of counters can be sensitive for large
machines, the impact is placed on the reading side which will be
much rarer.
Signed-off-by: Stephen Hemminger <stephen@...workplumber.org>
---
include/net/inet_connection_sock.h | 2 +-
net/ipv4/inet_connection_sock.c | 22 ++++++++++++++++++++++
net/ipv4/proc.c | 5 +++--
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index c1a93ce35e62..3044deec73ce 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -265,7 +265,7 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
}
struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern);
-
+unsigned int inet_csk_count_ports(struct net *net, struct proto *prot);
int inet_csk_get_port(struct sock *sk, unsigned short snum);
struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 881ac6d046f2..2418abce4d50 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -424,6 +424,28 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo)
return err;
}
+/* Count how many any entries are in the bind hash table */
+unsigned int inet_csk_count_ports(struct net *net, struct proto *prot)
+{
+ struct inet_hashinfo *hinfo = prot->h.hashinfo;
+ struct inet_bind_hashbucket *head;
+ struct inet_bind_bucket *tb;
+ unsigned int i, ports = 0;
+
+ for (i = 0; i < hinfo->bhash_size; i++) {
+ head = &hinfo->bhash[i];
+
+ spin_lock_bh(&head->lock);
+ inet_bind_bucket_for_each(tb, &head->chain) {
+ if (net_eq(ib_net(tb), net))
+ ++ports;
+ }
+ spin_unlock_bh(&head->lock);
+ }
+
+ return ports;
+}
+
/*
* This will accept the next outstanding connection.
*/
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index fdabc70283b6..7cd781026224 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -61,10 +61,11 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
sockets = proto_sockets_allocated_sum_positive(&tcp_prot);
socket_seq_show(seq);
- seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
+ seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld ports %u\n",
sock_prot_inuse_get(net, &tcp_prot), orphans,
atomic_read(&net->ipv4.tcp_death_row.tw_count), sockets,
- proto_memory_allocated(&tcp_prot));
+ proto_memory_allocated(&tcp_prot),
+ inet_csk_count_ports(net, &tcp_prot));
seq_printf(seq, "UDP: inuse %d mem %ld\n",
sock_prot_inuse_get(net, &udp_prot),
proto_memory_allocated(&udp_prot));
--
2.16.1
Powered by blists - more mailing lists