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 <step...@networkplumber.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