1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-22 07:20:00 +00:00

inpcb: fully retire inp_ppcb pointer

Before a protocol specific control block started to embed inpcb in self
(see 0aa120d52f, e68b379244, 483fe96511) this pointer used to point
at it.

Retain kf_sock_inpcb field in the struct kinfo_file in <sys/user.h>.  The
exp-run detected a minimal use of the field in ports:
  * sysutils/lsof - patched upstream
  * net-mgmt/netdata  - patch accepted upstream
  * emulators/qemu-user-static - upstream master branch seems not using
    the field anymore
We can keep the field around for some time, but eventually it may be
reused for something else.

PR:			277659 (exp-run)
Reviewed by:		tuexen
Differential Revision:	https://reviews.freebsd.org/D44491
This commit is contained in:
Gleb Smirnoff 2024-03-29 12:16:59 -07:00
parent de2a4e80d7
commit 1a8d176432
10 changed files with 30 additions and 80 deletions

View File

@ -83,8 +83,6 @@
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#define _WANT_INPCB
#include <netinet/in_pcb.h>
#include <assert.h>
#include <ctype.h>
@ -1473,7 +1471,6 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
struct sockstat *sock, char *errbuf)
{
struct domain dom;
struct inpcb inpcb;
struct protosw proto;
struct socket s;
struct unpcb unpcb;
@ -1522,28 +1519,15 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
sock->proto = proto.pr_protocol;
sock->dom_family = dom.dom_family;
sock->so_pcb = (uintptr_t)s.so_pcb;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
sock->so_rcv_sb_state = s.so_rcv.sb_state;
sock->so_snd_sb_state = s.so_snd.sb_state;
/*
* Protocol specific data.
*/
switch (dom.dom_family) {
case AF_INET:
case AF_INET6:
if (proto.pr_protocol == IPPROTO_TCP) {
if (s.so_pcb) {
if (kvm_read(kd, (u_long)s.so_pcb,
(char *)&inpcb, sizeof(struct inpcb))
!= sizeof(struct inpcb)) {
warnx("can't read inpcb at %p",
(void *)s.so_pcb);
} else
sock->inp_ppcb =
(uintptr_t)inpcb.inp_ppcb;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
}
}
break;
case AF_UNIX:
if (s.so_pcb) {
if (kvm_read(kd, (u_long)s.so_pcb, (char *)&unpcb,
@ -1551,11 +1535,7 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
warnx("can't read unpcb at %p",
(void *)s.so_pcb);
} else if (unpcb.unp_conn) {
sock->so_rcv_sb_state = s.so_rcv.sb_state;
sock->so_snd_sb_state = s.so_snd.sb_state;
sock->unp_conn = (uintptr_t)unpcb.unp_conn;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
}
}
break;
@ -1603,7 +1583,6 @@ procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock,
case AF_INET:
case AF_INET6:
if (sock->proto == IPPROTO_TCP) {
sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb;
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
}

View File

@ -154,7 +154,6 @@ struct shmstat {
uint16_t mode;
};
struct sockstat {
uint64_t inp_ppcb;
uint64_t so_addr;
uint64_t so_pcb;
uint64_t unp_conn;

View File

@ -182,7 +182,7 @@ freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *f
r = procstat_get_socket_info(procstat, fst, &sock, errbuf);
if (r != 0)
return (r);
sock_compat->inp_ppcb = sock.inp_ppcb;
sock_compat->inp_ppcb = sock.so_pcb;
sock_compat->so_addr = sock.so_addr;
sock_compat->so_pcb = sock.so_pcb;
sock_compat->unp_conn = sock.unp_conn;

View File

@ -357,7 +357,6 @@ static int
soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
{
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
struct inpcb *inpcb;
struct unpcb *unpcb;
struct socket *so;
int error;
@ -373,11 +372,8 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
switch (kif->kf_un.kf_sock.kf_sock_domain0) {
case AF_INET:
case AF_INET6:
if (so->so_pcb != NULL) {
inpcb = (struct inpcb *)(so->so_pcb);
kif->kf_un.kf_sock.kf_sock_inpcb =
(uintptr_t)inpcb->inp_ppcb;
}
/* XXX: kf_sock_inpcb is obsolete. It may be removed. */
kif->kf_un.kf_sock.kf_sock_inpcb = (uintptr_t)so->so_pcb;
kif->kf_un.kf_sock.kf_sock_rcv_sb_state =
so->so_rcv.sb_state;
kif->kf_un.kf_sock.kf_sock_snd_sb_state =

View File

@ -1805,10 +1805,6 @@ in_pcbdrop(struct inpcb *inp)
{
INP_WLOCK_ASSERT(inp);
#ifdef INVARIANTS
if (inp->inp_socket != NULL && inp->inp_ppcb != NULL)
MPASS(inp->inp_refcount > 1);
#endif
inp->inp_flags |= INP_DROPPED;
if (inp->inp_flags & INP_INHASHLIST)
@ -2865,7 +2861,6 @@ in_pcbtoxinpcb(const struct inpcb *inp, struct xinpcb *xi)
sotoxsocket(inp->inp_socket, &xi->xi_socket);
bcopy(&inp->inp_inc, &xi->inp_inc, sizeof(struct in_conninfo));
xi->inp_gencnt = inp->inp_gencnt;
xi->inp_ppcb = (uintptr_t)inp->inp_ppcb;
xi->inp_flow = inp->inp_flow;
xi->inp_flowid = inp->inp_flowid;
xi->inp_flowtype = inp->inp_flowtype;
@ -3150,10 +3145,6 @@ db_print_inpcb(struct inpcb *inp, const char *name, int indent)
db_print_inconninfo(&inp->inp_inc, "inp_conninfo", indent);
db_print_indent(indent);
db_printf("inp_ppcb: %p inp_pcbinfo: %p inp_socket: %p\n",
inp->inp_ppcb, inp->inp_pcbinfo, inp->inp_socket);
db_print_indent(indent);
db_printf("inp_label: %p inp_flags: 0x%x (",
inp->inp_label, inp->inp_flags);

View File

@ -133,8 +133,9 @@ struct in_conninfo {
/*
* struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and
* IPv6 sockets. In the case of TCP and UDP, further per-connection state is
* hung off of inp_ppcb most of the time. Almost all fields of struct inpcb
* are static after creation or protected by a per-inpcb rwlock, inp_lock.
* located in a larger protocol specific structure that embeds inpcb in it.
* Almost all fields of struct inpcb are static after creation or protected by
* a per-inpcb rwlock, inp_lock.
*
* A inpcb database is indexed by addresses/ports hash as well as list of
* all pcbs that belong to a certain proto. Database lookups or list traversals
@ -177,7 +178,6 @@ struct inpcb {
int inp_flags; /* (i) generic IP/datagram flags */
int inp_flags2; /* (i) generic IP/datagram flags #2*/
uint8_t inp_numa_domain; /* numa domain */
void *inp_ppcb; /* (i) pointer to per-protocol pcb */
struct socket *inp_socket; /* (i) back pointer to socket */
struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */
struct ucred *inp_cred; /* (c) cache of socket cred */
@ -266,8 +266,7 @@ struct xinpcb {
struct xsocket xi_socket; /* (s,p) */
struct in_conninfo inp_inc; /* (s,p) */
uint64_t inp_gencnt; /* (s,p) */
kvaddr_t inp_ppcb; /* (s) netstat(1) */
int64_t inp_spare64[4];
int64_t inp_spare64[5];
uint32_t inp_flow; /* (s) */
uint32_t inp_flowid; /* (s) */
uint32_t inp_flowtype; /* (s) */

View File

@ -3980,13 +3980,6 @@ tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
xt->xt_len = sizeof(struct xtcpcb);
in_pcbtoxinpcb(inp, &xt->xt_inp);
/*
* TCP doesn't use inp_ppcb pointer, we embed inpcb into tcpcb.
* Fixup the pointer that in_pcbtoxinpcb() has set. When printing
* TCP netstat(1) used to use this pointer, so this fixup needs to
* stay for stable/14.
*/
xt->xt_inp.inp_ppcb = (uintptr_t)tp;
}
void

View File

@ -371,7 +371,7 @@ struct kinfo_file {
struct sockaddr_storage kf_sa_peer;
/* Address of so_pcb. */
uint64_t kf_sock_pcb;
/* Address of inp_ppcb. */
/* Obsolete! May be reused as a spare. */
uint64_t kf_sock_inpcb;
/* Address of unp_conn. */
uint64_t kf_sock_unpconn;

View File

@ -400,11 +400,10 @@ print_socket_info(struct procstat *procstat, struct filestat *fst)
/*
* protocol specific formatting
*
* Try to find interesting things to print. For tcp, the interesting
* thing is the address of the tcpcb, for udp and others, just the
* inpcb (socket pcb). For unix domain, its the address of the socket
* pcb and the address of the connected pcb (if connected). Otherwise
* just print the protocol number and address of the socket itself.
* Try to find interesting things to print. For internet and unix
* sockets, its the address of the socket pcb. For unix it is also the
* address of the connected pcb (if connected). Otherwise just print
* the protocol number and address of the socket itself.
* The idea is not to duplicate netstat, but to make available enough
* information for further analysis.
*/
@ -417,11 +416,7 @@ print_socket_info(struct procstat *procstat, struct filestat *fst)
printf(" %s", pe->p_name);
else
printf(" %d", sock.proto);
if (sock.proto == IPPROTO_TCP ) {
if (sock.inp_ppcb != 0)
printf(" %lx", (u_long)sock.inp_ppcb);
}
else if (sock.so_pcb != 0)
if (sock.so_pcb != 0)
printf(" %lx", (u_long)sock.so_pcb);
if (!sflg)
break;

View File

@ -168,12 +168,11 @@ fetchnetstat(void)
static void
fetchnetstat_kvm(void)
{
struct inpcb *next;
struct netinfo *p;
struct inpcbhead head;
struct inpcb inpcb;
struct socket sockb;
struct tcpcb tcpcb;
struct inpcb *inpcb;
void *off;
int istcp;
@ -195,32 +194,31 @@ fetchnetstat_kvm(void)
}
again:
KREAD(off, &head, sizeof (struct inpcbhead));
LIST_FOREACH(next, &head, inp_list) {
KREAD(next, &inpcb, sizeof (inpcb));
next = &inpcb;
LIST_FOREACH(inpcb, &head, inp_list) {
KREAD(inpcb, &tcpcb, istcp ? sizeof(tcpcb) : sizeof(inpcb));
inpcb = (struct inpcb *)&tcpcb;
if (!aflag) {
if (inpcb.inp_vflag & INP_IPV4) {
if (inpcb.inp_laddr.s_addr == INADDR_ANY)
if (inpcb->inp_vflag & INP_IPV4) {
if (inpcb->inp_laddr.s_addr == INADDR_ANY)
continue;
}
#ifdef INET6
else if (inpcb.inp_vflag & INP_IPV6) {
if (memcmp(&inpcb.in6p_laddr,
else if (inpcb->inp_vflag & INP_IPV6) {
if (memcmp(&inpcb->in6p_laddr,
&in6addr_any, sizeof(in6addr_any)) == 0)
continue;
}
#endif
}
if (nhosts && !checkhost(&inpcb.inp_inc))
if (nhosts && !checkhost(&inpcb->inp_inc))
continue;
if (nports && !checkport(&inpcb.inp_inc))
if (nports && !checkport(&inpcb->inp_inc))
continue;
if (istcp) {
KREAD(inpcb.inp_socket, &sockb, sizeof (sockb));
KREAD(inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb));
enter_kvm(&inpcb, &sockb, tcpcb.t_state, "tcp");
KREAD(inpcb->inp_socket, &sockb, sizeof (sockb));
enter_kvm(inpcb, &sockb, tcpcb.t_state, "tcp");
} else
enter_kvm(&inpcb, &sockb, 0, "udp");
enter_kvm(inpcb, &sockb, 0, "udp");
}
if (istcp && (protos&UDP)) {
istcp = 0;