git: e7d02be19d40 - main - protosw: refactor protosw and domain static declaration and load
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 17 Aug 2022 18:52:27 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=e7d02be19d40063783d6b8f1ff2bc4c7170fd434
commit e7d02be19d40063783d6b8f1ff2bc4c7170fd434
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-08-17 18:50:32 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
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 <sys/rmlock.h>
#include <sys/socketvar.h>
#include <sys/systm.h>
+#include <sys/stat.h> /* XXXGL: remove */
#include <machine/atomic.h>
@@ -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 ***