protosw: refactor protosw and domain static declaration and load

o Assert that every protosw has pr_attach.  Now this structure is
  only for socket protocols declarations and nothing else.
o Merge struct pr_usrreqs into struct protosw.  This was suggested
  in 1996 by wollman@ (see 7b187005d1), and later reiterated
  in 2006 by rwatson@ (see 6fbb9cf860).
o Make struct domain hold a variable sized array of protosw pointers.
  For most protocols these pointers are initialized statically.
  Those domains that may have loadable protocols have spacers. IPv4
  and IPv6 have 8 spacers each (andre@ dff3237ee5).
o For inetsw and inet6sw leave a comment noting that many protosw
  entries very likely are dead code.
o Refactor pf_proto_[un]register() into protosw_[un]register().
o Isolate pr_*_notsupp() methods into uipc_domain.c

Reviewed by:		melifaro
Differential revision:	https://reviews.freebsd.org/D36232
This commit is contained in:
Gleb Smirnoff 2022-08-17 11:50:32 -07:00
parent d9f6ac882a
commit e7d02be19d
44 changed files with 1037 additions and 1460 deletions

View file

@ -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;

View file

@ -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;
bcopy(&tcp_protosw, &toe_protosw, sizeof(toe_protosw));
toe_protosw.pr_aio_queue = t4_aio_queue_tom;
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(&tcp6_protosw, &toe6_protosw, sizeof(toe6_protosw));
toe6_protosw.pr_aio_queue = t4_aio_queue_tom;
return (t4_register_uld(&tom_uld_info));
}

View file

@ -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_);

View file

@ -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 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
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 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
}
} 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();

View file

@ -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);

View file

@ -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 int
pr_shutdown_notsupp(struct socket *so)
{
return (EOPNOTSUPP);
}
static int
pr_sockaddr_notsupp(struct socket *so, struct sockaddr **nam)
{
return (EOPNOTSUPP);
}
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);
}
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_usrreqs_init(struct protosw *pr)
pr_init(struct protosw *pr)
{
struct pr_usrreqs *pu;
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)));
KASSERT(pr->pr_attach != NULL,
("%s: protocol doesn't have pr_attach", __func__));
/*
* 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
#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 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
#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;
struct protosw **prp;
/* 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);
/* 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);

View file

@ -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);
}

View file

@ -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 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
*/
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 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
(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 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio,
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 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio,
(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 @@ soreceive_stream(struct socket *so, struct sockaddr **psa, struct uio *uio,
!(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)
{

View file

@ -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;

View file

@ -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)
{
@ -3426,6 +3310,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

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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,
},
};
/*

View file

@ -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);

View file

@ -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)

View file

@ -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 },
};
/*

View file

@ -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
/* 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;
FEATURE(inet, "Internet Protocol version 4");
extern struct domain inetdomain;
/* 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
},
};
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,
&etherip_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);

View file

@ -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);

View file

@ -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,

View file

@ -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)

View file

@ -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 */

View file

@ -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);
}

View file

@ -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

View file

@ -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)

View file

@ -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 */
}

View file

@ -1462,48 +1462,58 @@ tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
}
#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 */

View file

@ -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 *);

View file

@ -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

View file

@ -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)

View file

@ -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,
&etherip6_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);

View file

@ -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
};

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -1322,22 +1322,34 @@ udp6_send(struct socket *so, int flags, struct mbuf *m,
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

View file

@ -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);

View file

@ -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;
#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
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,
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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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 */

View file

@ -107,23 +107,45 @@ 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 */
short pr_unused;
struct domain *pr_domain; /* domain protocol a member of */
struct pr_usrreqs *pr_usrreqs; /* user-protocol hook */
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;
@ -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