From nobody Wed Aug 17 18:52:27 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4M7HFR5ZFHz4YxwS; Wed, 17 Aug 2022 18:52:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4M7HFR5Knyz4CyT; Wed, 17 Aug 2022 18:52:27 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660762347; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lXsfmJycnue/70mRpm3lbgNBCOrbg/yLIaX00KsCd3M=; b=IyhoozXSupKx99FPRn1ItvARZIB/imOxtHBJY0h90UL7wIlZM3GDcJvwXqtZ1J59/0Dmxt WDNjFb/0GKP9GgQHknTVWXvHM6MXizD1LU6U8jU5AHgr7Fl4WA8mYqkD0ZNEIqbOmMrcby 496dvuguSkxzBYPGn701Z4zeDPjOi732dk6UOMqqZZbiGMs0sZQBbmXlpKyfw7qJvzokcS ZFwt08U1iayywCZikP1p9iERqw13v1SVaSrLzd8lJ3NwaNaQStinVbzvqGXZDq+FymR2oj kTJTkTwENJoIljQk0/oRNmj79boM1u1kw11Mp0uZrcyWQR6yASapot06W1IOOA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4M7HFR4N0Bz11GF; Wed, 17 Aug 2022 18:52:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 27HIqRee013246; Wed, 17 Aug 2022 18:52:27 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27HIqRL6013245; Wed, 17 Aug 2022 18:52:27 GMT (envelope-from git) Date: Wed, 17 Aug 2022 18:52:27 GMT Message-Id: <202208171852.27HIqRL6013245@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: e7d02be19d40 - main - protosw: refactor protosw and domain static declaration and load List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e7d02be19d40063783d6b8f1ff2bc4c7170fd434 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660762347; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lXsfmJycnue/70mRpm3lbgNBCOrbg/yLIaX00KsCd3M=; b=DNW61N+YgSg7DSUIHeFq+Z5UhVJWg2F9sLrkNk+RjAFQ6cV4hQwWqTwO1guOB5DnW1GBSu 3/oP7e/RnnWCxWtdUbz9Ouf9707q/L2INOnqOp2MOaZVC5RrTCVs6iVdagtaBJ8iTfCT7O rc/j+ymSiG4UT3i1uDWBNXDMjD3r45NXVkxN5EtZkg0jJaDcAbxRwnVF8q7ri/h1hw5q00 Wd1RReLUlB5YtmMDKMXT9aP2SiIAa2BlJxRbPvC9w23zBMsqyf7/3J2wEuinHjqUHWykps TuHYxjEeY4nkfa5hjLeFn8shgdHPYUuqbVOInf0Og15PnAVYzuFPiT53bGhxxg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1660762347; a=rsa-sha256; cv=none; b=ufpjEFnqfH+ktrxp/Ctl8IlNY5g1GcW300AvJHn5EI2DrABs4ZPldFlhpEBggxGJphg8mJ 59JqnVqli8YdA9RLRSpnV+sokjXK40mHD9hYtlYc/gIIQAU8Z1A3lQVa+/E53BWulRxIfp q0yYCmuX8+nhi3/e/xadyGrh3Jc7kzwOrUmZFYx3PfeTn4m8dR15UsRZIzaISKaT9tP8T4 niOr4kYSYD9A/x4TFw8byqJFoSKPIgcSPpipygdxJPL5sus9vYoEYiNPamg8gmcutXlOZw N2LmCgOtvvHmNuBufLGqNvj3alYXWUk9AOf++EloqZ61JPvavgjMEw1LeFiWKA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=e7d02be19d40063783d6b8f1ff2bc4c7170fd434 commit e7d02be19d40063783d6b8f1ff2bc4c7170fd434 Author: Gleb Smirnoff AuthorDate: 2022-08-17 18:50:32 +0000 Commit: Gleb Smirnoff CommitDate: 2022-08-17 18:50:32 +0000 protosw: refactor protosw and domain static declaration and load o Assert that every protosw has pr_attach. Now this structure is only for socket protocols declarations and nothing else. o Merge struct pr_usrreqs into struct protosw. This was suggested in 1996 by wollman@ (see 7b187005d18ef), and later reiterated in 2006 by rwatson@ (see 6fbb9cf860dcd). o Make struct domain hold a variable sized array of protosw pointers. For most protocols these pointers are initialized statically. Those domains that may have loadable protocols have spacers. IPv4 and IPv6 have 8 spacers each (andre@ dff3237ee54ea). o For inetsw and inet6sw leave a comment noting that many protosw entries very likely are dead code. o Refactor pf_proto_[un]register() into protosw_[un]register(). o Isolate pr_*_notsupp() methods into uipc_domain.c Reviewed by: melifaro Differential revision: https://reviews.freebsd.org/D36232 --- sys/compat/linuxkpi/common/include/linux/net.h | 4 +- sys/dev/cxgbe/tom/t4_tom.c | 29 +- sys/dev/hyperv/hvsock/hv_sock.c | 47 +-- sys/kern/kern_sendfile.c | 17 +- sys/kern/sys_socket.c | 11 +- sys/kern/uipc_domain.c | 376 ++++++++++++--------- sys/kern/uipc_ktls.c | 12 +- sys/kern/uipc_socket.c | 260 +++----------- sys/kern/uipc_syscalls.c | 4 +- sys/kern/uipc_usrreq.c | 223 ++++++------ sys/net/if.c | 3 +- sys/net/if_ovpn.c | 2 +- sys/net/rtsock.c | 25 +- sys/netgraph/bluetooth/socket/ng_btsocket.c | 210 +++++------- sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c | 4 +- sys/netgraph/ng_ksocket.c | 4 +- sys/netgraph/ng_socket.c | 59 ++-- sys/netinet/in_proto.c | 202 +++-------- sys/netinet/ip_divert.c | 28 +- sys/netinet/ip_output.c | 1 - sys/netinet/ip_var.h | 1 - sys/netinet/raw_ip.c | 81 ++++- sys/netinet/sctp_module.c | 60 +--- sys/netinet/sctp_usrreq.c | 51 +-- sys/netinet/sctp_var.h | 2 +- sys/netinet/tcp_subr.c | 4 +- sys/netinet/tcp_usrreq.c | 86 ++--- sys/netinet/tcp_var.h | 3 +- sys/netinet/udp_usrreq.c | 44 ++- sys/netinet/udp_var.h | 1 - sys/netinet6/in6_proto.c | 202 +++-------- sys/netinet6/raw_ip6.c | 75 +++- sys/netinet6/sctp6_usrreq.c | 50 +-- sys/netinet6/sctp6_var.h | 2 +- sys/netinet6/send.c | 15 +- sys/netinet6/udp6_usrreq.c | 44 ++- sys/netipsec/keysock.c | 34 +- sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c | 74 ++-- sys/rpc/rpc_generic.c | 6 +- sys/rpc/svc_dg.c | 2 +- sys/rpc/svc_vc.c | 6 +- sys/security/mac/mac_socket.c | 4 +- sys/sys/domain.h | 3 +- sys/sys/protosw.h | 136 +++----- 44 files changed, 1042 insertions(+), 1465 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/net.h b/sys/compat/linuxkpi/common/include/linux/net.h index 5438fccb8512..d5752093da74 100644 --- a/sys/compat/linuxkpi/common/include/linux/net.h +++ b/sys/compat/linuxkpi/common/include/linux/net.h @@ -58,9 +58,9 @@ sock_getname(struct socket *so, struct sockaddr *addr, int *sockaddr_len, if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) return (-ENOTCONN); - error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &nam); + error = so->so_proto->pr_peeraddr(so, &nam); } else - error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &nam); + error = so->so_proto->pr_sockaddr(so, &nam); if (error) return (-error); *addr = *nam; diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index 9bd6145c9acc..825a4e96ce81 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -80,13 +80,8 @@ __FBSDID("$FreeBSD$"); #include "tom/t4_tom.h" #include "tom/t4_tls.h" -static struct protosw *tcp_protosw; static struct protosw toe_protosw; -static struct pr_usrreqs toe_usrreqs; - -static struct protosw *tcp6_protosw; static struct protosw toe6_protosw; -static struct pr_usrreqs toe6_usrreqs; /* Module ops */ static int t4_tom_mod_load(void); @@ -269,9 +264,9 @@ void restore_so_proto(struct socket *so, bool v6) { if (v6) - so->so_proto = tcp6_protosw; + so->so_proto = &tcp6_protosw; else - so->so_proto = tcp_protosw; + so->so_proto = &tcp_protosw; } /* This is _not_ the normal way to "unoffload" a socket. */ @@ -2024,21 +2019,11 @@ t4_tom_mod_load(void) t4_ddp_mod_load(); t4_tls_mod_load(); - tcp_protosw = pffindproto(PF_INET, IPPROTO_TCP, SOCK_STREAM); - if (tcp_protosw == NULL) - return (ENOPROTOOPT); - bcopy(tcp_protosw, &toe_protosw, sizeof(toe_protosw)); - bcopy(tcp_protosw->pr_usrreqs, &toe_usrreqs, sizeof(toe_usrreqs)); - toe_usrreqs.pru_aio_queue = t4_aio_queue_tom; - toe_protosw.pr_usrreqs = &toe_usrreqs; - - tcp6_protosw = pffindproto(PF_INET6, IPPROTO_TCP, SOCK_STREAM); - if (tcp6_protosw == NULL) - return (ENOPROTOOPT); - bcopy(tcp6_protosw, &toe6_protosw, sizeof(toe6_protosw)); - bcopy(tcp6_protosw->pr_usrreqs, &toe6_usrreqs, sizeof(toe6_usrreqs)); - toe6_usrreqs.pru_aio_queue = t4_aio_queue_tom; - toe6_protosw.pr_usrreqs = &toe6_usrreqs; + bcopy(&tcp_protosw, &toe_protosw, sizeof(toe_protosw)); + toe_protosw.pr_aio_queue = t4_aio_queue_tom; + + bcopy(&tcp6_protosw, &toe6_protosw, sizeof(toe6_protosw)); + toe6_protosw.pr_aio_queue = t4_aio_queue_tom; return (t4_register_uld(&tom_uld_info)); } diff --git a/sys/dev/hyperv/hvsock/hv_sock.c b/sys/dev/hyperv/hvsock/hv_sock.c index 8c327a22e6fd..f728383a1b6f 100644 --- a/sys/dev/hyperv/hvsock/hv_sock.c +++ b/sys/dev/hyperv/hvsock/hv_sock.c @@ -86,48 +86,35 @@ static int hvs_dom_probe(void); roundup2(payload_len, 8) + \ sizeof(uint64_t)) - -static struct domain hv_socket_domain; - /* * HyperV Transport sockets */ -static struct pr_usrreqs hvs_trans_usrreqs = { - .pru_attach = hvs_trans_attach, - .pru_bind = hvs_trans_bind, - .pru_listen = hvs_trans_listen, - .pru_accept = hvs_trans_accept, - .pru_connect = hvs_trans_connect, - .pru_peeraddr = hvs_trans_peeraddr, - .pru_sockaddr = hvs_trans_sockaddr, - .pru_soreceive = hvs_trans_soreceive, - .pru_sosend = hvs_trans_sosend, - .pru_disconnect = hvs_trans_disconnect, - .pru_close = hvs_trans_close, - .pru_detach = hvs_trans_detach, - .pru_shutdown = hvs_trans_shutdown, - .pru_abort = hvs_trans_abort, -}; - -/* - * Definitions of protocols supported in HyperV socket domain - */ -static struct protosw hv_socket_protosw[] = { -{ +static struct protosw hv_socket_protosw = { .pr_type = SOCK_STREAM, - .pr_domain = &hv_socket_domain, .pr_protocol = HYPERV_SOCK_PROTO_TRANS, .pr_flags = PR_CONNREQUIRED, - .pr_usrreqs = &hvs_trans_usrreqs, -}, + .pr_attach = hvs_trans_attach, + .pr_bind = hvs_trans_bind, + .pr_listen = hvs_trans_listen, + .pr_accept = hvs_trans_accept, + .pr_connect = hvs_trans_connect, + .pr_peeraddr = hvs_trans_peeraddr, + .pr_sockaddr = hvs_trans_sockaddr, + .pr_soreceive = hvs_trans_soreceive, + .pr_sosend = hvs_trans_sosend, + .pr_disconnect = hvs_trans_disconnect, + .pr_close = hvs_trans_close, + .pr_detach = hvs_trans_detach, + .pr_shutdown = hvs_trans_shutdown, + .pr_abort = hvs_trans_abort, }; static struct domain hv_socket_domain = { .dom_family = AF_HYPERV, .dom_name = "hyperv", .dom_probe = hvs_dom_probe, - .dom_protosw = hv_socket_protosw, - .dom_protoswNPROTOSW = &hv_socket_protosw[nitems(hv_socket_protosw)] + .dom_nprotosw = 1, + .dom_protosw = { &hv_socket_protosw }, }; DOMAIN_SET(hv_socket_); diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c index 2de015254ab9..f444e38e153d 100644 --- a/sys/kern/kern_sendfile.c +++ b/sys/kern/kern_sendfile.c @@ -377,7 +377,7 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error) * for read, so that application receives EIO on next * syscall and eventually closes the socket. */ - so->so_proto->pr_usrreqs->pru_abort(so); + so->so_proto->pr_abort(so); so->so_error = EIO; mb_free_notready(sfio->m, sfio->npages); @@ -396,8 +396,7 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error) goto out_with_ref; #endif } else - (void)(so->so_proto->pr_usrreqs->pru_ready)(so, sfio->m, - sfio->npages); + (void)so->so_proto->pr_ready(so, sfio->m, sfio->npages); sorele(so); #ifdef KERN_TLS @@ -1172,8 +1171,8 @@ prepend_header: sendfile_iodone(sfio, NULL, 0, 0); #ifdef KERN_TLS if (tls != NULL && tls->mode == TCP_TLS_MODE_SW) { - error = (*so->so_proto->pr_usrreqs->pru_send) - (so, PRUS_NOTREADY, m, NULL, NULL, td); + error = so->so_proto->pr_send(so, + PRUS_NOTREADY, m, NULL, NULL, td); if (error != 0) { m_freem(m); } else { @@ -1182,14 +1181,14 @@ prepend_header: } } else #endif - error = (*so->so_proto->pr_usrreqs->pru_send) - (so, 0, m, NULL, NULL, td); + error = so->so_proto->pr_send(so, 0, m, NULL, + NULL, td); } else { sfio->so = so; sfio->m = m0; soref(so); - error = (*so->so_proto->pr_usrreqs->pru_send) - (so, PRUS_NOTREADY, m, NULL, NULL, td); + error = so->so_proto->pr_send(so, PRUS_NOTREADY, m, + NULL, NULL, td); sendfile_iodone(sfio, NULL, 0, error); } CURVNET_RESTORE(); diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 7f39e58f4ce4..5b8aadc12e08 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -276,8 +276,7 @@ soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, CURVNET_RESTORE(); } else { CURVNET_SET(so->so_vnet); - error = ((*so->so_proto->pr_usrreqs->pru_control) - (so, cmd, data, 0, td)); + error = so->so_proto->pr_control(so, cmd, data, 0, td); CURVNET_RESTORE(); } break; @@ -336,7 +335,7 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred) } ub->st_uid = so->so_cred->cr_uid; ub->st_gid = so->so_cred->cr_gid; - error = so->so_proto->pr_usrreqs->pru_sense(so, ub); + error = so->so_proto->pr_sense(so, ub); SOCK_UNLOCK(so); return (error); } @@ -414,13 +413,13 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) } break; } - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); if (error == 0 && sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) { bcopy(sa, &kif->kf_un.kf_sock.kf_sa_local, sa->sa_len); free(sa, M_SONAME); } - error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa); + error = so->so_proto->pr_peeraddr(so, &sa); if (error == 0 && sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) { bcopy(sa, &kif->kf_un.kf_sock.kf_sa_peer, sa->sa_len); @@ -812,7 +811,7 @@ soo_aio_queue(struct file *fp, struct kaiocb *job) int error; so = fp->f_data; - error = (*so->so_proto->pr_usrreqs->pru_aio_queue)(so, job); + error = so->so_proto->pr_aio_queue(so, job); if (error == 0) return (0); diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index c6a79d34beb2..d2b8d9095f13 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include /* XXXGL: remove */ #include @@ -76,85 +77,182 @@ int domain_init_status = 0; static struct mtx dom_mtx; /* domain list lock */ MTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF); +static int +pr_accept_notsupp(struct socket *so, struct sockaddr **nam) +{ + return (EOPNOTSUPP); +} + +static int +pr_aio_queue_notsupp(struct socket *so, struct kaiocb *job) +{ + return (EOPNOTSUPP); +} + +static int +pr_bind_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td) +{ + return (EOPNOTSUPP); +} + +static int +pr_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam, + struct thread *td) +{ + return (EOPNOTSUPP); +} + +static int +pr_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td) +{ + return (EOPNOTSUPP); +} + +static int +pr_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam, + struct thread *td) +{ + return (EOPNOTSUPP); +} + +static int +pr_connect2_notsupp(struct socket *so1, struct socket *so2) +{ + return (EOPNOTSUPP); +} + +static int +pr_control_notsupp(struct socket *so, u_long cmd, void *data, + struct ifnet *ifp, struct thread *td) +{ + return (EOPNOTSUPP); +} + +static int +pr_disconnect_notsupp(struct socket *so) +{ + return (EOPNOTSUPP); +} + +static int +pr_listen_notsupp(struct socket *so, int backlog, struct thread *td) +{ + return (EOPNOTSUPP); +} + +static int +pr_peeraddr_notsupp(struct socket *so, struct sockaddr **nam) +{ + return (EOPNOTSUPP); +} + +static int +pr_rcvd_notsupp(struct socket *so, int flags) +{ + return (EOPNOTSUPP); +} + +static int +pr_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags) +{ + return (EOPNOTSUPP); +} + +static int +pr_send_notsupp(struct socket *so, int flags, struct mbuf *m, + struct sockaddr *addr, struct mbuf *control, struct thread *td) +{ + if (control != NULL) + m_freem(control); + if ((flags & PRUS_NOTREADY) == 0) + m_freem(m); + return (EOPNOTSUPP); +} + +static int +pr_ready_notsupp(struct socket *so, struct mbuf *m, int count) +{ + return (EOPNOTSUPP); +} + /* - * Dummy protocol specific user requests function pointer array. - * All functions return EOPNOTSUPP. + * This isn't really a ``null'' operation, but it's the default one and + * doesn't do anything destructive. */ -struct pr_usrreqs nousrreqs = { - .pru_accept = pru_accept_notsupp, - .pru_attach = pru_attach_notsupp, - .pru_bind = pru_bind_notsupp, - .pru_connect = pru_connect_notsupp, - .pru_connect2 = pru_connect2_notsupp, - .pru_control = pru_control_notsupp, - .pru_disconnect = pru_disconnect_notsupp, - .pru_listen = pru_listen_notsupp, - .pru_peeraddr = pru_peeraddr_notsupp, - .pru_rcvd = pru_rcvd_notsupp, - .pru_rcvoob = pru_rcvoob_notsupp, - .pru_send = pru_send_notsupp, - .pru_sense = pru_sense_null, - .pru_shutdown = pru_shutdown_notsupp, - .pru_sockaddr = pru_sockaddr_notsupp, - .pru_sosend = pru_sosend_notsupp, - .pru_soreceive = pru_soreceive_notsupp, - .pru_sopoll = pru_sopoll_notsupp, -}; +static int +pr_sense_notsupp(struct socket *so, struct stat *sb) +{ + sb->st_blksize = so->so_snd.sb_hiwat; + return (0); +} -static void -pr_usrreqs_init(struct protosw *pr) +static int +pr_shutdown_notsupp(struct socket *so) { - struct pr_usrreqs *pu; + return (EOPNOTSUPP); +} - pu = pr->pr_usrreqs; - KASSERT(pu != NULL, ("%s: %ssw[%d] has no usrreqs!", __func__, - pr->pr_domain->dom_name, - (int)(pr - pr->pr_domain->dom_protosw))); +static int +pr_sockaddr_notsupp(struct socket *so, struct sockaddr **nam) +{ + return (EOPNOTSUPP); +} - /* - * Protocol switch methods fall into three categories: mandatory, - * mandatory but protosw_init() provides a default, and optional. - * - * For true protocols (i.e., pru_attach != NULL), KASSERT truly - * mandatory methods with no defaults, and initialize defaults for - * other mandatory methods if the protocol hasn't defined an - * implementation (NULL function pointer). - */ -#if 0 - if (pu->pru_attach != NULL) { - KASSERT(pu->pru_abort != NULL, - ("protosw_init: %ssw[%d] pru_abort NULL", - pr->pr_domain->dom_name, - (int)(pr - pr->pr_domain->dom_protosw))); - KASSERT(pu->pru_send != NULL, - ("protosw_init: %ssw[%d] pru_send NULL", - pr->pr_domain->dom_name, - (int)(pr - pr->pr_domain->dom_protosw))); - } -#endif +static int +pr_sosend_notsupp(struct socket *so, struct sockaddr *addr, struct uio *uio, + struct mbuf *top, struct mbuf *control, int flags, struct thread *td) +{ + return (EOPNOTSUPP); +} -#define DEFAULT(foo, bar) if ((foo) == NULL) (foo) = (bar) - DEFAULT(pu->pru_accept, pru_accept_notsupp); - DEFAULT(pu->pru_aio_queue, pru_aio_queue_notsupp); - DEFAULT(pu->pru_bind, pru_bind_notsupp); - DEFAULT(pu->pru_bindat, pru_bindat_notsupp); - DEFAULT(pu->pru_connect, pru_connect_notsupp); - DEFAULT(pu->pru_connect2, pru_connect2_notsupp); - DEFAULT(pu->pru_connectat, pru_connectat_notsupp); - DEFAULT(pu->pru_control, pru_control_notsupp); - DEFAULT(pu->pru_disconnect, pru_disconnect_notsupp); - DEFAULT(pu->pru_listen, pru_listen_notsupp); - DEFAULT(pu->pru_peeraddr, pru_peeraddr_notsupp); - DEFAULT(pu->pru_rcvd, pru_rcvd_notsupp); - DEFAULT(pu->pru_rcvoob, pru_rcvoob_notsupp); - DEFAULT(pu->pru_sense, pru_sense_null); - DEFAULT(pu->pru_shutdown, pru_shutdown_notsupp); - DEFAULT(pu->pru_sockaddr, pru_sockaddr_notsupp); - DEFAULT(pu->pru_sosend, sosend_generic); - DEFAULT(pu->pru_soreceive, soreceive_generic); - DEFAULT(pu->pru_sopoll, sopoll_generic); - DEFAULT(pu->pru_ready, pru_ready_notsupp); -#undef DEFAULT +static int +pr_soreceive_notsupp(struct socket *so, struct sockaddr **paddr, + struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp) +{ + return (EOPNOTSUPP); +} + +static int +pr_sopoll_notsupp(struct socket *so, int events, struct ucred *cred, + struct thread *td) +{ + return (EOPNOTSUPP); +} + +static void +pr_init(struct protosw *pr) +{ + + KASSERT(pr->pr_attach != NULL, + ("%s: protocol doesn't have pr_attach", __func__)); + +#define DEFAULT(foo, bar) if (pr->foo == NULL) pr->foo = bar + DEFAULT(pr_sosend, sosend_generic); + DEFAULT(pr_soreceive, soreceive_generic); + DEFAULT(pr_sopoll, sopoll_generic); + +#define NOTSUPP(foo) if (pr->foo == NULL) pr->foo = foo ## _notsupp + NOTSUPP(pr_accept); + NOTSUPP(pr_aio_queue); + NOTSUPP(pr_bind); + NOTSUPP(pr_bindat); + NOTSUPP(pr_connect); + NOTSUPP(pr_connect2); + NOTSUPP(pr_connectat); + NOTSUPP(pr_control); + NOTSUPP(pr_disconnect); + NOTSUPP(pr_listen); + NOTSUPP(pr_peeraddr); + NOTSUPP(pr_rcvd); + NOTSUPP(pr_rcvoob); + NOTSUPP(pr_send); + NOTSUPP(pr_sense); + NOTSUPP(pr_shutdown); + NOTSUPP(pr_sockaddr); + NOTSUPP(pr_sosend); + NOTSUPP(pr_soreceive); + NOTSUPP(pr_sopoll); + NOTSUPP(pr_ready); } /* @@ -176,9 +274,11 @@ domain_init(void *arg) return; MPASS((flags & DOMF_INITED) == 0); - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { - pr_usrreqs_init(pr); - } + for (int i = 0; i < dp->dom_nprotosw; i++) + if ((pr = dp->dom_protosw[i]) != NULL) { + pr->pr_domain = dp; + pr_init(pr); + } /* * update global information about maximums @@ -288,9 +388,10 @@ pffindtype(int family, int type) if (dp == NULL) return (NULL); - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) - if (pr->pr_type && pr->pr_type == type) + for (int i = 0; i < dp->dom_nprotosw; i++) + if ((pr = dp->dom_protosw[i]) != NULL && pr->pr_type == type) return (pr); + return (NULL); } @@ -301,18 +402,18 @@ pffindproto(int family, int protocol, int type) struct protosw *pr; struct protosw *maybe; - maybe = NULL; - if (family == 0) - return (NULL); - dp = pffinddomain(family); if (dp == NULL) return (NULL); - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { + maybe = NULL; + for (int i = 0; i < dp->dom_nprotosw; i++) { + if ((pr = dp->dom_protosw[i]) == NULL) + continue; if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) return (pr); + /* XXX: raw catches all. Why? */ if (type == SOCK_RAW && pr->pr_type == SOCK_RAW && pr->pr_protocol == 0 && maybe == NULL) maybe = pr; @@ -325,60 +426,49 @@ pffindproto(int family, int protocol, int type) * accept requests before it is registered. */ int -pf_proto_register(int family, struct protosw *npr) +protosw_register(struct domain *dp, struct protosw *npr) { - struct domain *dp; - struct protosw *pr, *fpr; - - /* Sanity checks. */ - if (family == 0) - return (EPFNOSUPPORT); - if (npr->pr_type == 0) - return (EPROTOTYPE); - if (npr->pr_protocol == 0) - return (EPROTONOSUPPORT); - if (npr->pr_usrreqs == NULL) - return (ENXIO); - - /* Try to find the specified domain based on the family. */ - dp = pffinddomain(family); - if (dp == NULL) - return (EPFNOSUPPORT); + struct protosw **prp; - /* Initialize backpointer to struct domain. */ - npr->pr_domain = dp; - fpr = NULL; + MPASS(dp); + MPASS(npr && npr->pr_type > 0 && npr->pr_protocol > 0); + prp = NULL; /* * Protect us against races when two protocol registrations for * the same protocol happen at the same time. */ mtx_lock(&dom_mtx); + for (int i = 0; i < dp->dom_nprotosw; i++) { + if (dp->dom_protosw[i] == NULL) { + /* Remember the first free spacer. */ + if (prp == NULL) + prp = &dp->dom_protosw[i]; + } else { + /* + * The new protocol must not yet exist. + * XXXAO: Check only protocol? + * XXXGL: Maybe assert that it doesn't exist? + */ + if ((dp->dom_protosw[i]->pr_type == npr->pr_type) && + (dp->dom_protosw[i]->pr_protocol == + npr->pr_protocol)) { + mtx_unlock(&dom_mtx); + return (EEXIST); + } - /* The new protocol must not yet exist. */ - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { - if ((pr->pr_type == npr->pr_type) && - (pr->pr_protocol == npr->pr_protocol)) { - mtx_unlock(&dom_mtx); - return (EEXIST); /* XXX: Check only protocol? */ } - /* While here, remember the first free spacer. */ - if ((fpr == NULL) && (pr->pr_protocol == PROTO_SPACER)) - fpr = pr; } /* If no free spacer is found we can't add the new protocol. */ - if (fpr == NULL) { + if (prp == NULL) { mtx_unlock(&dom_mtx); return (ENOMEM); } - /* Copy the new struct protosw over the spacer. */ - bcopy(npr, fpr, sizeof(*fpr)); - - pr_usrreqs_init(fpr); - - /* Job is done, no more protection required. */ + npr->pr_domain = dp; + pr_init(npr); + *prp = npr; mtx_unlock(&dom_mtx); return (0); @@ -389,55 +479,33 @@ pf_proto_register(int family, struct protosw *npr) * all sockets and release all locks and memory references. */ int -pf_proto_unregister(int family, int protocol, int type) +protosw_unregister(struct protosw *pr) { struct domain *dp; - struct protosw *pr, *dpr; + struct protosw **prp; - /* Sanity checks. */ - if (family == 0) - return (EPFNOSUPPORT); - if (protocol == 0) - return (EPROTONOSUPPORT); - if (type == 0) - return (EPROTOTYPE); + dp = pr->pr_domain; + prp = NULL; - /* Try to find the specified domain based on the family type. */ - dp = pffinddomain(family); - if (dp == NULL) - return (EPFNOSUPPORT); - - dpr = NULL; - - /* Lock out everyone else while we are manipulating the protosw. */ mtx_lock(&dom_mtx); - /* The protocol must exist and only once. */ - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { - if ((pr->pr_type == type) && (pr->pr_protocol == protocol)) { - if (dpr != NULL) { - mtx_unlock(&dom_mtx); - return (EMLINK); /* Should not happen! */ - } else - dpr = pr; + for (int i = 0; i < dp->dom_nprotosw; i++) { + if (dp->dom_protosw[i] == pr) { + KASSERT(prp == NULL, + ("%s: domain %p protocol %p registered twice\n", + __func__, dp, pr)); + prp = &dp->dom_protosw[i]; } } - /* Protocol does not exist. */ - if (dpr == NULL) { + /* Protocol does not exist. XXXGL: assert that it does? */ + if (prp == NULL) { mtx_unlock(&dom_mtx); return (EPROTONOSUPPORT); } /* De-orbit the protocol and make the slot available again. */ - dpr->pr_type = 0; - dpr->pr_domain = dp; - dpr->pr_protocol = PROTO_SPACER; - dpr->pr_flags = 0; - dpr->pr_ctloutput = NULL; - dpr->pr_usrreqs = &nousrreqs; - - /* Job is done, not more protection required. */ + *prp = NULL; mtx_unlock(&dom_mtx); return (0); diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c index 5855e62bd983..ff20b3652407 100644 --- a/sys/kern/uipc_ktls.c +++ b/sys/kern/uipc_ktls.c @@ -2366,7 +2366,7 @@ ktls_decrypt(struct socket *so) counter_u64_add(ktls_offload_corrupted_records, 1); CURVNET_SET(so->so_vnet); - so->so_proto->pr_usrreqs->pru_abort(so); + so->so_proto->pr_abort(so); so->so_error = error; CURVNET_RESTORE(); goto deref; @@ -2890,9 +2890,9 @@ ktls_encrypt(struct ktls_wq *wq, struct mbuf *top) CURVNET_SET(so->so_vnet); if (error == 0) { - (void)(*so->so_proto->pr_usrreqs->pru_ready)(so, top, npages); + (void)so->so_proto->pr_ready(so, top, npages); } else { - so->so_proto->pr_usrreqs->pru_abort(so); + so->so_proto->pr_abort(so); so->so_error = EIO; mb_free_notready(top, total_pages); } @@ -2934,9 +2934,9 @@ ktls_encrypt_cb(struct ktls_ocf_encrypt_state *state, int error) npages = m->m_epg_nrdy; if (error == 0) { - (void)(*so->so_proto->pr_usrreqs->pru_ready)(so, m, npages); + (void)so->so_proto->pr_ready(so, m, npages); } else { - so->so_proto->pr_usrreqs->pru_abort(so); + so->so_proto->pr_abort(so); so->so_error = EIO; mb_free_notready(m, npages); } @@ -3001,7 +3001,7 @@ ktls_encrypt_async(struct ktls_wq *wq, struct mbuf *top) CURVNET_SET(so->so_vnet); if (error != 0) { - so->so_proto->pr_usrreqs->pru_abort(so); + so->so_proto->pr_abort(so); so->so_error = EIO; mb_free_notready(m, total_pages - npages); } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index bbca2d8663d7..bf22c0245f24 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -523,9 +523,8 @@ socreate(int dom, struct socket **aso, int type, int proto, return (EPROTOTYPE); return (EPROTONOSUPPORT); } - if (prp->pr_usrreqs->pru_attach == NULL || - prp->pr_usrreqs->pru_attach == pru_attach_notsupp) - return (EPROTONOSUPPORT); + + MPASS(prp->pr_attach); if (IN_CAPABILITY_MODE(td) && (prp->pr_flags & PR_CAPATTACH) == 0) return (ECAPMODE); @@ -564,7 +563,7 @@ socreate(int dom, struct socket **aso, int type, int proto, * the appropriate flags must be set in the pru_attach function. */ CURVNET_SET(so->so_vnet); - error = (*prp->pr_usrreqs->pru_attach)(so, proto, td); + error = prp->pr_attach(so, proto, td); CURVNET_RESTORE(); if (error) { sodealloc(so); @@ -789,9 +788,9 @@ sonewconn(struct socket *head, int connstatus) if ((so = solisten_clone(head)) == NULL) return (NULL); - if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) { + if (so->so_proto->pr_attach(so, 0, NULL) != 0) { sodealloc(so); - log(LOG_DEBUG, "%s: pcb %p: pru_attach() failed\n", + log(LOG_DEBUG, "%s: pcb %p: pr_attach() failed\n", __func__, head->so_pcb); return (NULL); } @@ -894,7 +893,7 @@ sopeeloff(struct socket *head) __func__, head->so_pcb); return (NULL); } - if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) { + if ((*so->so_proto->pr_attach)(so, 0, NULL)) { sodealloc(so); log(LOG_DEBUG, "%s: pcb %p: pru_attach() failed\n", __func__, head->so_pcb); @@ -919,7 +918,7 @@ sobind(struct socket *so, struct sockaddr *nam, struct thread *td) int error; CURVNET_SET(so->so_vnet); - error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td); + error = so->so_proto->pr_bind(so, nam, td); CURVNET_RESTORE(); return (error); } @@ -930,7 +929,7 @@ sobindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) int error; CURVNET_SET(so->so_vnet); - error = (*so->so_proto->pr_usrreqs->pru_bindat)(fd, so, nam, td); + error = so->so_proto->pr_bindat(fd, so, nam, td); CURVNET_RESTORE(); return (error); } @@ -953,7 +952,7 @@ solisten(struct socket *so, int backlog, struct thread *td) int error; CURVNET_SET(so->so_vnet); - error = (*so->so_proto->pr_usrreqs->pru_listen)(so, backlog, td); + error = so->so_proto->pr_listen(so, backlog, td); CURVNET_RESTORE(); return (error); } @@ -1178,8 +1177,8 @@ sofree(struct socket *so) MPASS(pr->pr_domain->dom_dispose != NULL); (*pr->pr_domain->dom_dispose)(so); } - if (pr->pr_usrreqs->pru_detach != NULL) - (*pr->pr_usrreqs->pru_detach)(so); + if (pr->pr_detach != NULL) + pr->pr_detach(so); /* * From this point on, we assume that no other references to this @@ -1253,8 +1252,8 @@ soclose(struct socket *so) } drop: - if (so->so_proto->pr_usrreqs->pru_close != NULL) - (*so->so_proto->pr_usrreqs->pru_close)(so); + if (so->so_proto->pr_close != NULL) + so->so_proto->pr_close(so); SOCK_LOCK(so); if ((listening = SOLISTENING(so))) { @@ -1314,8 +1313,8 @@ soabort(struct socket *so) VNET_SO_ASSERT(so); - if (so->so_proto->pr_usrreqs->pru_abort != NULL) - (*so->so_proto->pr_usrreqs->pru_abort)(so); + if (so->so_proto->pr_abort != NULL) + so->so_proto->pr_abort(so); SOCK_LOCK(so); sorele_locked(so); } @@ -1326,7 +1325,7 @@ soaccept(struct socket *so, struct sockaddr **nam) int error; CURVNET_SET(so->so_vnet); - error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam); + error = so->so_proto->pr_accept(so, nam); CURVNET_RESTORE(); return (error); } @@ -1360,11 +1359,9 @@ soconnectat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) */ so->so_error = 0; if (fd == AT_FDCWD) { - error = (*so->so_proto->pr_usrreqs->pru_connect)(so, - nam, td); + error = so->so_proto->pr_connect(so, nam, td); } else { - error = (*so->so_proto->pr_usrreqs->pru_connectat)(fd, - so, nam, td); + error = so->so_proto->pr_connectat(fd, so, nam, td); } } CURVNET_RESTORE(); @@ -1378,7 +1375,7 @@ soconnect2(struct socket *so1, struct socket *so2) int error; CURVNET_SET(so1->so_vnet); - error = (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2); + error = so1->so_proto->pr_connect2(so1, so2); CURVNET_RESTORE(); return (error); } @@ -1393,7 +1390,7 @@ sodisconnect(struct socket *so) if (so->so_state & SS_ISDISCONNECTING) return (EALREADY); VNET_SO_ASSERT(so); - error = (*so->so_proto->pr_usrreqs->pru_disconnect)(so); + error = so->so_proto->pr_disconnect(so); return (error); } *** 2768 LINES SKIPPED ***