RDS: TCP: report addr/port info based on TCP socket in rds-info
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Fri, 4 Nov 2016 17:04:11 +0000 (10:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Nov 2016 17:47:49 +0000 (12:47 -0500)
The socket argument passed to rds_tcp_tc_info() is a PF_RDS socket,
so it is incorrect to report the address port info based on
rds_getname() as part of TCP state report.

Invoke inet_getname() for the t_sock associated with the
rds_tcp_connection instead.

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/rds/tcp.c

index fcddacc92e018bee041f250cde5e48ba8ea70c6a..3296a6ac583ab37eb61ca511f71359d666b36295 100644 (file)
@@ -220,7 +220,7 @@ void rds_tcp_set_callbacks(struct socket *sock, struct rds_conn_path *cp)
        write_unlock_bh(&sock->sk->sk_callback_lock);
 }
 
-static void rds_tcp_tc_info(struct socket *sock, unsigned int len,
+static void rds_tcp_tc_info(struct socket *rds_sock, unsigned int len,
                            struct rds_info_iterator *iter,
                            struct rds_info_lengths *lens)
 {
@@ -229,6 +229,7 @@ static void rds_tcp_tc_info(struct socket *sock, unsigned int len,
        unsigned long flags;
        struct sockaddr_in sin;
        int sinlen;
+       struct socket *sock;
 
        spin_lock_irqsave(&rds_tcp_tc_list_lock, flags);
 
@@ -237,12 +238,17 @@ static void rds_tcp_tc_info(struct socket *sock, unsigned int len,
 
        list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) {
 
-               sock->ops->getname(sock, (struct sockaddr *)&sin, &sinlen, 0);
-               tsinfo.local_addr = sin.sin_addr.s_addr;
-               tsinfo.local_port = sin.sin_port;
-               sock->ops->getname(sock, (struct sockaddr *)&sin, &sinlen, 1);
-               tsinfo.peer_addr = sin.sin_addr.s_addr;
-               tsinfo.peer_port = sin.sin_port;
+               sock = tc->t_sock;
+               if (sock) {
+                       sock->ops->getname(sock, (struct sockaddr *)&sin,
+                                          &sinlen, 0);
+                       tsinfo.local_addr = sin.sin_addr.s_addr;
+                       tsinfo.local_port = sin.sin_port;
+                       sock->ops->getname(sock, (struct sockaddr *)&sin,
+                                          &sinlen, 1);
+                       tsinfo.peer_addr = sin.sin_addr.s_addr;
+                       tsinfo.peer_port = sin.sin_port;
+               }
 
                tsinfo.hdr_rem = tc->t_tinc_hdr_rem;
                tsinfo.data_rem = tc->t_tinc_data_rem;