diff options
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); } @@ -1519,8 +1516,7 @@ sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, * rethink this. */ VNET_SO_ASSERT(so); - error = (*so->so_proto->pr_usrreqs->pru_send)(so, - (flags & MSG_OOB) ? PRUS_OOB : + error = so->so_proto->pr_send(so, (flags & MSG_OOB) ? PRUS_OOB : /* * If the user set MSG_EOF, the protocol understands this flag and * nothing left to send then use PRU_SEND_EOF instead of PRU_SEND. @@ -1570,10 +1566,10 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio, ssize_t resid; int clen = 0, error, dontroute; int atomic = sosendallatonce(so) || top; - int pru_flag; + int pr_send_flag; #ifdef KERN_TLS struct ktls_session *tls; - int tls_enq_cnt, tls_pruflag; + int tls_enq_cnt, tls_send_flag; uint8_t tls_rtype; tls = NULL; @@ -1613,11 +1609,11 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio, goto out; #ifdef KERN_TLS - tls_pruflag = 0; + tls_send_flag = 0; tls = ktls_hold(so->so_snd.sb_tls_info); if (tls != NULL) { if (tls->mode == TCP_TLS_MODE_SW) - tls_pruflag = PRUS_NOTREADY; + tls_send_flag = PRUS_NOTREADY; if (control != NULL) { struct cmsghdr *cm = mtod(control, struct cmsghdr *); @@ -1764,7 +1760,7 @@ restart: */ VNET_SO_ASSERT(so); - pru_flag = (flags & MSG_OOB) ? PRUS_OOB : + pr_send_flag = (flags & MSG_OOB) ? PRUS_OOB : /* * If the user set MSG_EOF, the protocol understands * this flag and nothing left to send then use @@ -1779,11 +1775,11 @@ restart: (resid > 0 && space > 0) ? PRUS_MORETOCOME : 0; #ifdef KERN_TLS - pru_flag |= tls_pruflag; + pr_send_flag |= tls_send_flag; #endif - error = (*so->so_proto->pr_usrreqs->pru_send)(so, - pru_flag, top, addr, control, td); + error = so->so_proto->pr_send(so, pr_send_flag, top, + addr, control, td); if (dontroute) { SOCK_LOCK(so); @@ -1831,7 +1827,7 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, int error; CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sosend(so, addr, uio, + error = so->so_proto->pr_sosend(so, addr, uio, top, control, flags, td); CURVNET_RESTORE(); return (error); @@ -1856,7 +1852,7 @@ soreceive_rcvoob(struct socket *so, struct uio *uio, int flags) VNET_SO_ASSERT(so); m = m_get(M_WAITOK, MT_DATA); - error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK); + error = pr->pr_rcvoob(so, m, flags & MSG_PEEK); if (error) goto bad; do { @@ -1952,7 +1948,7 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio, if ((pr->pr_flags & PR_WANTRCVD) && (so->so_state & SS_ISCONFIRMING) && uio->uio_resid) { VNET_SO_ASSERT(so); - (*pr->pr_usrreqs->pru_rcvd)(so, 0); + pr->pr_rcvd(so, 0); } error = SOCK_IO_RECV_LOCK(so, SBLOCKWAIT(flags)); @@ -2341,7 +2337,7 @@ dontblock: if (pr->pr_flags & PR_WANTRCVD) { SOCKBUF_UNLOCK(&so->so_rcv); VNET_SO_ASSERT(so); - (*pr->pr_usrreqs->pru_rcvd)(so, flags); + pr->pr_rcvd(so, flags); SOCKBUF_LOCK(&so->so_rcv); } SBLASTRECORDCHK(&so->so_rcv); @@ -2396,7 +2392,7 @@ dontblock: (pr->pr_flags & PR_WANTRCVD)) { SOCKBUF_UNLOCK(&so->so_rcv); VNET_SO_ASSERT(so); - (*pr->pr_usrreqs->pru_rcvd)(so, flags); + pr->pr_rcvd(so, flags); SOCKBUF_LOCK(&so->so_rcv); } } @@ -2617,7 +2613,7 @@ deliver: !(flags & MSG_SOCALLBCK))) { SOCKBUF_UNLOCK(sb); VNET_SO_ASSERT(so); - (*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags); + so->so_proto->pr_rcvd(so, flags); SOCKBUF_LOCK(sb); } } @@ -2831,8 +2827,7 @@ soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, int error; CURVNET_SET(so->so_vnet); - error = (so->so_proto->pr_usrreqs->pru_soreceive(so, psa, uio, - mp0, controlp, flagsp)); + error = so->so_proto->pr_soreceive(so, psa, uio, mp0, controlp, flagsp); CURVNET_RESTORE(); return (error); } @@ -2879,12 +2874,12 @@ soshutdown(struct socket *so, int how) CURVNET_SET(so->so_vnet); pr = so->so_proto; - if (pr->pr_usrreqs->pru_flush != NULL) - (*pr->pr_usrreqs->pru_flush)(so, how); + if (pr->pr_flush != NULL) + pr->pr_flush(so, how); if (how != SHUT_WR) sorflush(so); if (how != SHUT_RD) { - error = (*pr->pr_usrreqs->pru_shutdown)(so); + error = pr->pr_shutdown(so); wakeup(&so->so_timeo); CURVNET_RESTORE(); return ((error == 0 && soerror_enotconn) ? ENOTCONN : error); @@ -3555,8 +3550,7 @@ sopoll(struct socket *so, int events, struct ucred *active_cred, * We do not need to set or assert curvnet as long as everyone uses * sopoll_generic(). */ - return (so->so_proto->pr_usrreqs->pru_sopoll(so, events, active_cred, - td)); + return (so->so_proto->pr_sopoll(so, events, active_cred, td)); } int @@ -3662,180 +3656,6 @@ soo_kqfilter(struct file *fp, struct knote *kn) return (0); } -/* - * Some routines that return EOPNOTSUPP for entry points that are not - * supported by a protocol. Fill in as needed. - */ -int -pru_accept_notsupp(struct socket *so, struct sockaddr **nam) -{ - - return EOPNOTSUPP; -} - -int -pru_aio_queue_notsupp(struct socket *so, struct kaiocb *job) -{ - - return EOPNOTSUPP; -} - -int -pru_attach_notsupp(struct socket *so, int proto, struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_bind_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam, - struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam, - struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_connect2_notsupp(struct socket *so1, struct socket *so2) -{ - - return EOPNOTSUPP; -} - -int -pru_control_notsupp(struct socket *so, u_long cmd, void *data, - struct ifnet *ifp, struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_disconnect_notsupp(struct socket *so) -{ - - return EOPNOTSUPP; -} - -int -pru_listen_notsupp(struct socket *so, int backlog, struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam) -{ - - return EOPNOTSUPP; -} - -int -pru_rcvd_notsupp(struct socket *so, int flags) -{ - - return EOPNOTSUPP; -} - -int -pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags) -{ - - return EOPNOTSUPP; -} - -int -pru_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); -} - -int -pru_ready_notsupp(struct socket *so, struct mbuf *m, int count) -{ - - return (EOPNOTSUPP); -} - -/* - * This isn't really a ``null'' operation, but it's the default one and - * doesn't do anything destructive. - */ -int -pru_sense_null(struct socket *so, struct stat *sb) -{ - - sb->st_blksize = so->so_snd.sb_hiwat; - return 0; -} - -int -pru_shutdown_notsupp(struct socket *so) -{ - - return EOPNOTSUPP; -} - -int -pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam) -{ - - return EOPNOTSUPP; -} - -int -pru_sosend_notsupp(struct socket *so, struct sockaddr *addr, struct uio *uio, - struct mbuf *top, struct mbuf *control, int flags, struct thread *td) -{ - - return EOPNOTSUPP; -} - -int -pru_soreceive_notsupp(struct socket *so, struct sockaddr **paddr, - struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp) -{ - - return EOPNOTSUPP; -} - -int -pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred, - struct thread *td) -{ - - return EOPNOTSUPP; -} - static void filt_sordetach(struct knote *kn) { diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index d108795efcaf..4be1c9aa6a59 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1385,7 +1385,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, so = fp->f_data; *sa = NULL; CURVNET_SET(so->so_vnet); - error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa); + error = so->so_proto->pr_sockaddr(so, sa); CURVNET_RESTORE(); if (error != 0) goto bad; @@ -1471,7 +1471,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, } *sa = NULL; CURVNET_SET(so->so_vnet); - error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa); + error = so->so_proto->pr_peeraddr(so, sa); CURVNET_RESTORE(); if (error != 0) goto bad; diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index eb6404c86320..1f2d8a6647b9 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -105,9 +105,7 @@ __FBSDID("$FreeBSD$"); MALLOC_DECLARE(M_FILECAPS); -/* - * See unpcb.h for the locking key. - */ +static struct domain localdomain; static uma_zone_t unp_zone; static unp_gen_t unp_gencnt; /* (l) */ @@ -221,7 +219,7 @@ SYSCTL_INT(_net_local, OID_AUTO, deferred, CTLFLAG_RD, * using a reference counter to maintain liveness. * * UNIX domain sockets each have an unpcb hung off of their so_pcb pointer, - * allocated in pru_attach() and freed in pru_detach(). The validity of that + * allocated in pr_attach() and freed in pr_detach(). The validity of that * pointer is an invariant, so no lock is required to dereference the so_pcb * pointer if a valid socket reference is held by the caller. In practice, * this is always true during operations performed on a socket. Each unpcb @@ -419,55 +417,6 @@ unp_pcb_lock_peer(struct unpcb *unp) return (unp2); } -/* - * Definitions of protocols supported in the LOCAL domain. - */ -static struct domain localdomain; -static struct pr_usrreqs uipc_usrreqs_dgram, uipc_usrreqs_stream; -static struct pr_usrreqs uipc_usrreqs_seqpacket; -static struct protosw localsw[] = { -{ - .pr_type = SOCK_STREAM, - .pr_domain = &localdomain, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS| - PR_CAPATTACH, - .pr_ctloutput = &uipc_ctloutput, - .pr_usrreqs = &uipc_usrreqs_stream -}, -{ - .pr_type = SOCK_DGRAM, - .pr_domain = &localdomain, - .pr_flags = PR_ATOMIC | PR_ADDR |PR_RIGHTS | PR_CAPATTACH | - PR_SOCKBUF, - .pr_ctloutput = &uipc_ctloutput, - .pr_usrreqs = &uipc_usrreqs_dgram -}, -{ - .pr_type = SOCK_SEQPACKET, - .pr_domain = &localdomain, - - /* - * XXXRW: For now, PR_ADDR because soreceive will bump into them - * due to our use of sbappendaddr. A new sbappend variants is needed - * that supports both atomic record writes and control data. - */ - .pr_flags = PR_ADDR|PR_ATOMIC|PR_CONNREQUIRED| - PR_WANTRCVD|PR_RIGHTS|PR_CAPATTACH, - .pr_ctloutput = &uipc_ctloutput, - .pr_usrreqs = &uipc_usrreqs_seqpacket, -}, -}; - -static struct domain localdomain = { - .dom_family = AF_LOCAL, - .dom_name = "local", - .dom_externalize = unp_externalize, - .dom_dispose = unp_dispose, - .dom_protosw = localsw, - .dom_protoswNPROTOSW = &localsw[nitems(localsw)] -}; -DOMAIN_SET(local); - static void uipc_abort(struct socket *so) { @@ -1118,7 +1067,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, m = NULL; out: /* - * PRUS_EOF is equivalent to pru_send followed by pru_shutdown. + * PRUS_EOF is equivalent to pr_send followed by pr_shutdown. */ if (flags & PRUS_EOF) { UNP_PCB_LOCK(unp); @@ -1211,7 +1160,7 @@ uipc_sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, (error = unp_internalize(&c, td, &clast, &ctl, &mbcnt))) goto out; } else { - /* pru_sosend() with mbuf usually is a kernel thread. */ + /* pr_sosend() with mbuf usually is a kernel thread. */ M_ASSERTPKTHDR(m); if (__predict_false(c != NULL)) @@ -1771,71 +1720,6 @@ uipc_sockaddr(struct socket *so, struct sockaddr **nam) return (0); } -static struct pr_usrreqs uipc_usrreqs_dgram = { - .pru_abort = uipc_abort, - .pru_accept = uipc_accept, - .pru_attach = uipc_attach, - .pru_bind = uipc_bind, - .pru_bindat = uipc_bindat, - .pru_connect = uipc_connect, - .pru_connectat = uipc_connectat, - .pru_connect2 = uipc_connect2, - .pru_detach = uipc_detach, - .pru_disconnect = uipc_disconnect, - .pru_peeraddr = uipc_peeraddr, - .pru_sosend = uipc_sosend_dgram, - .pru_sense = uipc_sense, - .pru_shutdown = uipc_shutdown, - .pru_sockaddr = uipc_sockaddr, - .pru_soreceive = uipc_soreceive_dgram, - .pru_close = uipc_close, -}; - -static struct pr_usrreqs uipc_usrreqs_seqpacket = { - .pru_abort = uipc_abort, - .pru_accept = uipc_accept, - .pru_attach = uipc_attach, - .pru_bind = uipc_bind, - .pru_bindat = uipc_bindat, - .pru_connect = uipc_connect, - .pru_connectat = uipc_connectat, - .pru_connect2 = uipc_connect2, - .pru_detach = uipc_detach, - .pru_disconnect = uipc_disconnect, - .pru_listen = uipc_listen, - .pru_peeraddr = uipc_peeraddr, - .pru_rcvd = uipc_rcvd, - .pru_send = uipc_send, - .pru_sense = uipc_sense, - .pru_shutdown = uipc_shutdown, - .pru_sockaddr = uipc_sockaddr, - .pru_soreceive = soreceive_generic, /* XXX: or...? */ - .pru_close = uipc_close, -}; - -static struct pr_usrreqs uipc_usrreqs_stream = { - .pru_abort = uipc_abort, - .pru_accept = uipc_accept, - .pru_attach = uipc_attach, - .pru_bind = uipc_bind, - .pru_bindat = uipc_bindat, - .pru_connect = uipc_connect, - .pru_connectat = uipc_connectat, - .pru_connect2 = uipc_connect2, - .pru_detach = uipc_detach, - .pru_disconnect = uipc_disconnect, - .pru_listen = uipc_listen, - .pru_peeraddr = uipc_peeraddr, - .pru_rcvd = uipc_rcvd, - .pru_send = uipc_send, - .pru_ready = uipc_ready, - .pru_sense = uipc_sense, - .pru_shutdown = uipc_shutdown, - .pru_sockaddr = uipc_sockaddr, - .pru_soreceive = soreceive_generic, - .pru_close = uipc_close, -}; - static int uipc_ctloutput(struct socket *so, struct sockopt *sopt) { @@ -3427,6 +3311,105 @@ unp_scan(struct mbuf *m0, void (*op)(struct filedescent **, int)) } /* + * Definitions of protocols supported in the LOCAL domain. + */ +static struct protosw streamproto = { + .pr_type = SOCK_STREAM, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS| + PR_CAPATTACH, + .pr_ctloutput = &uipc_ctloutput, + .pr_abort = uipc_abort, + .pr_accept = uipc_accept, + .pr_attach = uipc_attach, + .pr_bind = uipc_bind, + .pr_bindat = uipc_bindat, + .pr_connect = uipc_connect, + .pr_connectat = uipc_connectat, + .pr_connect2 = uipc_connect2, + .pr_detach = uipc_detach, + .pr_disconnect = uipc_disconnect, + .pr_listen = uipc_listen, + .pr_peeraddr = uipc_peeraddr, + .pr_rcvd = uipc_rcvd, + .pr_send = uipc_send, + .pr_ready = uipc_ready, + .pr_sense = uipc_sense, + .pr_shutdown = uipc_shutdown, + .pr_sockaddr = uipc_sockaddr, + .pr_soreceive = soreceive_generic, + .pr_close = uipc_close, +}; + +static struct protosw dgramproto = { + .pr_type = SOCK_DGRAM, + .pr_flags = PR_ATOMIC | PR_ADDR |PR_RIGHTS | PR_CAPATTACH | + PR_SOCKBUF, + .pr_ctloutput = &uipc_ctloutput, + .pr_abort = uipc_abort, + .pr_accept = uipc_accept, + .pr_attach = uipc_attach, + .pr_bind = uipc_bind, + .pr_bindat = uipc_bindat, + .pr_connect = uipc_connect, + .pr_connectat = uipc_connectat, + .pr_connect2 = uipc_connect2, + .pr_detach = uipc_detach, + .pr_disconnect = uipc_disconnect, + .pr_peeraddr = uipc_peeraddr, + .pr_sosend = uipc_sosend_dgram, + .pr_sense = uipc_sense, + .pr_shutdown = uipc_shutdown, + .pr_sockaddr = uipc_sockaddr, + .pr_soreceive = uipc_soreceive_dgram, + .pr_close = uipc_close, +}; + +static struct protosw seqpacketproto = { + .pr_type = SOCK_SEQPACKET, + /* + * XXXRW: For now, PR_ADDR because soreceive will bump into them + * due to our use of sbappendaddr. A new sbappend variants is needed + * that supports both atomic record writes and control data. + */ + .pr_flags = PR_ADDR|PR_ATOMIC|PR_CONNREQUIRED| + PR_WANTRCVD|PR_RIGHTS|PR_CAPATTACH, + .pr_ctloutput = &uipc_ctloutput, + .pr_abort = uipc_abort, + .pr_accept = uipc_accept, + .pr_attach = uipc_attach, + .pr_bind = uipc_bind, + .pr_bindat = uipc_bindat, + .pr_connect = uipc_connect, + .pr_connectat = uipc_connectat, + .pr_connect2 = uipc_connect2, + .pr_detach = uipc_detach, + .pr_disconnect = uipc_disconnect, + .pr_listen = uipc_listen, + .pr_peeraddr = uipc_peeraddr, + .pr_rcvd = uipc_rcvd, + .pr_send = uipc_send, + .pr_sense = uipc_sense, + .pr_shutdown = uipc_shutdown, + .pr_sockaddr = uipc_sockaddr, + .pr_soreceive = soreceive_generic, /* XXX: or...? */ + .pr_close = uipc_close, +}; + +static struct domain localdomain = { + .dom_family = AF_LOCAL, + .dom_name = "local", + .dom_externalize = unp_externalize, + .dom_dispose = unp_dispose, + .dom_nprotosw = 3, + .dom_protosw = { + &streamproto, + &dgramproto, + &seqpacketproto, + } +}; +DOMAIN_SET(local); + +/* * A helper function called by VFS before socket-type vnode reclamation. * For an active vnode it clears unp_vnode pointer and decrements unp_vnode * use count. diff --git a/sys/net/if.c b/sys/net/if.c index 79995e3b9ea4..886d3f7833c0 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -3163,8 +3163,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td) * layer, and do not perform any credentials checks or input * validation. */ - error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, - ifp, td)); + error = so->so_proto->pr_control(so, cmd, data, ifp, td); if (error == EOPNOTSUPP && ifp != NULL && ifp->if_ioctl != NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFBRDADDR && cmd != SIOCSIFDSTADDR && cmd != SIOCSIFNETMASK) diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 7d5d384a6f75..a90c11c1dcbf 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -513,7 +513,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) callout_init_rm(&peer->ping_send, &sc->lock, CALLOUT_SHAREDLOCK); callout_init_rm(&peer->ping_rcv, &sc->lock, 0); - ret = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &name); + ret = so->so_proto->pr_sockaddr(so, &name); if (ret) goto error; diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index f0fcc7ab9004..1ddb72d926b9 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -2648,29 +2648,22 @@ static SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD | CTLFLAG_MPSAFE, static struct domain routedomain; /* or at least forward */ -static struct pr_usrreqs route_usrreqs = { - .pru_abort = rts_close, - .pru_attach = rts_attach, - .pru_detach = rts_detach, - .pru_send = rts_send, - .pru_shutdown = rts_shutdown, - .pru_close = rts_close, -}; - -static struct protosw routesw[] = { -{ +static struct protosw routesw = { .pr_type = SOCK_RAW, - .pr_domain = &routedomain, .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &route_usrreqs -} + .pr_abort = rts_close, + .pr_attach = rts_attach, + .pr_detach = rts_detach, + .pr_send = rts_send, + .pr_shutdown = rts_shutdown, + .pr_close = rts_close, }; static struct domain routedomain = { .dom_family = PF_ROUTE, .dom_name = "route", - .dom_protosw = routesw, - .dom_protoswNPROTOSW = &routesw[nitems(routesw)] + .dom_nprotosw = 1, + .dom_protosw = { &routesw }, }; DOMAIN_SET(route); diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket.c b/sys/netgraph/bluetooth/socket/ng_btsocket.c index 1ea3b1f649b3..0ed694cb19db 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket.c @@ -62,153 +62,111 @@ #include <netgraph/bluetooth/include/ng_btsocket_sco.h> static int ng_btsocket_modevent (module_t, int, void *); -static struct domain ng_btsocket_domain; - -/* - * Bluetooth raw HCI sockets - */ - -static struct pr_usrreqs ng_btsocket_hci_raw_usrreqs = { - .pru_abort = ng_btsocket_hci_raw_abort, - .pru_attach = ng_btsocket_hci_raw_attach, - .pru_bind = ng_btsocket_hci_raw_bind, - .pru_connect = ng_btsocket_hci_raw_connect, - .pru_control = ng_btsocket_hci_raw_control, - .pru_detach = ng_btsocket_hci_raw_detach, - .pru_disconnect = ng_btsocket_hci_raw_disconnect, - .pru_peeraddr = ng_btsocket_hci_raw_peeraddr, - .pru_send = ng_btsocket_hci_raw_send, - .pru_sockaddr = ng_btsocket_hci_raw_sockaddr, - .pru_close = ng_btsocket_hci_raw_close, -}; - -/* - * Bluetooth raw L2CAP sockets - */ - -static struct pr_usrreqs ng_btsocket_l2cap_raw_usrreqs = { - .pru_abort = ng_btsocket_l2cap_raw_abort, - .pru_attach = ng_btsocket_l2cap_raw_attach, - .pru_bind = ng_btsocket_l2cap_raw_bind, - .pru_connect = ng_btsocket_l2cap_raw_connect, - .pru_control = ng_btsocket_l2cap_raw_control, - .pru_detach = ng_btsocket_l2cap_raw_detach, - .pru_disconnect = ng_btsocket_l2cap_raw_disconnect, - .pru_peeraddr = ng_btsocket_l2cap_raw_peeraddr, - .pru_send = ng_btsocket_l2cap_raw_send, - .pru_sockaddr = ng_btsocket_l2cap_raw_sockaddr, - .pru_close = ng_btsocket_l2cap_raw_close, -}; - -/* - * Bluetooth SEQPACKET L2CAP sockets - */ - -static struct pr_usrreqs ng_btsocket_l2cap_usrreqs = { - .pru_abort = ng_btsocket_l2cap_abort, - .pru_accept = ng_btsocket_l2cap_accept, - .pru_attach = ng_btsocket_l2cap_attach, - .pru_bind = ng_btsocket_l2cap_bind, - .pru_connect = ng_btsocket_l2cap_connect, - .pru_control = ng_btsocket_l2cap_control, - .pru_detach = ng_btsocket_l2cap_detach, - .pru_disconnect = ng_btsocket_l2cap_disconnect, - .pru_listen = ng_btsocket_l2cap_listen, - .pru_peeraddr = ng_btsocket_l2cap_peeraddr, - .pru_send = ng_btsocket_l2cap_send, - .pru_sockaddr = ng_btsocket_l2cap_sockaddr, - .pru_close = ng_btsocket_l2cap_close, -}; - -/* - * Bluetooth STREAM RFCOMM sockets - */ - -static struct pr_usrreqs ng_btsocket_rfcomm_usrreqs = { - .pru_abort = ng_btsocket_rfcomm_abort, - .pru_accept = ng_btsocket_rfcomm_accept, - .pru_attach = ng_btsocket_rfcomm_attach, - .pru_bind = ng_btsocket_rfcomm_bind, - .pru_connect = ng_btsocket_rfcomm_connect, - .pru_control = ng_btsocket_rfcomm_control, - .pru_detach = ng_btsocket_rfcomm_detach, - .pru_disconnect = ng_btsocket_rfcomm_disconnect, - .pru_listen = ng_btsocket_rfcomm_listen, - .pru_peeraddr = ng_btsocket_rfcomm_peeraddr, - .pru_send = ng_btsocket_rfcomm_send, - .pru_sockaddr = ng_btsocket_rfcomm_sockaddr, - .pru_close = ng_btsocket_rfcomm_close, -}; - -/* - * Bluetooth SEQPACKET SCO sockets - */ - -static struct pr_usrreqs ng_btsocket_sco_usrreqs = { - .pru_abort = ng_btsocket_sco_abort, - .pru_accept = ng_btsocket_sco_accept, - .pru_attach = ng_btsocket_sco_attach, - .pru_bind = ng_btsocket_sco_bind, - .pru_connect = ng_btsocket_sco_connect, - .pru_control = ng_btsocket_sco_control, - .pru_detach = ng_btsocket_sco_detach, - .pru_disconnect = ng_btsocket_sco_disconnect, - .pru_listen = ng_btsocket_sco_listen, - .pru_peeraddr = ng_btsocket_sco_peeraddr, - .pru_send = ng_btsocket_sco_send, - .pru_sockaddr = ng_btsocket_sco_sockaddr, - .pru_close = ng_btsocket_sco_close, -}; /* * Definitions of protocols supported in the BLUETOOTH domain */ -static struct protosw ng_btsocket_protosw[] = { -{ +/* Bluetooth raw HCI sockets */ +static struct protosw ng_btsocket_hci_raw_protosw = { .pr_type = SOCK_RAW, - .pr_domain = &ng_btsocket_domain, .pr_protocol = BLUETOOTH_PROTO_HCI, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_ctloutput = ng_btsocket_hci_raw_ctloutput, - .pr_usrreqs = &ng_btsocket_hci_raw_usrreqs, -}, -{ + .pr_abort = ng_btsocket_hci_raw_abort, + .pr_attach = ng_btsocket_hci_raw_attach, + .pr_bind = ng_btsocket_hci_raw_bind, + .pr_connect = ng_btsocket_hci_raw_connect, + .pr_control = ng_btsocket_hci_raw_control, + .pr_detach = ng_btsocket_hci_raw_detach, + .pr_disconnect = ng_btsocket_hci_raw_disconnect, + .pr_peeraddr = ng_btsocket_hci_raw_peeraddr, + .pr_send = ng_btsocket_hci_raw_send, + .pr_sockaddr = ng_btsocket_hci_raw_sockaddr, + .pr_close = ng_btsocket_hci_raw_close, +}; + +/* Bluetooth raw L2CAP sockets */ +static struct protosw ng_btsocket_l2cap_raw_protosw = { .pr_type = SOCK_RAW, - .pr_domain = &ng_btsocket_domain, .pr_protocol = BLUETOOTH_PROTO_L2CAP, .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &ng_btsocket_l2cap_raw_usrreqs, -}, -{ + .pr_abort = ng_btsocket_l2cap_raw_abort, + .pr_attach = ng_btsocket_l2cap_raw_attach, + .pr_bind = ng_btsocket_l2cap_raw_bind, + .pr_connect = ng_btsocket_l2cap_raw_connect, + .pr_control = ng_btsocket_l2cap_raw_control, + .pr_detach = ng_btsocket_l2cap_raw_detach, + .pr_disconnect = ng_btsocket_l2cap_raw_disconnect, + .pr_peeraddr = ng_btsocket_l2cap_raw_peeraddr, + .pr_send = ng_btsocket_l2cap_raw_send, + .pr_sockaddr = ng_btsocket_l2cap_raw_sockaddr, + .pr_close = ng_btsocket_l2cap_raw_close, +}; + +/* Bluetooth SEQPACKET L2CAP sockets */ +static struct protosw ng_btsocket_l2cap_protosw = { .pr_type = SOCK_SEQPACKET, - .pr_domain = &ng_btsocket_domain, .pr_protocol = BLUETOOTH_PROTO_L2CAP, .pr_flags = PR_ATOMIC|PR_CONNREQUIRED, .pr_ctloutput = ng_btsocket_l2cap_ctloutput, - .pr_usrreqs = &ng_btsocket_l2cap_usrreqs, -}, -{ + .pr_abort = ng_btsocket_l2cap_abort, + .pr_accept = ng_btsocket_l2cap_accept, + .pr_attach = ng_btsocket_l2cap_attach, + .pr_bind = ng_btsocket_l2cap_bind, + .pr_connect = ng_btsocket_l2cap_connect, + .pr_control = ng_btsocket_l2cap_control, + .pr_detach = ng_btsocket_l2cap_detach, + .pr_disconnect = ng_btsocket_l2cap_disconnect, + .pr_listen = ng_btsocket_l2cap_listen, + .pr_peeraddr = ng_btsocket_l2cap_peeraddr, + .pr_send = ng_btsocket_l2cap_send, + .pr_sockaddr = ng_btsocket_l2cap_sockaddr, + .pr_close = ng_btsocket_l2cap_close, +}; + +/* Bluetooth STREAM RFCOMM sockets */ +static struct protosw ng_btsocket_rfcomm_protosw = { .pr_type = SOCK_STREAM, - .pr_domain = &ng_btsocket_domain, .pr_protocol = BLUETOOTH_PROTO_RFCOMM, .pr_flags = PR_CONNREQUIRED, .pr_ctloutput = ng_btsocket_rfcomm_ctloutput, - .pr_usrreqs = &ng_btsocket_rfcomm_usrreqs, -}, -{ + .pr_abort = ng_btsocket_rfcomm_abort, + .pr_accept = ng_btsocket_rfcomm_accept, + .pr_attach = ng_btsocket_rfcomm_attach, + .pr_bind = ng_btsocket_rfcomm_bind, + .pr_connect = ng_btsocket_rfcomm_connect, + .pr_control = ng_btsocket_rfcomm_control, + .pr_detach = ng_btsocket_rfcomm_detach, + .pr_disconnect = ng_btsocket_rfcomm_disconnect, + .pr_listen = ng_btsocket_rfcomm_listen, + .pr_peeraddr = ng_btsocket_rfcomm_peeraddr, + .pr_send = ng_btsocket_rfcomm_send, + .pr_sockaddr = ng_btsocket_rfcomm_sockaddr, + .pr_close = ng_btsocket_rfcomm_close, +}; + +/* Bluetooth SEQPACKET SCO sockets */ +static struct protosw ng_btsocket_sco_protosw = { .pr_type = SOCK_SEQPACKET, - .pr_domain = &ng_btsocket_domain, .pr_protocol = BLUETOOTH_PROTO_SCO, .pr_flags = PR_ATOMIC|PR_CONNREQUIRED, .pr_ctloutput = ng_btsocket_sco_ctloutput, - .pr_usrreqs = &ng_btsocket_sco_usrreqs, -}, + .pr_abort = ng_btsocket_sco_abort, + .pr_accept = ng_btsocket_sco_accept, + .pr_attach = ng_btsocket_sco_attach, + .pr_bind = ng_btsocket_sco_bind, + .pr_connect = ng_btsocket_sco_connect, + .pr_control = ng_btsocket_sco_control, + .pr_detach = ng_btsocket_sco_detach, + .pr_disconnect = ng_btsocket_sco_disconnect, + .pr_listen = ng_btsocket_sco_listen, + .pr_peeraddr = ng_btsocket_sco_peeraddr, + .pr_send = ng_btsocket_sco_send, + .pr_sockaddr = ng_btsocket_sco_sockaddr, + .pr_close = ng_btsocket_sco_close, }; -#define ng_btsocket_protosw_end \ - &ng_btsocket_protosw[nitems(ng_btsocket_protosw)] - /* * BLUETOOTH domain */ @@ -216,8 +174,14 @@ static struct protosw ng_btsocket_protosw[] = { static struct domain ng_btsocket_domain = { .dom_family = AF_BLUETOOTH, .dom_name = "bluetooth", - .dom_protosw = ng_btsocket_protosw, - .dom_protoswNPROTOSW = ng_btsocket_protosw_end + .dom_nprotosw = 5, + .dom_protosw = { + &ng_btsocket_hci_raw_protosw, + &ng_btsocket_l2cap_raw_protosw, + &ng_btsocket_l2cap_protosw, + &ng_btsocket_rfcomm_protosw, + &ng_btsocket_sco_protosw, + }, }; /* diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c index ac504483b0a8..ee1b3b85f1dc 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c @@ -1637,8 +1637,8 @@ ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s) return (0); /* we are done */ /* Call send function on the L2CAP socket */ - error = (*s->l2so->so_proto->pr_usrreqs->pru_send)(s->l2so, - 0, m, NULL, NULL, curthread /* XXX */); + error = s->l2so->so_proto->pr_send(s->l2so, 0, m, NULL, NULL, + curthread /* XXX */); if (error != 0) { NG_BTSOCKET_RFCOMM_ERR( "%s: Could not send data to L2CAP socket, error=%d\n", __func__, error); diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c index 7c8cbd38e98e..d4f41fe02205 100644 --- a/sys/netgraph/ng_ksocket.c +++ b/sys/netgraph/ng_ksocket.c @@ -774,9 +774,9 @@ ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook) if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) ERROUT(ENOTCONN); - func = so->so_proto->pr_usrreqs->pru_peeraddr; + func = so->so_proto->pr_peeraddr; } else - func = so->so_proto->pr_usrreqs->pru_sockaddr; + func = so->so_proto->pr_sockaddr; /* Get local or peer address */ if ((error = (*func)(so, &sa)) != 0) diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index a7a70b0c35a6..852d51af296a 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -1128,59 +1128,42 @@ dummy_disconnect(struct socket *so) { return (0); } + /* + * Definitions of protocols supported in the NETGRAPH domain. * Control and data socket type descriptors * * XXXRW: Perhaps _close should do something? */ - -static struct pr_usrreqs ngc_usrreqs = { - .pru_attach = ngc_attach, - .pru_bind = ngc_bind, - .pru_connect = ngc_connect, - .pru_detach = ngc_detach, - .pru_disconnect = dummy_disconnect, - .pru_send = ngc_send, - .pru_sockaddr = ng_getsockaddr, -}; - -static struct pr_usrreqs ngd_usrreqs = { - .pru_attach = ngd_attach, - .pru_connect = ngd_connect, - .pru_detach = ngd_detach, - .pru_disconnect = dummy_disconnect, - .pru_send = ngd_send, - .pru_sockaddr = ng_getsockaddr, -}; - -/* - * Definitions of protocols supported in the NETGRAPH domain. - */ - -extern struct domain ngdomain; /* stop compiler warnings */ - -static struct protosw ngsw[] = { -{ +static struct protosw ngcontrol_protosw = { .pr_type = SOCK_DGRAM, - .pr_domain = &ngdomain, .pr_protocol = NG_CONTROL, .pr_flags = PR_ATOMIC | PR_ADDR /* | PR_RIGHTS */, - .pr_usrreqs = &ngc_usrreqs -}, -{ + .pr_attach = ngc_attach, + .pr_bind = ngc_bind, + .pr_connect = ngc_connect, + .pr_detach = ngc_detach, + .pr_disconnect = dummy_disconnect, + .pr_send = ngc_send, + .pr_sockaddr = ng_getsockaddr, +}; +static struct protosw ngdata_protosw = { .pr_type = SOCK_DGRAM, - .pr_domain = &ngdomain, .pr_protocol = NG_DATA, .pr_flags = PR_ATOMIC | PR_ADDR, - .pr_usrreqs = &ngd_usrreqs -} + .pr_attach = ngd_attach, + .pr_connect = ngd_connect, + .pr_detach = ngd_detach, + .pr_disconnect = dummy_disconnect, + .pr_send = ngd_send, + .pr_sockaddr = ng_getsockaddr, }; -struct domain ngdomain = { +static struct domain ngdomain = { .dom_family = AF_NETGRAPH, .dom_name = "netgraph", - .dom_protosw = ngsw, - .dom_protoswNPROTOSW = &ngsw[nitems(ngsw)] + .dom_nprotosw = 2, + .dom_protosw = { &ngcontrol_protosw, &ngdata_protosw }, }; /* diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index cac885560a30..35b02d706e72 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -86,8 +86,6 @@ __FBSDID("$FreeBSD$"); * TCP/IP protocol family: IP, ICMP, UDP, TCP. */ -static struct pr_usrreqs nousrreqs; - #ifdef SCTP #include <netinet/in_pcb.h> #include <netinet/sctp_pcb.h> @@ -95,173 +93,59 @@ static struct pr_usrreqs nousrreqs; #include <netinet/sctp_var.h> #endif -FEATURE(inet, "Internet Protocol version 4"); - -extern struct domain inetdomain; +/* netinet/raw_ip.c */ +extern struct protosw rip_protosw, rsvp_protosw, rawipv4_protosw, + rawipv6_protosw, mobile_protosw, etherip_protosw, icmp_protosw, + igmp_protosw, gre_protosw, pim_protosw, ripwild_protosw; +/* netinet/udp_usrreq.c */ +extern struct protosw udp_protosw, udplite_protosw; -/* Spacer for loadable protocols. */ -#define IPPROTOSPACER \ -{ \ - .pr_domain = &inetdomain, \ - .pr_protocol = PROTO_SPACER, \ - .pr_usrreqs = &nousrreqs \ -} - -struct protosw inetsw[] = { -{ - .pr_type = SOCK_DGRAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_UDP, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_CAPATTACH, - .pr_ctloutput = udp_ctloutput, - .pr_usrreqs = &udp_usrreqs -}, -{ - .pr_type = SOCK_STREAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_TCP, - .pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD| - PR_CAPATTACH, - .pr_ctloutput = tcp_ctloutput, - .pr_usrreqs = &tcp_usrreqs -}, -#ifdef SCTP -{ - .pr_type = SOCK_SEQPACKET, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp_usrreqs -}, -{ - .pr_type = SOCK_STREAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp_usrreqs -}, -#endif /* SCTP */ -{ - .pr_type = SOCK_DGRAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_UDPLITE, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_CAPATTACH, - .pr_ctloutput = udp_ctloutput, - .pr_usrreqs = &udp_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_RAW, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_ICMP, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_IGMP, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_RSVP, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_IPV4, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_MOBILE, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_ETHERIP, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_GRE, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -# ifdef INET6 -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_IPV6, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -#endif -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_PIM, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -/* Spacer n-times for loadable protocols. */ -IPPROTOSPACER, -IPPROTOSPACER, -IPPROTOSPACER, -IPPROTOSPACER, -IPPROTOSPACER, -IPPROTOSPACER, -IPPROTOSPACER, -IPPROTOSPACER, -/* raw wildcard */ -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &rip_usrreqs -}, -}; +FEATURE(inet, "Internet Protocol version 4"); struct domain inetdomain = { .dom_family = AF_INET, .dom_name = "internet", - .dom_protosw = inetsw, - .dom_protoswNPROTOSW = &inetsw[nitems(inetsw)], .dom_rtattach = in_inithead, #ifdef VIMAGE .dom_rtdetach = in_detachhead, #endif .dom_ifattach = in_domifattach, - .dom_ifdetach = in_domifdetach + .dom_ifdetach = in_domifdetach, + .dom_nprotosw = 24, + .dom_protosw = { + &tcp_protosw, + &udp_protosw, +#ifdef SCTP + &sctp_seqpacket_protosw, + &sctp_stream_protosw, +#else + NULL, NULL, +#endif + &udplite_protosw, + &rip_protosw, + /* + * XXXGL: it is entirely possible that all below raw-based + * protosw definitions are not needed. They could have existed + * just to define pr_input, pr_drain, pr_*timo or PR_LASTHDR + * flag, and were never supposed to create a special socket. + */ + &icmp_protosw, + &igmp_protosw, + &rsvp_protosw, + &rawipv4_protosw, + &mobile_protosw, + ðerip_protosw, + &gre_protosw, +#ifdef INET6 + &rawipv6_protosw, +#else + NULL, +#endif + &pim_protosw, + /* Spacer 8 times for loadable protocols. XXXGL: why 8? */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &ripwild_protosw, + }, }; DOMAIN_SET(inet); diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index c8a2ad7b4c94..b4730b069fc1 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -726,23 +726,19 @@ SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, "List of active divert sockets"); #endif -struct pr_usrreqs div_usrreqs = { - .pru_attach = div_attach, - .pru_bind = div_bind, - .pru_control = in_control, - .pru_detach = div_detach, - .pru_peeraddr = in_getpeeraddr, - .pru_send = div_send, - .pru_shutdown = div_shutdown, - .pru_sockaddr = in_getsockaddr, - .pru_sosetlabel = in_pcbsosetlabel -}; - -struct protosw div_protosw = { +static struct protosw div_protosw = { .pr_type = SOCK_RAW, .pr_protocol = IPPROTO_DIVERT, .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &div_usrreqs + .pr_attach = div_attach, + .pr_bind = div_bind, + .pr_control = in_control, + .pr_detach = div_detach, + .pr_peeraddr = in_getpeeraddr, + .pr_send = div_send, + .pr_shutdown = div_shutdown, + .pr_sockaddr = in_getsockaddr, + .pr_sosetlabel = in_pcbsosetlabel }; static int @@ -755,7 +751,7 @@ div_modevent(module_t mod, int type, void *unused) /* * Protocol will be initialized by pf_proto_register(). */ - err = pf_proto_register(PF_INET, &div_protosw); + err = protosw_register(&inetdomain, &div_protosw); if (err != 0) return (err); ip_divert_ptr = divert_packet; @@ -787,7 +783,7 @@ div_modevent(module_t mod, int type, void *unused) break; } ip_divert_ptr = NULL; - err = pf_proto_unregister(PF_INET, IPPROTO_DIVERT, SOCK_RAW); + err = protosw_unregister(&div_protosw); INP_INFO_WUNLOCK(&V_divcbinfo); #ifndef VIMAGE div_destroy(NULL); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index b68a6536c8b8..a502f50ac4df 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -106,7 +106,6 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_frag_size, CTLFLAG_RW, static void ip_mloopback(struct ifnet *, const struct mbuf *, int); extern int in_mcast_loop; -extern struct protosw inetsw[]; static inline int ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, int flags, diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 7701b64c1be0..237a99a3481c 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -195,7 +195,6 @@ extern int (*legal_vif_num)(int); extern u_long (*ip_mcast_src)(int); VNET_DECLARE(int, rsvp_on); VNET_DECLARE(int, drop_redirect); -extern struct pr_usrreqs rip_usrreqs; #define V_ip_id VNET(ip_id) #define V_ip_defttl VNET(ip_defttl) diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 4da408080794..0e7e75b1fe99 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -133,8 +133,6 @@ int (*ip_rsvp_vif)(struct socket *, struct sockopt *); void (*ip_rsvp_force_done)(struct socket *); #endif /* INET */ -extern struct protosw inetsw[]; - u_long rip_sendspace = 9216; SYSCTL_ULONG(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW, &rip_sendspace, 0, "Maximum outgoing raw IP datagram size"); @@ -1070,19 +1068,70 @@ SYSCTL_PROC(_net_inet_raw, OID_AUTO/*XXX*/, pcblist, "List of active raw IP sockets"); #ifdef INET -struct pr_usrreqs rip_usrreqs = { - .pru_abort = rip_abort, - .pru_attach = rip_attach, - .pru_bind = rip_bind, - .pru_connect = rip_connect, - .pru_control = in_control, - .pru_detach = rip_detach, - .pru_disconnect = rip_disconnect, - .pru_peeraddr = in_getpeeraddr, - .pru_send = rip_send, - .pru_shutdown = rip_shutdown, - .pru_sockaddr = in_getsockaddr, - .pru_sosetlabel = in_pcbsosetlabel, - .pru_close = rip_close, +/* + * See comment in in_proto.c containing "protosw definitions are not needed". + */ +#define RAW_PROTOSW \ + .pr_type = SOCK_RAW, \ + .pr_flags = PR_ATOMIC|PR_ADDR, \ + .pr_ctloutput = rip_ctloutput, \ + .pr_abort = rip_abort, \ + .pr_attach = rip_attach, \ + .pr_bind = rip_bind, \ + .pr_connect = rip_connect, \ + .pr_control = in_control, \ + .pr_detach = rip_detach, \ + .pr_disconnect = rip_disconnect, \ + .pr_peeraddr = in_getpeeraddr, \ + .pr_send = rip_send, \ + .pr_shutdown = rip_shutdown, \ + .pr_sockaddr = in_getsockaddr, \ + .pr_sosetlabel = in_pcbsosetlabel, \ + .pr_close = rip_close + +struct protosw rip_protosw = { + .pr_protocol = IPPROTO_RAW, + RAW_PROTOSW +}; +struct protosw icmp_protosw = { + .pr_protocol = IPPROTO_ICMP, + RAW_PROTOSW +}; +struct protosw igmp_protosw = { + .pr_protocol = IPPROTO_IGMP, + RAW_PROTOSW +}; +struct protosw rsvp_protosw = { + .pr_protocol = IPPROTO_RSVP, + RAW_PROTOSW +}; +struct protosw rawipv4_protosw = { + .pr_protocol = IPPROTO_IPV4, + RAW_PROTOSW +}; +struct protosw mobile_protosw = { + .pr_protocol = IPPROTO_MOBILE, + RAW_PROTOSW +}; +struct protosw etherip_protosw = { + .pr_protocol = IPPROTO_ETHERIP, + RAW_PROTOSW +}; +struct protosw gre_protosw = { + .pr_protocol = IPPROTO_GRE, + RAW_PROTOSW +}; +#ifdef INET6 +struct protosw rawipv6_protosw = { + .pr_protocol = IPPROTO_IPV6, + RAW_PROTOSW +}; +#endif +struct protosw pim_protosw = { + .pr_protocol = IPPROTO_PIM, + RAW_PROTOSW +}; +struct protosw ripwild_protosw = { + RAW_PROTOSW }; #endif /* INET */ diff --git a/sys/netinet/sctp_module.c b/sys/netinet/sctp_module.c index ba0d585bd541..a4f294d72e00 100644 --- a/sys/netinet/sctp_module.c +++ b/sys/netinet/sctp_module.c @@ -52,60 +52,16 @@ __FBSDID("$FreeBSD$"); #include <netinet6/ip6_var.h> #include <netinet6/sctp6_var.h> -#ifdef INET -extern struct domain inetdomain; - -struct protosw sctp_stream_protosw = { - .pr_type = SOCK_STREAM, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp_usrreqs, -}; - -struct protosw sctp_seqpacket_protosw = { - .pr_type = SOCK_SEQPACKET, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp_usrreqs, -}; -#endif - -#ifdef INET6 -extern struct domain inet6domain; - -struct protosw sctp6_stream_protosw = { - .pr_type = SOCK_STREAM, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp6_usrreqs, -}; - -struct protosw sctp6_seqpacket_protosw = { - .pr_type = SOCK_SEQPACKET, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp6_usrreqs, -}; -#endif - static int sctp_module_load(void) { int error; #ifdef INET - error = pf_proto_register(PF_INET, &sctp_stream_protosw); + error = protosw_register(&inetdomain, &sctp_stream_protosw); if (error != 0) return (error); - error = pf_proto_register(PF_INET, &sctp_seqpacket_protosw); + error = protosw_register(&inetdomain, &sctp_seqpacket_protosw); if (error != 0) return (error); error = ipproto_register(IPPROTO_SCTP, sctp_input, sctp_ctlinput); @@ -113,10 +69,10 @@ sctp_module_load(void) return (error); #endif #ifdef INET6 - error = pf_proto_register(PF_INET6, &sctp6_stream_protosw); + error = protosw_register(&inet6domain, &sctp6_stream_protosw); if (error != 0) return (error); - error = pf_proto_register(PF_INET6, &sctp6_seqpacket_protosw); + error = protosw_register(&inet6domain, &sctp6_seqpacket_protosw); if (error != 0) return (error); error = ip6proto_register(IPPROTO_SCTP, sctp6_input, sctp6_ctlinput); @@ -137,13 +93,13 @@ sctp_module_unload(void) #ifdef INET (void)ipproto_unregister(IPPROTO_SCTP); - (void)pf_proto_unregister(PF_INET, IPPROTO_SCTP, SOCK_STREAM); - (void)pf_proto_unregister(PF_INET, IPPROTO_SCTP, SOCK_SEQPACKET); + (void)protosw_unregister(&sctp_seqpacket_protosw); + (void)protosw_unregister(&sctp_stream_protosw); #endif #ifdef INET6 (void)ip6proto_unregister(IPPROTO_SCTP); - (void)pf_proto_unregister(PF_INET6, IPPROTO_SCTP, SOCK_STREAM); - (void)pf_proto_unregister(PF_INET6, IPPROTO_SCTP, SOCK_SEQPACKET); + (void)protosw_unregister(&sctp6_seqpacket_protosw); + (void)protosw_unregister(&sctp6_stream_protosw); #endif return (0); } diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 285fbcfbf512..58a9d610b003 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -7526,24 +7526,37 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr) return (0); } -struct pr_usrreqs sctp_usrreqs = { - .pru_abort = sctp_abort, - .pru_accept = sctp_accept, - .pru_attach = sctp_attach, - .pru_bind = sctp_bind, - .pru_connect = sctp_connect, - .pru_control = in_control, - .pru_close = sctp_close, - .pru_detach = sctp_close, - .pru_sopoll = sopoll_generic, - .pru_flush = sctp_flush, - .pru_disconnect = sctp_disconnect, - .pru_listen = sctp_listen, - .pru_peeraddr = sctp_peeraddr, - .pru_send = sctp_sendm, - .pru_shutdown = sctp_shutdown, - .pru_sockaddr = sctp_ingetaddr, - .pru_sosend = sctp_sosend, - .pru_soreceive = sctp_soreceive +#define SCTP_PROTOSW \ + .pr_protocol = IPPROTO_SCTP, \ + .pr_ctloutput = sctp_ctloutput, \ + .pr_abort = sctp_abort, \ + .pr_accept = sctp_accept, \ + .pr_attach = sctp_attach, \ + .pr_bind = sctp_bind, \ + .pr_connect = sctp_connect, \ + .pr_control = in_control, \ + .pr_close = sctp_close, \ + .pr_detach = sctp_close, \ + .pr_sopoll = sopoll_generic, \ + .pr_flush = sctp_flush, \ + .pr_disconnect = sctp_disconnect, \ + .pr_listen = sctp_listen, \ + .pr_peeraddr = sctp_peeraddr, \ + .pr_send = sctp_sendm, \ + .pr_shutdown = sctp_shutdown, \ + .pr_sockaddr = sctp_ingetaddr, \ + .pr_sosend = sctp_sosend, \ + .pr_soreceive = sctp_soreceive \ + +struct protosw sctp_seqpacket_protosw = { + .pr_type = SOCK_SEQPACKET, + .pr_flags = PR_WANTRCVD, + SCTP_PROTOSW +}; + +struct protosw sctp_stream_protosw = { + .pr_type = SOCK_STREAM, + .pr_flags = PR_CONNREQUIRED | PR_WANTRCVD, + SCTP_PROTOSW }; #endif diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index 3bff09adb367..3675ba4443a4 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #if defined(_KERNEL) || defined(__Userspace__) -extern struct pr_usrreqs sctp_usrreqs; +extern struct protosw sctp_seqpacket_protosw, sctp_stream_protosw; #define sctp_feature_on(inp, feature) (inp->sctp_features |= feature) #define sctp_feature_off(inp, feature) (inp->sctp_features &= ~feature) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 51a2e23db6ef..1c04de080623 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1535,10 +1535,10 @@ tcp_init(void *arg __unused) if (tcp_soreceive_stream) { #ifdef INET - tcp_usrreqs.pru_soreceive = soreceive_stream; + tcp_protosw.pr_soreceive = soreceive_stream; #endif #ifdef INET6 - tcp6_usrreqs.pru_soreceive = soreceive_stream; + tcp6_protosw.pr_soreceive = soreceive_stream; #endif /* INET6 */ } diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 1245995724e1..291d6a76bb20 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1462,48 +1462,58 @@ out: } #ifdef INET -struct pr_usrreqs tcp_usrreqs = { - .pru_abort = tcp_usr_abort, - .pru_accept = tcp_usr_accept, - .pru_attach = tcp_usr_attach, - .pru_bind = tcp_usr_bind, - .pru_connect = tcp_usr_connect, - .pru_control = in_control, - .pru_detach = tcp_usr_detach, - .pru_disconnect = tcp_usr_disconnect, - .pru_listen = tcp_usr_listen, - .pru_peeraddr = in_getpeeraddr, - .pru_rcvd = tcp_usr_rcvd, - .pru_rcvoob = tcp_usr_rcvoob, - .pru_send = tcp_usr_send, - .pru_ready = tcp_usr_ready, - .pru_shutdown = tcp_usr_shutdown, - .pru_sockaddr = in_getsockaddr, - .pru_sosetlabel = in_pcbsosetlabel, - .pru_close = tcp_usr_close, +struct protosw tcp_protosw = { + .pr_type = SOCK_STREAM, + .pr_protocol = IPPROTO_TCP, + .pr_flags = PR_CONNREQUIRED | PR_IMPLOPCL | PR_WANTRCVD | + PR_CAPATTACH, + .pr_ctloutput = tcp_ctloutput, + .pr_abort = tcp_usr_abort, + .pr_accept = tcp_usr_accept, + .pr_attach = tcp_usr_attach, + .pr_bind = tcp_usr_bind, + .pr_connect = tcp_usr_connect, + .pr_control = in_control, + .pr_detach = tcp_usr_detach, + .pr_disconnect = tcp_usr_disconnect, + .pr_listen = tcp_usr_listen, + .pr_peeraddr = in_getpeeraddr, + .pr_rcvd = tcp_usr_rcvd, + .pr_rcvoob = tcp_usr_rcvoob, + .pr_send = tcp_usr_send, + .pr_ready = tcp_usr_ready, + .pr_shutdown = tcp_usr_shutdown, + .pr_sockaddr = in_getsockaddr, + .pr_sosetlabel = in_pcbsosetlabel, + .pr_close = tcp_usr_close, }; #endif /* INET */ #ifdef INET6 -struct pr_usrreqs tcp6_usrreqs = { - .pru_abort = tcp_usr_abort, - .pru_accept = tcp6_usr_accept, - .pru_attach = tcp_usr_attach, - .pru_bind = tcp6_usr_bind, - .pru_connect = tcp6_usr_connect, - .pru_control = in6_control, - .pru_detach = tcp_usr_detach, - .pru_disconnect = tcp_usr_disconnect, - .pru_listen = tcp6_usr_listen, - .pru_peeraddr = in6_mapped_peeraddr, - .pru_rcvd = tcp_usr_rcvd, - .pru_rcvoob = tcp_usr_rcvoob, - .pru_send = tcp_usr_send, - .pru_ready = tcp_usr_ready, - .pru_shutdown = tcp_usr_shutdown, - .pru_sockaddr = in6_mapped_sockaddr, - .pru_sosetlabel = in_pcbsosetlabel, - .pru_close = tcp_usr_close, +struct protosw tcp6_protosw = { + .pr_type = SOCK_STREAM, + .pr_protocol = IPPROTO_TCP, + .pr_flags = PR_CONNREQUIRED | PR_IMPLOPCL |PR_WANTRCVD | + PR_CAPATTACH, + .pr_ctloutput = tcp_ctloutput, + .pr_abort = tcp_usr_abort, + .pr_accept = tcp6_usr_accept, + .pr_attach = tcp_usr_attach, + .pr_bind = tcp6_usr_bind, + .pr_connect = tcp6_usr_connect, + .pr_control = in6_control, + .pr_detach = tcp_usr_detach, + .pr_disconnect = tcp_usr_disconnect, + .pr_listen = tcp6_usr_listen, + .pr_peeraddr = in6_mapped_peeraddr, + .pr_rcvd = tcp_usr_rcvd, + .pr_rcvoob = tcp_usr_rcvoob, + .pr_send = tcp_usr_send, + .pr_ready = tcp_usr_ready, + .pr_shutdown = tcp_usr_shutdown, + .pr_sockaddr = in6_mapped_sockaddr, + .pr_sosetlabel = in_pcbsosetlabel, + .pr_close = tcp_usr_close, }; #endif /* INET6 */ diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 62d64f2dbdb2..d80bbef1c51d 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1209,7 +1209,8 @@ uint32_t tcp_hc_getmtu(struct in_conninfo *); void tcp_hc_updatemtu(struct in_conninfo *, uint32_t); void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *); -extern struct pr_usrreqs tcp_usrreqs; +extern struct protosw tcp_protosw; /* shared for TOE */ +extern struct protosw tcp6_protosw; /* shared for TOE */ uint32_t tcp_new_ts_offset(struct in_conninfo *); tcp_seq tcp_new_isn(struct in_conninfo *); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 13fe863ecb75..3cbeb4a5e50f 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1753,22 +1753,34 @@ udp_shutdown(struct socket *so) } #ifdef INET -struct pr_usrreqs udp_usrreqs = { - .pru_abort = udp_abort, - .pru_attach = udp_attach, - .pru_bind = udp_bind, - .pru_connect = udp_connect, - .pru_control = in_control, - .pru_detach = udp_detach, - .pru_disconnect = udp_disconnect, - .pru_peeraddr = in_getpeeraddr, - .pru_send = udp_send, - .pru_soreceive = soreceive_dgram, - .pru_sosend = sosend_dgram, - .pru_shutdown = udp_shutdown, - .pru_sockaddr = in_getsockaddr, - .pru_sosetlabel = in_pcbsosetlabel, - .pru_close = udp_close, +#define UDP_PROTOSW \ + .pr_type = SOCK_DGRAM, \ + .pr_flags = PR_ATOMIC | PR_ADDR | PR_CAPATTACH, \ + .pr_ctloutput = udp_ctloutput, \ + .pr_abort = udp_abort, \ + .pr_attach = udp_attach, \ + .pr_bind = udp_bind, \ + .pr_connect = udp_connect, \ + .pr_control = in_control, \ + .pr_detach = udp_detach, \ + .pr_disconnect = udp_disconnect, \ + .pr_peeraddr = in_getpeeraddr, \ + .pr_send = udp_send, \ + .pr_soreceive = soreceive_dgram, \ + .pr_sosend = sosend_dgram, \ + .pr_shutdown = udp_shutdown, \ + .pr_sockaddr = in_getsockaddr, \ + .pr_sosetlabel = in_pcbsosetlabel, \ + .pr_close = udp_close + +struct protosw udp_protosw = { + .pr_protocol = IPPROTO_UDP, + UDP_PROTOSW +}; + +struct protosw udplite_protosw = { + .pr_protocol = IPPROTO_UDPLITE, + UDP_PROTOSW }; static void diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 8da2592054af..5fb86aa656b2 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -141,7 +141,6 @@ void kmod_udpstat_inc(int statnum); #include <netinet/in_pcb.h> SYSCTL_DECL(_net_inet_udp); -extern struct pr_usrreqs udp_usrreqs; VNET_DECLARE(struct inpcbinfo, udbinfo); VNET_DECLARE(struct inpcbinfo, ulitecbinfo); #define V_udbinfo VNET(udbinfo) diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 963b6a8d9aed..72b84c915641 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -121,179 +121,63 @@ __FBSDID("$FreeBSD$"); #include <netinet6/ip6protosw.h> +/* netinet6/raw_ip6.c */ +extern struct protosw rip6_protosw, icmp6_protosw, dstopts6_protosw, + routing6_protosw, frag6_protosw, rawipv4in6_protosw, rawipv6in6_protosw, + etherip6_protosw, gre6_protosw, pim6_protosw, rip6wild_protosw; +/* netinet6/udp6_usrreq.c */ +extern struct protosw udp6_protosw, udplite6_protosw; + /* * TCP/IP protocol family: IP6, ICMP6, UDP, TCP. */ FEATURE(inet6, "Internet Protocol version 6"); -extern struct domain inet6domain; -static struct pr_usrreqs nousrreqs; - -#define PR_LISTEN 0 -#define PR_ABRTACPTDIS 0 - -/* Spacer for loadable protocols. */ -#define IP6PROTOSPACER \ -{ \ - .pr_domain = &inet6domain, \ - .pr_protocol = PROTO_SPACER, \ - .pr_usrreqs = &nousrreqs \ -} - -struct protosw inet6sw[] = { -{ - .pr_type = SOCK_DGRAM, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_UDP, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_CAPATTACH, - .pr_ctloutput = ip6_ctloutput, - .pr_usrreqs = &udp6_usrreqs, -}, -{ - .pr_type = SOCK_STREAM, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_TCP, - .pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD| - PR_LISTEN|PR_CAPATTACH, - .pr_ctloutput = tcp_ctloutput, - .pr_usrreqs = &tcp6_usrreqs, -}, -#ifdef SCTP -{ - .pr_type = SOCK_SEQPACKET, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp6_usrreqs -}, -{ - .pr_type = SOCK_STREAM, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, - .pr_ctloutput = sctp_ctloutput, - .pr_usrreqs = &sctp6_usrreqs -}, -#endif /* SCTP */ -{ - .pr_type = SOCK_DGRAM, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_UDPLITE, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_CAPATTACH, - .pr_ctloutput = udp_ctloutput, - .pr_usrreqs = &udp6_usrreqs, -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_RAW, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_ICMPV6, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_DSTOPTS, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &nousrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_ROUTING, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &nousrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_FRAGMENT, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &nousrreqs -}, -#ifdef INET -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_IPV4, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -#endif /* INET */ -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_IPV6, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_ETHERIP, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_GRE, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_protocol = IPPROTO_PIM, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -/* Spacer n-times for loadable protocols. */ -IP6PROTOSPACER, -IP6PROTOSPACER, -IP6PROTOSPACER, -IP6PROTOSPACER, -IP6PROTOSPACER, -IP6PROTOSPACER, -IP6PROTOSPACER, -IP6PROTOSPACER, -/* raw wildcard */ -{ - .pr_type = SOCK_RAW, - .pr_domain = &inet6domain, - .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_ctloutput = rip6_ctloutput, - .pr_usrreqs = &rip6_usrreqs -}, -}; - struct domain inet6domain = { .dom_family = AF_INET6, .dom_name = "internet6", - .dom_protosw = (struct protosw *)inet6sw, - .dom_protoswNPROTOSW = (struct protosw *)&inet6sw[nitems(inet6sw)], .dom_rtattach = in6_inithead, #ifdef VIMAGE .dom_rtdetach = in6_detachhead, #endif .dom_ifattach = in6_domifattach, .dom_ifdetach = in6_domifdetach, - .dom_ifmtu = in6_domifmtu + .dom_ifmtu = in6_domifmtu, + .dom_nprotosw = 24, + .dom_protosw = { + &tcp6_protosw, + &udp6_protosw, +#ifdef SCTP + &sctp6_seqpacket_protosw, + &sctp6_stream_protosw, +#else + NULL, NULL, +#endif + &udplite6_protosw, + &rip6_protosw, + /* + * XXXGL: it is entirely possible that all below raw-based + * protosw definitions are not needed. They could have existed + * just to define pr_input, pr_drain, pr_*timo or PR_LASTHDR + * flag, and were never supposed to create a special socket. + */ + &icmp6_protosw, + &dstopts6_protosw, + &routing6_protosw, + &frag6_protosw, +#ifdef INET + &rawipv4in6_protosw, +#else + NULL, +#endif + &rawipv6in6_protosw, + ðerip6_protosw, + &gre6_protosw, + &pim6_protosw, + /* Spacer 8 times for loadable protocols. XXXGL: why 8? */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &rip6wild_protosw, + }, }; DOMAIN_SET(inet6); diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 678121b0ca32..091e90b0eaed 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -869,17 +869,66 @@ rip6_shutdown(struct socket *so) return (0); } -struct pr_usrreqs rip6_usrreqs = { - .pru_abort = rip6_abort, - .pru_attach = rip6_attach, - .pru_bind = rip6_bind, - .pru_connect = rip6_connect, - .pru_control = in6_control, - .pru_detach = rip6_detach, - .pru_disconnect = rip6_disconnect, - .pru_peeraddr = in6_getpeeraddr, - .pru_send = rip6_send, - .pru_shutdown = rip6_shutdown, - .pru_sockaddr = in6_getsockaddr, - .pru_close = rip6_close, +/* + * See comment in in6_proto.c containing "protosw definitions are not needed". + */ +#define RAW6_PROTOSW \ + .pr_type = SOCK_RAW, \ + .pr_flags = PR_ATOMIC|PR_ADDR, \ + .pr_ctloutput = rip6_ctloutput, \ + .pr_abort = rip6_abort, \ + .pr_attach = rip6_attach, \ + .pr_bind = rip6_bind, \ + .pr_connect = rip6_connect, \ + .pr_control = in6_control, \ + .pr_detach = rip6_detach, \ + .pr_disconnect = rip6_disconnect, \ + .pr_peeraddr = in6_getpeeraddr, \ + .pr_send = rip6_send, \ + .pr_shutdown = rip6_shutdown, \ + .pr_sockaddr = in6_getsockaddr, \ + .pr_close = rip6_close + +struct protosw rip6_protosw = { + .pr_protocol = IPPROTO_RAW, + RAW6_PROTOSW +}; +struct protosw icmp6_protosw = { + .pr_protocol = IPPROTO_ICMPV6, + RAW6_PROTOSW +}; +struct protosw dstopts6_protosw = { + .pr_protocol = IPPROTO_DSTOPTS, + RAW6_PROTOSW +}; +struct protosw routing6_protosw = { + .pr_protocol = IPPROTO_ROUTING, + RAW6_PROTOSW +}; +struct protosw frag6_protosw = { + .pr_protocol = IPPROTO_FRAGMENT, + RAW6_PROTOSW +}; +struct protosw rawipv4in6_protosw = { + .pr_protocol = IPPROTO_IPV4, + RAW6_PROTOSW +}; +struct protosw rawipv6in6_protosw = { + .pr_protocol = IPPROTO_IPV6, + RAW6_PROTOSW +}; +struct protosw etherip6_protosw = { + .pr_protocol = IPPROTO_ETHERIP, + RAW6_PROTOSW +}; +struct protosw gre6_protosw = { + .pr_protocol = IPPROTO_GRE, + RAW6_PROTOSW +}; +struct protosw pim6_protosw = { + .pr_protocol = IPPROTO_PIM, + RAW6_PROTOSW +}; +struct protosw rip6wild_protosw = { + RAW6_PROTOSW }; diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index 361bc4a18a2f..b14d7d10451a 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -1199,25 +1199,37 @@ sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam) return (error); } -struct pr_usrreqs sctp6_usrreqs = { - .pru_abort = sctp6_abort, - .pru_accept = sctp_accept, - .pru_attach = sctp6_attach, - .pru_bind = sctp6_bind, - .pru_connect = sctp6_connect, - .pru_control = in6_control, - .pru_close = sctp6_close, - .pru_detach = sctp6_close, - .pru_sopoll = sopoll_generic, - .pru_flush = sctp_flush, - .pru_disconnect = sctp6_disconnect, - .pru_listen = sctp_listen, - .pru_peeraddr = sctp6_getpeeraddr, - .pru_send = sctp6_send, - .pru_shutdown = sctp_shutdown, - .pru_sockaddr = sctp6_in6getaddr, - .pru_sosend = sctp_sosend, - .pru_soreceive = sctp_soreceive +#define SCTP6_PROTOSW \ + .pr_protocol = IPPROTO_SCTP, \ + .pr_ctloutput = sctp_ctloutput, \ + .pr_abort = sctp6_abort, \ + .pr_accept = sctp_accept, \ + .pr_attach = sctp6_attach, \ + .pr_bind = sctp6_bind, \ + .pr_connect = sctp6_connect, \ + .pr_control = in6_control, \ + .pr_close = sctp6_close, \ + .pr_detach = sctp6_close, \ + .pr_sopoll = sopoll_generic, \ + .pr_flush = sctp_flush, \ + .pr_disconnect = sctp6_disconnect, \ + .pr_listen = sctp_listen, \ + .pr_peeraddr = sctp6_getpeeraddr, \ + .pr_send = sctp6_send, \ + .pr_shutdown = sctp_shutdown, \ + .pr_sockaddr = sctp6_in6getaddr, \ + .pr_sosend = sctp_sosend, \ + .pr_soreceive = sctp_soreceive + +struct protosw sctp6_seqpacket_protosw = { + .pr_type = SOCK_SEQPACKET, + .pr_flags = PR_WANTRCVD, + SCTP6_PROTOSW }; +struct protosw sctp6_stream_protosw = { + .pr_type = SOCK_STREAM, + .pr_flags = PR_CONNREQUIRED | PR_WANTRCVD, + SCTP6_PROTOSW +}; #endif diff --git a/sys/netinet6/sctp6_var.h b/sys/netinet6/sctp6_var.h index 4ad0ca2811c1..74a24f425cea 100644 --- a/sys/netinet6/sctp6_var.h +++ b/sys/netinet6/sctp6_var.h @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); #if defined(_KERNEL) SYSCTL_DECL(_net_inet6_sctp6); -extern struct pr_usrreqs sctp6_usrreqs; +extern struct protosw sctp6_seqpacket_protosw, sctp6_stream_protosw; int sctp6_input(struct mbuf **, int *, int); int sctp6_input_with_port(struct mbuf **, int *, uint16_t); diff --git a/sys/netinet6/send.c b/sys/netinet6/send.c index 736039c695af..0684e2eea22c 100644 --- a/sys/netinet6/send.c +++ b/sys/netinet6/send.c @@ -318,16 +318,13 @@ send_input(struct mbuf *m, struct ifnet *ifp, int direction, int msglen __unused return (0); } -struct pr_usrreqs send_usrreqs = { - .pru_attach = send_attach, - .pru_send = send_send, - .pru_detach = send_close -}; -struct protosw send_protosw = { +static struct protosw send_protosw = { .pr_type = SOCK_RAW, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_protocol = IPPROTO_SEND, - .pr_usrreqs = &send_usrreqs + .pr_attach = send_attach, + .pr_send = send_send, + .pr_detach = send_close }; static int @@ -342,7 +339,7 @@ send_modevent(module_t mod, int type, void *unused) case MOD_LOAD: SEND_LOCK_INIT(); - error = pf_proto_register(PF_INET6, &send_protosw); + error = protosw_register(&inet6domain, &send_protosw); if (error != 0) { printf("%s:%d: MOD_LOAD pf_proto_register(): %d\n", __func__, __LINE__, error); @@ -369,7 +366,7 @@ send_modevent(module_t mod, int type, void *unused) } SEND_UNLOCK(); VNET_LIST_RUNLOCK_NOSLEEP(); - error = pf_proto_unregister(PF_INET6, IPPROTO_SEND, SOCK_RAW); + error = protosw_unregister(&send_protosw); if (error == 0) SEND_LOCK_DESTROY(); send_sendso_input_hook = NULL; diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 13a44530ce67..81cea4d8036f 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -1322,22 +1322,34 @@ bad: return (error); } -struct pr_usrreqs udp6_usrreqs = { - .pru_abort = udp6_abort, - .pru_attach = udp6_attach, - .pru_bind = udp6_bind, - .pru_connect = udp6_connect, - .pru_control = in6_control, - .pru_detach = udp6_detach, - .pru_disconnect = udp6_disconnect, - .pru_peeraddr = in6_mapped_peeraddr, - .pru_send = udp6_send, - .pru_shutdown = udp_shutdown, - .pru_sockaddr = in6_mapped_sockaddr, - .pru_soreceive = soreceive_dgram, - .pru_sosend = sosend_dgram, - .pru_sosetlabel = in_pcbsosetlabel, - .pru_close = udp6_close +#define UDP6_PROTOSW \ + .pr_type = SOCK_DGRAM, \ + .pr_flags = PR_ATOMIC|PR_ADDR|PR_CAPATTACH, \ + .pr_ctloutput = ip6_ctloutput, \ + .pr_abort = udp6_abort, \ + .pr_attach = udp6_attach, \ + .pr_bind = udp6_bind, \ + .pr_connect = udp6_connect, \ + .pr_control = in6_control, \ + .pr_detach = udp6_detach, \ + .pr_disconnect = udp6_disconnect, \ + .pr_peeraddr = in6_mapped_peeraddr, \ + .pr_send = udp6_send, \ + .pr_shutdown = udp_shutdown, \ + .pr_sockaddr = in6_mapped_sockaddr, \ + .pr_soreceive = soreceive_dgram, \ + .pr_sosend = sosend_dgram, \ + .pr_sosetlabel = in_pcbsosetlabel, \ + .pr_close = udp6_close + +struct protosw udp6_protosw = { + .pr_protocol = IPPROTO_UDP, + UDP6_PROTOSW +}; + +struct protosw udplite6_protosw = { + .pr_protocol = IPPROTO_UDPLITE, + UDP6_PROTOSW }; static void diff --git a/sys/netipsec/keysock.c b/sys/netipsec/keysock.c index 8c95bc775c73..d0ab2f6020ec 100644 --- a/sys/netipsec/keysock.c +++ b/sys/netipsec/keysock.c @@ -318,39 +318,25 @@ key_shutdown(struct socket *so) return (0); } -struct pr_usrreqs key_usrreqs = { - .pru_abort = key_close, - .pru_attach = key_attach, - .pru_detach = key_detach, - .pru_send = key_send, - .pru_shutdown = key_shutdown, - .pru_close = key_close, -}; - -/* sysctl */ SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Key Family"); -/* - * Definitions of protocols supported in the KEY domain. - */ - -extern struct domain keydomain; - -struct protosw keysw[] = { -{ +static struct protosw keysw = { .pr_type = SOCK_RAW, - .pr_domain = &keydomain, .pr_protocol = PF_KEY_V2, .pr_flags = PR_ATOMIC|PR_ADDR, - .pr_usrreqs = &key_usrreqs -} + .pr_abort = key_close, + .pr_attach = key_attach, + .pr_detach = key_detach, + .pr_send = key_send, + .pr_shutdown = key_shutdown, + .pr_close = key_close, }; -struct domain keydomain = { +static struct domain keydomain = { .dom_family = PF_KEY, .dom_name = "key", - .dom_protosw = keysw, - .dom_protoswNPROTOSW = &keysw[nitems(keysw)] + .dom_nprotosw = 1, + .dom_protosw = { &keysw }, }; DOMAIN_SET(key); diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c index b5de5ed11b00..7a4403488ecf 100644 --- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c @@ -1195,7 +1195,7 @@ soreceive_rcvoob(struct socket *so, struct uio *uio, int flags) KASSERT(flags & MSG_OOB, ("soreceive_rcvoob: (flags & MSG_OOB) == 0")); m = m_get(M_WAITOK, MT_DATA); - error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK); + error = pr->pr_rcvoob(so, m, flags & MSG_PEEK); if (error) goto bad; do { @@ -1876,51 +1876,45 @@ sdp_init(void *arg __unused) } SYSINIT(sdp_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND, sdp_init, NULL); -extern struct domain sdpdomain; - -struct pr_usrreqs sdp_usrreqs = { - .pru_abort = sdp_abort, - .pru_accept = sdp_accept, - .pru_attach = sdp_attach, - .pru_bind = sdp_bind, - .pru_connect = sdp_connect, - .pru_detach = sdp_detach, - .pru_disconnect = sdp_disconnect, - .pru_listen = sdp_listen, - .pru_peeraddr = sdp_getpeeraddr, - .pru_rcvoob = sdp_rcvoob, - .pru_send = sdp_send, - .pru_sosend = sdp_sosend, - .pru_soreceive = sdp_sorecv, - .pru_shutdown = sdp_shutdown, - .pru_sockaddr = sdp_getsockaddr, - .pru_close = sdp_close, -}; - -struct protosw sdpsw[] = { -{ - .pr_type = SOCK_STREAM, - .pr_domain = &sdpdomain, +#define SDP_PROTOSW \ + .pr_type = SOCK_STREAM, \ + .pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD,\ + .pr_ctloutput = sdp_ctloutput, \ + .pr_abort = sdp_abort, \ + .pr_accept = sdp_accept, \ + .pr_attach = sdp_attach, \ + .pr_bind = sdp_bind, \ + .pr_connect = sdp_connect, \ + .pr_detach = sdp_detach, \ + .pr_disconnect = sdp_disconnect, \ + .pr_listen = sdp_listen, \ + .pr_peeraddr = sdp_getpeeraddr, \ + .pr_rcvoob = sdp_rcvoob, \ + .pr_send = sdp_send, \ + .pr_sosend = sdp_sosend, \ + .pr_soreceive = sdp_sorecv, \ + .pr_shutdown = sdp_shutdown, \ + .pr_sockaddr = sdp_getsockaddr, \ + .pr_close = sdp_close + + +static struct protosw sdp_ip_protosw = { .pr_protocol = IPPROTO_IP, - .pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD, - .pr_ctloutput = sdp_ctloutput, - .pr_usrreqs = &sdp_usrreqs -}, -{ - .pr_type = SOCK_STREAM, - .pr_domain = &sdpdomain, + SDP_PROTOSW +}; +static struct protosw sdp_tcp_protosw = { .pr_protocol = IPPROTO_TCP, - .pr_flags = PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD, - .pr_ctloutput = sdp_ctloutput, - .pr_usrreqs = &sdp_usrreqs -}, + SDP_PROTOSW }; -struct domain sdpdomain = { +static struct domain sdpdomain = { .dom_family = AF_INET_SDP, .dom_name = "SDP", - .dom_protosw = sdpsw, - .dom_protoswNPROTOSW = &sdpsw[sizeof(sdpsw)/sizeof(sdpsw[0])], + .dom_nprotosw = 2, + .dom_protosw = { + &sdp_ip_protosw, + &sdp_tcp_protosw, + }, }; DOMAIN_SET(sdp); diff --git a/sys/rpc/rpc_generic.c b/sys/rpc/rpc_generic.c index d75f23493f90..0e1797272a03 100644 --- a/sys/rpc/rpc_generic.c +++ b/sys/rpc/rpc_generic.c @@ -195,7 +195,7 @@ __rpc_socket2sockinfo(struct socket *so, struct __rpc_sockinfo *sip) int error; CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) return 0; @@ -708,7 +708,7 @@ __rpc_sockisbound(struct socket *so) int error, bound; CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) return (0); @@ -798,7 +798,7 @@ bindresvport(struct socket *so, struct sockaddr *sa) if (sa == NULL) { CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) return (error); diff --git a/sys/rpc/svc_dg.c b/sys/rpc/svc_dg.c index db1928655618..4ab86bb5904a 100644 --- a/sys/rpc/svc_dg.c +++ b/sys/rpc/svc_dg.c @@ -127,7 +127,7 @@ svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize, xprt->xp_ops = &svc_dg_ops; CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) goto freedata; diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index b8b22fb7f4cf..8b11cdf82e8b 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -159,7 +159,7 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) { SOCK_UNLOCK(so); CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa); + error = so->so_proto->pr_peeraddr(so, &sa); CURVNET_RESTORE(); if (error) return (NULL); @@ -178,7 +178,7 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, xprt->xp_ops = &svc_vc_rendezvous_ops; CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) { goto cleanup_svc_vc_create; @@ -262,7 +262,7 @@ svc_vc_create_conn(SVCPOOL *pool, struct socket *so, struct sockaddr *raddr) memcpy(&xprt->xp_rtaddr, raddr, raddr->sa_len); CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + error = so->so_proto->pr_sockaddr(so, &sa); CURVNET_RESTORE(); if (error) goto cleanup_svc_vc_create; diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c index d55487897522..4b3d6ccfb90c 100644 --- a/sys/security/mac/mac_socket.c +++ b/sys/security/mac/mac_socket.c @@ -516,8 +516,8 @@ mac_socket_label_set(struct ucred *cred, struct socket *so, * from the socket, notify it of the label change while holding the * socket lock. */ - if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL) - (so->so_proto->pr_usrreqs->pru_sosetlabel)(so); + if (so->so_proto->pr_sosetlabel != NULL) + so->so_proto->pr_sosetlabel(so); return (0); } diff --git a/sys/sys/domain.h b/sys/sys/domain.h index 3a1c30e163ed..af4dbf0be9ee 100644 --- a/sys/sys/domain.h +++ b/sys/sys/domain.h @@ -49,6 +49,7 @@ struct rib_head; struct domain { int dom_family; /* AF_xxx */ + u_int dom_nprotosw; /* length of dom_protosw[] */ char *dom_name; int dom_flags; int (*dom_probe)(void); /* check for support (optional) */ @@ -56,7 +57,6 @@ struct domain { (struct mbuf *, struct mbuf **, int); void (*dom_dispose) /* dispose of internalized rights */ (struct socket *); - struct protosw *dom_protosw, *dom_protoswNPROTOSW; struct domain *dom_next; struct rib_head *(*dom_rtattach) /* initialize routing table */ (uint32_t); @@ -66,6 +66,7 @@ struct domain { void (*dom_ifdetach)(struct ifnet *, void *); int (*dom_ifmtu)(struct ifnet *); /* af-dependent data on ifnet */ + struct protosw *dom_protosw[]; }; /* dom_flags */ diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 965c363afce1..f6907505178e 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -107,24 +107,46 @@ typedef int pr_aio_queue_t(struct socket *, struct kaiocb *); struct protosw { short pr_type; /* socket type used for */ - struct domain *pr_domain; /* domain protocol a member of */ short pr_protocol; /* protocol number */ short pr_flags; /* see below */ -/* protocol-protocol hooks */ - pr_ctloutput_t *pr_ctloutput; /* control output (from above) */ -/* utility hooks */ - - struct pr_usrreqs *pr_usrreqs; /* user-protocol hook */ + short pr_unused; + struct domain *pr_domain; /* domain protocol a member of */ + + pr_soreceive_t *pr_soreceive; /* recv(2) */ + pr_rcvd_t *pr_rcvd; /* soreceive_generic() if PR_WANTRCVD */ + pr_sosend_t *pr_sosend; /* send(2) */ + pr_send_t *pr_send; /* send(2) via sosend_generic() */ + pr_ready_t *pr_ready; /* sendfile/ktls readyness */ + pr_sopoll_t *pr_sopoll; /* poll(2) */ +/* Cache line #2 */ + pr_attach_t *pr_attach; /* creation: socreate(), sonewconn() */ + pr_detach_t *pr_detach; /* destruction: sofree() */ + pr_connect_t *pr_connect; /* connect(2) */ + pr_disconnect_t *pr_disconnect; /* sodisconnect() */ + pr_close_t *pr_close; /* close(2) */ + pr_shutdown_t *pr_shutdown; /* shutdown(2) */ + pr_abort_t *pr_abort; /* abrupt tear down: soabort() */ + pr_aio_queue_t *pr_aio_queue; /* aio(9) */ +/* Cache line #3 */ + pr_bind_t *pr_bind; /* bind(2) */ + pr_bindat_t *pr_bindat; /* bindat(2) */ + pr_listen_t *pr_listen; /* listen(2) */ + pr_accept_t *pr_accept; /* accept(2) */ + pr_connectat_t *pr_connectat; /* connectat(2) */ + pr_connect2_t *pr_connect2; /* socketpair(2) */ + pr_control_t *pr_control; /* ioctl(2) */ + pr_rcvoob_t *pr_rcvoob; /* soreceive_rcvoob() */ +/* Cache line #4 */ + pr_ctloutput_t *pr_ctloutput; /* control output (from above) */ + pr_peeraddr_t *pr_peeraddr; /* getpeername(2) */ + pr_sockaddr_t *pr_sockaddr; /* getsockname(2) */ + pr_sense_t *pr_sense; /* stat(2) */ + pr_flush_t *pr_flush; /* XXXGL: merge with pr_shutdown_t! */ + pr_sosetlabel_t *pr_sosetlabel; /* MAC, XXXGL: remove */ }; /*#endif*/ /* - * This number should be defined again within each protocol family to avoid - * confusion. - */ -#define PROTO_SPACER 32767 /* spacer for loadable protocols */ - -/* * Values for pr_flags. * PR_ADDR requires PR_ATOMIC; * PR_ADDR and PR_CONNREQUIRED are mutually exclusive. @@ -145,88 +167,6 @@ struct protosw { #define PR_CAPATTACH 0x80 /* socket can attach in cap mode */ #define PR_SOCKBUF 0x100 /* private implementation of buffers */ -#ifdef _KERNEL /* users shouldn't see this decl */ - -struct ifnet; -struct stat; -struct ucred; -struct uio; - -/* - * If the ordering here looks odd, that's because it's alphabetical. These - * should eventually be merged back into struct protosw. - * - * Some fields initialized to defaults if they are NULL. - */ -struct pr_usrreqs { - pr_abort_t *pru_abort; - pr_accept_t *pru_accept; - pr_attach_t *pru_attach; - pr_bind_t *pru_bind; - pr_connect_t *pru_connect; - pr_connect2_t *pru_connect2; - pr_control_t *pru_control; - pr_detach_t *pru_detach; - pr_disconnect_t *pru_disconnect; - pr_listen_t *pru_listen; - pr_peeraddr_t *pru_peeraddr; - pr_rcvd_t *pru_rcvd; - pr_rcvoob_t *pru_rcvoob; - pr_send_t *pru_send; - pr_ready_t *pru_ready; - pr_sense_t *pru_sense; - pr_shutdown_t *pru_shutdown; - pr_flush_t *pru_flush; - pr_sockaddr_t *pru_sockaddr; - pr_sosend_t *pru_sosend; - pr_soreceive_t *pru_soreceive; - pr_sopoll_t *pru_sopoll; - pr_sosetlabel_t *pru_sosetlabel; - pr_close_t *pru_close; - pr_bindat_t *pru_bindat; - pr_connectat_t *pru_connectat; - pr_aio_queue_t *pru_aio_queue; -}; - -/* - * All nonvoid pru_*() functions below return EOPNOTSUPP. - */ -int pru_accept_notsupp(struct socket *so, struct sockaddr **nam); -int pru_aio_queue_notsupp(struct socket *so, struct kaiocb *job); -int pru_attach_notsupp(struct socket *so, int proto, struct thread *td); -int pru_bind_notsupp(struct socket *so, struct sockaddr *nam, - struct thread *td); -int pru_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam, - struct thread *td); -int pru_connect_notsupp(struct socket *so, struct sockaddr *nam, - struct thread *td); -int pru_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam, - struct thread *td); -int pru_connect2_notsupp(struct socket *so1, struct socket *so2); -int pru_control_notsupp(struct socket *so, u_long cmd, void *data, - struct ifnet *ifp, struct thread *td); -int pru_disconnect_notsupp(struct socket *so); -int pru_listen_notsupp(struct socket *so, int backlog, struct thread *td); -int pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam); -int pru_rcvd_notsupp(struct socket *so, int flags); -int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags); -int pru_send_notsupp(struct socket *so, int flags, struct mbuf *m, - struct sockaddr *addr, struct mbuf *control, struct thread *td); -int pru_ready_notsupp(struct socket *so, struct mbuf *m, int count); -int pru_sense_null(struct socket *so, struct stat *sb); -int pru_shutdown_notsupp(struct socket *so); -int pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam); -int pru_sosend_notsupp(struct socket *so, struct sockaddr *addr, - struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, - struct thread *td); -int pru_soreceive_notsupp(struct socket *so, struct sockaddr **paddr, - struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, - int *flagsp); -int pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred, - struct thread *td); - -#endif /* _KERNEL */ - /* * The arguments to the ctlinput routine are * (*protosw[].pr_ctlinput)(cmd, sa, arg); @@ -298,8 +238,12 @@ char *prcorequests[] = { struct domain *pffinddomain(int family); struct protosw *pffindproto(int family, int protocol, int type); struct protosw *pffindtype(int family, int type); -int pf_proto_register(int family, struct protosw *npr); -int pf_proto_unregister(int family, int protocol, int type); +int protosw_register(struct domain *, struct protosw *); +int protosw_unregister(struct protosw *); + +/* Domains that are known to be avaliable for protosw_register(). */ +extern struct domain inetdomain; +extern struct domain inet6domain; #endif #endif |