From 49f689eda0bc3331beb70df17ac4990034460f2b Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Thu, 9 Feb 2023 20:15:46 +0800 Subject: [PATCH 73/89] Fix for "net -s" option to show IPv6 addresses on Linux 3.13 and later Currently, the "net -s" option fails to show IPv6 addresses and ports for the SOURCE-PORT and DESTINATION-PORT columns on Linux 3.13 and later kernels, which have kernel commit efe4208f47f907 ("ipv6: make lookups simpler and faster"). For example: crash> net -s PID: 305524 TASK: ffff9bc449895580 CPU: 6 COMMAND: "sshd" FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT 3 ffff9bc446e9a680 ffff9bc4455b5940 UNIX:DGRAM 4 ffff9bc446e9c600 ffff9bc3b2b24e00 INET6:STREAM With the patch: crash> net -s PID: 305524 TASK: ffff9bc449895580 CPU: 6 COMMAND: "sshd" FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT 3 ffff9bc446e9a680 ffff9bc4455b5940 UNIX:DGRAM 4 ffff9bc446e9c600 ffff9bc3b2b24e00 INET6:STREAM xxxx:xx:x:xxxx:xxxx:xxxx:xxxx:xxxx-22 yyyy:yy:y:yyyy:yyyy:yyyy:yyyy:yyyy-44870 Reported-by: Buland Kumar Singh Signed-off-by: Lianbo Jiang Signed-off-by: Kazuhito Hagio --- defs.h | 3 +++ net.c | 20 +++++++++++++++----- symbols.c | 3 +++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/defs.h b/defs.h index ae5d1244e8b3..801781749666 100644 --- a/defs.h +++ b/defs.h @@ -2204,6 +2204,9 @@ struct offset_table { /* stash of commonly-used offsets */ long maple_range_64_slot; long maple_metadata_end; long maple_metadata_gap; + long sock_sk_common; + long sock_common_skc_v6_daddr; + long sock_common_skc_v6_rcv_saddr; }; struct size_table { /* stash of commonly-used sizes */ diff --git a/net.c b/net.c index 7c9c8bd9c98d..aa445ab7ee13 100644 --- a/net.c +++ b/net.c @@ -199,6 +199,9 @@ net_init(void) MEMBER_OFFSET_INIT(sock_common_skc_family, "sock_common", "skc_family"); MEMBER_OFFSET_INIT(sock_sk_type, "sock", "sk_type"); + MEMBER_OFFSET_INIT(sock_sk_common, "sock", "__sk_common"); + MEMBER_OFFSET_INIT(sock_common_skc_v6_daddr, "sock_common", "skc_v6_daddr"); + MEMBER_OFFSET_INIT(sock_common_skc_v6_rcv_saddr, "sock_common", "skc_v6_rcv_saddr"); /* * struct inet_sock { * struct sock sk; @@ -1104,12 +1107,19 @@ get_sock_info(ulong sock, char *buf) break; case SOCK_V2: - if (INVALID_MEMBER(ipv6_pinfo_rcv_saddr) || - INVALID_MEMBER(ipv6_pinfo_daddr)) + if (VALID_MEMBER(ipv6_pinfo_rcv_saddr) && + VALID_MEMBER(ipv6_pinfo_daddr)) { + ipv6_rcv_saddr = ipv6_pinfo + OFFSET(ipv6_pinfo_rcv_saddr); + ipv6_daddr = ipv6_pinfo + OFFSET(ipv6_pinfo_daddr); + } else if (VALID_MEMBER(sock_sk_common) && + VALID_MEMBER(sock_common_skc_v6_daddr) && + VALID_MEMBER(sock_common_skc_v6_rcv_saddr)) { + ipv6_rcv_saddr = sock + OFFSET(sock_sk_common) + OFFSET(sock_common_skc_v6_rcv_saddr); + ipv6_daddr = sock + OFFSET(sock_sk_common) + OFFSET(sock_common_skc_v6_daddr); + } else { + sprintf(&buf[strlen(buf)], "%s", "(cannot get IPv6 addresses)"); break; - - ipv6_rcv_saddr = ipv6_pinfo + OFFSET(ipv6_pinfo_rcv_saddr); - ipv6_daddr = ipv6_pinfo + OFFSET(ipv6_pinfo_daddr); + } if (!readmem(ipv6_rcv_saddr, KVADDR, u6_addr16_src, SIZE(in6_addr), "ipv6_rcv_saddr buffer", QUIET|RETURN_ON_ERROR)) diff --git a/symbols.c b/symbols.c index 20bfac35c1f6..54115d753601 100644 --- a/symbols.c +++ b/symbols.c @@ -9830,8 +9830,11 @@ dump_offset_table(char *spec, ulong makestruct) fprintf(fp, " sock_sk_type: %ld\n", OFFSET(sock_sk_type)); + fprintf(fp, " sock_sk_common: %ld\n", OFFSET(sock_sk_common)); fprintf(fp, " sock_common_skc_family: %ld\n", OFFSET(sock_common_skc_family)); + fprintf(fp, " sock_common_skc_v6_daddr: %ld\n", OFFSET(sock_common_skc_v6_daddr)); + fprintf(fp, " sock_common_skc_v6_rcv_saddr: %ld\n", OFFSET(sock_common_skc_v6_rcv_saddr)); fprintf(fp, " socket_alloc_vfs_inode: %ld\n", OFFSET(socket_alloc_vfs_inode)); fprintf(fp, " inet_sock_inet: %ld\n", -- 2.37.1