svn commit: r272823 - in head/sys: compat/freebsd32 conf kern netinet sys

Marcel Moolenaar marcel at FreeBSD.org
Thu Oct 9 15:16:54 UTC 2014


Author: marcel
Date: Thu Oct  9 15:16:52 2014
New Revision: 272823
URL: https://svnweb.freebsd.org/changeset/base/272823

Log:
  Move the SCTP syscalls to netinet with the rest of the SCTP code.  The
  syscalls themselves are tightly coupled with the network stack and
  therefore should not be in the generic socket code.
  
  The following four syscalls have been marked as NOSTD so they can be
  dynamically registered in sctp_syscalls_init() function:
    sys_sctp_peeloff
    sys_sctp_generic_sendmsg
    sys_sctp_generic_sendmsg_iov
    sys_sctp_generic_recvmsg
  
  The syscalls are also set up to be dynamically registered when COMPAT32
  option is configured.
  
  As a side effect of moving the SCTP syscalls, getsock_cap needs to be
  made available outside of the uipc_syscalls.c source file.  A proper
  prototype has been added to the sys/socketvar.h header file.
  
  API tests from the SCTP reference implementation have been run to ensure
  compatibility. (http://code.google.com/p/sctp-refimpl/source/checkout)
  
  Submitted by:	Steve Kiernan <stevek at juniper.net>
  Reviewed by:	tuexen, rrs
  Obtained from:	Juniper Networks, Inc.

Added:
  head/sys/netinet/sctp_syscalls.c
     - copied, changed from r272821, head/sys/kern/uipc_syscalls.c
Modified:
  head/sys/compat/freebsd32/syscalls.master
  head/sys/conf/files
  head/sys/kern/syscalls.master
  head/sys/kern/uipc_syscalls.c
  head/sys/sys/socketvar.h

Modified: head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- head/sys/compat/freebsd32/syscalls.master	Thu Oct  9 14:43:43 2014	(r272822)
+++ head/sys/compat/freebsd32/syscalls.master	Thu Oct  9 15:16:52 2014	(r272823)
@@ -845,14 +845,14 @@
 468	AUE_NULL	UNIMPL	nosys
 469	AUE_NULL	UNIMPL	__getpath_fromfd
 470	AUE_NULL	UNIMPL	__getpath_fromaddr
-471	AUE_NULL	NOPROTO	{ int sctp_peeloff(int sd, uint32_t name); }
-472	AUE_NULL	NOPROTO	{ int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
+471	AUE_NULL	NOPROTO|NOSTD	{ int sctp_peeloff(int sd, uint32_t name); }
+472	AUE_NULL	NOPROTO|NOSTD	{ int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
 				    caddr_t to, __socklen_t tolen, \
 				    struct sctp_sndrcvinfo *sinfo, int flags); }
-473	AUE_NULL	NOPROTO	{ int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
+473	AUE_NULL	NOPROTO|NOSTD	{ int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
 				    caddr_t to, __socklen_t tolen, \
 				    struct sctp_sndrcvinfo *sinfo, int flags); }
-474	AUE_NULL	NOPROTO	{ int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
+474	AUE_NULL	NOPROTO|NOSTD	{ int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
 				    struct sockaddr * from, __socklen_t *fromlenaddr, \
 				    struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
 #ifdef PAD64_REQUIRED

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Thu Oct  9 14:43:43 2014	(r272822)
+++ head/sys/conf/files	Thu Oct  9 15:16:52 2014	(r272823)
@@ -3429,6 +3429,7 @@ netinet/sctp_output.c		optional inet sct
 netinet/sctp_pcb.c		optional inet sctp | inet6 sctp
 netinet/sctp_peeloff.c		optional inet sctp | inet6 sctp
 netinet/sctp_ss_functions.c	optional inet sctp | inet6 sctp
+netinet/sctp_syscalls.c		optional inet sctp | inet6 sctp
 netinet/sctp_sysctl.c		optional inet sctp | inet6 sctp
 netinet/sctp_timer.c		optional inet sctp | inet6 sctp
 netinet/sctp_usrreq.c		optional inet sctp | inet6 sctp

Modified: head/sys/kern/syscalls.master
==============================================================================
--- head/sys/kern/syscalls.master	Thu Oct  9 14:43:43 2014	(r272822)
+++ head/sys/kern/syscalls.master	Thu Oct  9 15:16:52 2014	(r272823)
@@ -837,14 +837,14 @@
 468	AUE_NULL	UNIMPL	nosys
 469	AUE_NULL	UNIMPL	__getpath_fromfd
 470	AUE_NULL	UNIMPL	__getpath_fromaddr
-471	AUE_NULL	STD	{ int sctp_peeloff(int sd, uint32_t name); }
-472     AUE_NULL        STD    { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
+471	AUE_NULL	NOSTD	{ int sctp_peeloff(int sd, uint32_t name); }
+472     AUE_NULL        NOSTD	{ int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
 	                            caddr_t to, __socklen_t tolen, \
 				    struct sctp_sndrcvinfo *sinfo, int flags); }
-473     AUE_NULL        STD    { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
+473     AUE_NULL        NOSTD	{ int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
 	                            caddr_t to, __socklen_t tolen, \
 				    struct sctp_sndrcvinfo *sinfo, int flags); }
-474     AUE_NULL        STD    { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
+474     AUE_NULL        NOSTD	{ int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
 				    struct sockaddr * from, __socklen_t *fromlenaddr, \
 				    struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
 475	AUE_PREAD	STD	{ ssize_t pread(int fd, void *buf, \

Modified: head/sys/kern/uipc_syscalls.c
==============================================================================
--- head/sys/kern/uipc_syscalls.c	Thu Oct  9 14:43:43 2014	(r272822)
+++ head/sys/kern/uipc_syscalls.c	Thu Oct  9 15:16:52 2014	(r272823)
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
 #include "opt_capsicum.h"
 #include "opt_inet.h"
 #include "opt_inet6.h"
-#include "opt_sctp.h"
 #include "opt_compat.h"
 #include "opt_ktrace.h"
 
@@ -95,13 +94,6 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 #include <vm/uma.h>
 
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
-#include <netinet/sctp.h>
-#include <netinet/sctp_peeloff.h>
-#endif /* SCTP */
-#endif /* INET || INET6 */
-
 /*
  * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC
  * and SOCK_NONBLOCK.
@@ -198,7 +190,7 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat,
  * capability rights are present.
  * A reference on the file entry is held upon returning.
  */
-static int
+int
 getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp,
     struct file **fpp, u_int *fflagp)
 {
@@ -3206,484 +3198,3 @@ out:
 
 	return (error);
 }
-
-/*
- * SCTP syscalls.
- * Functionality only compiled in if SCTP is defined in the kernel Makefile,
- * otherwise all return EOPNOTSUPP.
- * XXX: We should make this loadable one day.
- */
-int
-sys_sctp_peeloff(td, uap)
-	struct thread *td;
-	struct sctp_peeloff_args /* {
-		int	sd;
-		caddr_t	name;
-	} */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
-	struct file *nfp = NULL;
-	struct socket *head, *so;
-	cap_rights_t rights;
-	u_int fflag;
-	int error, fd;
-
-	AUDIT_ARG_FD(uap->sd);
-	error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF),
-	    &head, &fflag);
-	if (error != 0)
-		goto done2;
-	if (head->so_proto->pr_protocol != IPPROTO_SCTP) {
-		error = EOPNOTSUPP;
-		goto done;
-	}
-	error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name);
-	if (error != 0)
-		goto done;
-	/*
-	 * At this point we know we do have a assoc to pull
-	 * we proceed to get the fd setup. This may block
-	 * but that is ok.
-	 */
-
-	error = falloc(td, &nfp, &fd, 0);
-	if (error != 0)
-		goto done;
-	td->td_retval[0] = fd;
-
-	CURVNET_SET(head->so_vnet);
-	so = sonewconn(head, SS_ISCONNECTED);
-	if (so == NULL) {
-		error = ENOMEM;
-		goto noconnection;
-	}
-	/*
-	 * Before changing the flags on the socket, we have to bump the
-	 * reference count.  Otherwise, if the protocol calls sofree(),
-	 * the socket will be released due to a zero refcount.
-	 */
-        SOCK_LOCK(so);
-        soref(so);                      /* file descriptor reference */
-        SOCK_UNLOCK(so);
-
-	ACCEPT_LOCK();
-
-	TAILQ_REMOVE(&head->so_comp, so, so_list);
-	head->so_qlen--;
-	so->so_state |= (head->so_state & SS_NBIO);
-	so->so_state &= ~SS_NOFDREF;
-	so->so_qstate &= ~SQ_COMP;
-	so->so_head = NULL;
-	ACCEPT_UNLOCK();
-	finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
-	error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name);
-	if (error != 0)
-		goto noconnection;
-	if (head->so_sigio != NULL)
-		fsetown(fgetown(&head->so_sigio), &so->so_sigio);
-
-noconnection:
-	/*
-	 * close the new descriptor, assuming someone hasn't ripped it
-	 * out from under us.
-	 */
-	if (error != 0)
-		fdclose(td->td_proc->p_fd, nfp, fd, td);
-
-	/*
-	 * Release explicitly held references before returning.
-	 */
-	CURVNET_RESTORE();
-done:
-	if (nfp != NULL)
-		fdrop(nfp, td);
-	fputsock(head);
-done2:
-	return (error);
-#else  /* SCTP */
-	return (EOPNOTSUPP);
-#endif /* SCTP */
-}
-
-int
-sys_sctp_generic_sendmsg (td, uap)
-	struct thread *td;
-	struct sctp_generic_sendmsg_args /* {
-		int sd,
-		caddr_t msg,
-		int mlen,
-		caddr_t to,
-		__socklen_t tolen,
-		struct sctp_sndrcvinfo *sinfo,
-		int flags
-	} */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
-	struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL;
-	struct socket *so;
-	struct file *fp = NULL;
-	struct sockaddr *to = NULL;
-#ifdef KTRACE
-	struct uio *ktruio = NULL;
-#endif
-	struct uio auio;
-	struct iovec iov[1];
-	cap_rights_t rights;
-	int error = 0, len;
-
-	if (uap->sinfo != NULL) {
-		error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
-		if (error != 0)
-			return (error);
-		u_sinfo = &sinfo;
-	}
-
-	cap_rights_init(&rights, CAP_SEND);
-	if (uap->tolen != 0) {
-		error = getsockaddr(&to, uap->to, uap->tolen);
-		if (error != 0) {
-			to = NULL;
-			goto sctp_bad2;
-		}
-		cap_rights_set(&rights, CAP_CONNECT);
-	}
-
-	AUDIT_ARG_FD(uap->sd);
-	error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL);
-	if (error != 0)
-		goto sctp_bad;
-#ifdef KTRACE
-	if (to && (KTRPOINT(td, KTR_STRUCT)))
-		ktrsockaddr(to);
-#endif
-
-	iov[0].iov_base = uap->msg;
-	iov[0].iov_len = uap->mlen;
-
-	so = (struct socket *)fp->f_data;
-	if (so->so_proto->pr_protocol != IPPROTO_SCTP) {
-		error = EOPNOTSUPP;
-		goto sctp_bad;
-	}
-#ifdef MAC
-	error = mac_socket_check_send(td->td_ucred, so);
-	if (error != 0)
-		goto sctp_bad;
-#endif /* MAC */
-
-	auio.uio_iov =  iov;
-	auio.uio_iovcnt = 1;
-	auio.uio_segflg = UIO_USERSPACE;
-	auio.uio_rw = UIO_WRITE;
-	auio.uio_td = td;
-	auio.uio_offset = 0;			/* XXX */
-	auio.uio_resid = 0;
-	len = auio.uio_resid = uap->mlen;
-	CURVNET_SET(so->so_vnet);
-	error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL,
-	    (struct mbuf *)NULL, uap->flags, u_sinfo, td);
-	CURVNET_RESTORE();
-	if (error != 0) {
-		if (auio.uio_resid != len && (error == ERESTART ||
-		    error == EINTR || error == EWOULDBLOCK))
-			error = 0;
-		/* Generation of SIGPIPE can be controlled per socket. */
-		if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
-		    !(uap->flags & MSG_NOSIGNAL)) {
-			PROC_LOCK(td->td_proc);
-			tdsignal(td, SIGPIPE);
-			PROC_UNLOCK(td->td_proc);
-		}
-	}
-	if (error == 0)
-		td->td_retval[0] = len - auio.uio_resid;
-#ifdef KTRACE
-	if (ktruio != NULL) {
-		ktruio->uio_resid = td->td_retval[0];
-		ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
-	}
-#endif /* KTRACE */
-sctp_bad:
-	if (fp != NULL)
-		fdrop(fp, td);
-sctp_bad2:
-	free(to, M_SONAME);
-	return (error);
-#else  /* SCTP */
-	return (EOPNOTSUPP);
-#endif /* SCTP */
-}
-
-int
-sys_sctp_generic_sendmsg_iov(td, uap)
-	struct thread *td;
-	struct sctp_generic_sendmsg_iov_args /* {
-		int sd,
-		struct iovec *iov,
-		int iovlen,
-		caddr_t to,
-		__socklen_t tolen,
-		struct sctp_sndrcvinfo *sinfo,
-		int flags
-	} */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
-	struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL;
-	struct socket *so;
-	struct file *fp = NULL;
-	struct sockaddr *to = NULL;
-#ifdef KTRACE
-	struct uio *ktruio = NULL;
-#endif
-	struct uio auio;
-	struct iovec *iov, *tiov;
-	cap_rights_t rights;
-	ssize_t len;
-	int error, i;
-
-	if (uap->sinfo != NULL) {
-		error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
-		if (error != 0)
-			return (error);
-		u_sinfo = &sinfo;
-	}
-	cap_rights_init(&rights, CAP_SEND);
-	if (uap->tolen != 0) {
-		error = getsockaddr(&to, uap->to, uap->tolen);
-		if (error != 0) {
-			to = NULL;
-			goto sctp_bad2;
-		}
-		cap_rights_set(&rights, CAP_CONNECT);
-	}
-
-	AUDIT_ARG_FD(uap->sd);
-	error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL);
-	if (error != 0)
-		goto sctp_bad1;
-
-#ifdef COMPAT_FREEBSD32
-	if (SV_CURPROC_FLAG(SV_ILP32))
-		error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
-		    uap->iovlen, &iov, EMSGSIZE);
-	else
-#endif
-		error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
-	if (error != 0)
-		goto sctp_bad1;
-#ifdef KTRACE
-	if (to && (KTRPOINT(td, KTR_STRUCT)))
-		ktrsockaddr(to);
-#endif
-
-	so = (struct socket *)fp->f_data;
-	if (so->so_proto->pr_protocol != IPPROTO_SCTP) {
-		error = EOPNOTSUPP;
-		goto sctp_bad;
-	}
-#ifdef MAC
-	error = mac_socket_check_send(td->td_ucred, so);
-	if (error != 0)
-		goto sctp_bad;
-#endif /* MAC */
-
-	auio.uio_iov = iov;
-	auio.uio_iovcnt = uap->iovlen;
-	auio.uio_segflg = UIO_USERSPACE;
-	auio.uio_rw = UIO_WRITE;
-	auio.uio_td = td;
-	auio.uio_offset = 0;			/* XXX */
-	auio.uio_resid = 0;
-	tiov = iov;
-	for (i = 0; i <uap->iovlen; i++, tiov++) {
-		if ((auio.uio_resid += tiov->iov_len) < 0) {
-			error = EINVAL;
-			goto sctp_bad;
-		}
-	}
-	len = auio.uio_resid;
-	CURVNET_SET(so->so_vnet);
-	error = sctp_lower_sosend(so, to, &auio,
-		    (struct mbuf *)NULL, (struct mbuf *)NULL,
-		    uap->flags, u_sinfo, td);
-	CURVNET_RESTORE();
-	if (error != 0) {
-		if (auio.uio_resid != len && (error == ERESTART ||
-		    error == EINTR || error == EWOULDBLOCK))
-			error = 0;
-		/* Generation of SIGPIPE can be controlled per socket */
-		if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
-		    !(uap->flags & MSG_NOSIGNAL)) {
-			PROC_LOCK(td->td_proc);
-			tdsignal(td, SIGPIPE);
-			PROC_UNLOCK(td->td_proc);
-		}
-	}
-	if (error == 0)
-		td->td_retval[0] = len - auio.uio_resid;
-#ifdef KTRACE
-	if (ktruio != NULL) {
-		ktruio->uio_resid = td->td_retval[0];
-		ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
-	}
-#endif /* KTRACE */
-sctp_bad:
-	free(iov, M_IOV);
-sctp_bad1:
-	if (fp != NULL)
-		fdrop(fp, td);
-sctp_bad2:
-	free(to, M_SONAME);
-	return (error);
-#else  /* SCTP */
-	return (EOPNOTSUPP);
-#endif /* SCTP */
-}
-
-int
-sys_sctp_generic_recvmsg(td, uap)
-	struct thread *td;
-	struct sctp_generic_recvmsg_args /* {
-		int sd,
-		struct iovec *iov,
-		int iovlen,
-		struct sockaddr *from,
-		__socklen_t *fromlenaddr,
-		struct sctp_sndrcvinfo *sinfo,
-		int *msg_flags
-	} */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
-	uint8_t sockbufstore[256];
-	struct uio auio;
-	struct iovec *iov, *tiov;
-	struct sctp_sndrcvinfo sinfo;
-	struct socket *so;
-	struct file *fp = NULL;
-	struct sockaddr *fromsa;
-	cap_rights_t rights;
-#ifdef KTRACE
-	struct uio *ktruio = NULL;
-#endif
-	ssize_t len;
-	int error, fromlen, i, msg_flags;
-
-	AUDIT_ARG_FD(uap->sd);
-	error = getsock_cap(td->td_proc->p_fd, uap->sd,
-	    cap_rights_init(&rights, CAP_RECV), &fp, NULL);
-	if (error != 0)
-		return (error);
-#ifdef COMPAT_FREEBSD32
-	if (SV_CURPROC_FLAG(SV_ILP32))
-		error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
-		    uap->iovlen, &iov, EMSGSIZE);
-	else
-#endif
-		error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
-	if (error != 0)
-		goto out1;
-
-	so = fp->f_data;
-	if (so->so_proto->pr_protocol != IPPROTO_SCTP) {
-		error = EOPNOTSUPP;
-		goto out;
-	}
-#ifdef MAC
-	error = mac_socket_check_receive(td->td_ucred, so);
-	if (error != 0)
-		goto out;
-#endif /* MAC */
-
-	if (uap->fromlenaddr != NULL) {
-		error = copyin(uap->fromlenaddr, &fromlen, sizeof (fromlen));
-		if (error != 0)
-			goto out;
-	} else {
-		fromlen = 0;
-	}
-	if (uap->msg_flags) {
-		error = copyin(uap->msg_flags, &msg_flags, sizeof (int));
-		if (error != 0)
-			goto out;
-	} else {
-		msg_flags = 0;
-	}
-	auio.uio_iov = iov;
-	auio.uio_iovcnt = uap->iovlen;
-	auio.uio_segflg = UIO_USERSPACE;
-	auio.uio_rw = UIO_READ;
-	auio.uio_td = td;
-	auio.uio_offset = 0;			/* XXX */
-	auio.uio_resid = 0;
-	tiov = iov;
-	for (i = 0; i <uap->iovlen; i++, tiov++) {
-		if ((auio.uio_resid += tiov->iov_len) < 0) {
-			error = EINVAL;
-			goto out;
-		}
-	}
-	len = auio.uio_resid;
-	fromsa = (struct sockaddr *)sockbufstore;
-
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_GENIO))
-		ktruio = cloneuio(&auio);
-#endif /* KTRACE */
-	memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
-	CURVNET_SET(so->so_vnet);
-	error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
-		    fromsa, fromlen, &msg_flags,
-		    (struct sctp_sndrcvinfo *)&sinfo, 1);
-	CURVNET_RESTORE();
-	if (error != 0) {
-		if (auio.uio_resid != len && (error == ERESTART ||
-		    error == EINTR || error == EWOULDBLOCK))
-			error = 0;
-	} else {
-		if (uap->sinfo)
-			error = copyout(&sinfo, uap->sinfo, sizeof (sinfo));
-	}
-#ifdef KTRACE
-	if (ktruio != NULL) {
-		ktruio->uio_resid = len - auio.uio_resid;
-		ktrgenio(uap->sd, UIO_READ, ktruio, error);
-	}
-#endif /* KTRACE */
-	if (error != 0)
-		goto out;
-	td->td_retval[0] = len - auio.uio_resid;
-
-	if (fromlen && uap->from) {
-		len = fromlen;
-		if (len <= 0 || fromsa == 0)
-			len = 0;
-		else {
-			len = MIN(len, fromsa->sa_len);
-			error = copyout(fromsa, uap->from, (size_t)len);
-			if (error != 0)
-				goto out;
-		}
-		error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t));
-		if (error != 0)
-			goto out;
-	}
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_STRUCT))
-		ktrsockaddr(fromsa);
-#endif
-	if (uap->msg_flags) {
-		error = copyout(&msg_flags, uap->msg_flags, sizeof (int));
-		if (error != 0)
-			goto out;
-	}
-out:
-	free(iov, M_IOV);
-out1:
-	if (fp != NULL)
-		fdrop(fp, td);
-
-	return (error);
-#else  /* SCTP */
-	return (EOPNOTSUPP);
-#endif /* SCTP */
-}

Copied and modified: head/sys/netinet/sctp_syscalls.c (from r272821, head/sys/kern/uipc_syscalls.c)
==============================================================================
--- head/sys/kern/uipc_syscalls.c	Thu Oct  9 14:33:20 2014	(r272821, copy source)
+++ head/sys/netinet/sctp_syscalls.c	Thu Oct  9 15:16:52 2014	(r272823)
@@ -2,9 +2,6 @@
  * Copyright (c) 1982, 1986, 1989, 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
- * sendfile(2) and related extensions:
- * Copyright (c) 1998, David Greenman. All rights reserved.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -29,7 +26,6 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
  */
 
 #include <sys/cdefs.h>
@@ -45,7 +41,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/capsicum.h>
-#include <sys/condvar.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -58,18 +53,15 @@ __FBSDID("$FreeBSD$");
 #include <sys/file.h>
 #include <sys/filio.h>
 #include <sys/jail.h>
-#include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/mbuf.h>
 #include <sys/protosw.h>
-#include <sys/rwlock.h>
 #include <sys/sf_buf.h>
-#include <sys/sf_sync.h>
-#include <sys/sf_base.h>
 #include <sys/sysent.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/signalvar.h>
+#include <sys/syscall.h>
 #include <sys/syscallsubr.h>
 #include <sys/sysctl.h>
 #include <sys/uio.h>
@@ -86,3126 +78,33 @@ __FBSDID("$FreeBSD$");
 #include <security/audit/audit.h>
 #include <security/mac/mac_framework.h>
 
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pager.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_extern.h>
-#include <vm/uma.h>
-
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
 #include <netinet/sctp.h>
 #include <netinet/sctp_peeloff.h>
-#endif /* SCTP */
-#endif /* INET || INET6 */
-
-/*
- * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC
- * and SOCK_NONBLOCK.
- */
-#define	ACCEPT4_INHERIT	0x1
-#define	ACCEPT4_COMPAT	0x2
-
-static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
-static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
-
-static int accept1(struct thread *td, int s, struct sockaddr *uname,
-		   socklen_t *anamelen, int flags);
-static int do_sendfile(struct thread *td, struct sendfile_args *uap,
-		   int compat);
-static int getsockname1(struct thread *td, struct getsockname_args *uap,
-			int compat);
-static int getpeername1(struct thread *td, struct getpeername_args *uap,
-			int compat);
-
-counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)];
-
-static int	filt_sfsync_attach(struct knote *kn);
-static void	filt_sfsync_detach(struct knote *kn);
-static int	filt_sfsync(struct knote *kn, long hint);
 
-/*
- * sendfile(2)-related variables and associated sysctls
- */
-static SYSCTL_NODE(_kern_ipc, OID_AUTO, sendfile, CTLFLAG_RW, 0,
-    "sendfile(2) tunables");
-static int sfreadahead = 1;
-SYSCTL_INT(_kern_ipc_sendfile, OID_AUTO, readahead, CTLFLAG_RW,
-    &sfreadahead, 0, "Number of sendfile(2) read-ahead MAXBSIZE blocks");
-
-#ifdef	SFSYNC_DEBUG
-static int sf_sync_debug = 0;
-SYSCTL_INT(_debug, OID_AUTO, sf_sync_debug, CTLFLAG_RW,
-    &sf_sync_debug, 0, "Output debugging during sf_sync lifecycle");
-#define	SFSYNC_DPRINTF(s, ...)				\
-		do {					\
-			if (sf_sync_debug)		\
-				printf((s), ##__VA_ARGS__); \
-		} while (0)
-#else
-#define	SFSYNC_DPRINTF(c, ...)
-#endif
-
-static uma_zone_t	zone_sfsync;
-
-static struct filterops sendfile_filtops = {
-	.f_isfd = 0,
-	.f_attach = filt_sfsync_attach,
-	.f_detach = filt_sfsync_detach,
-	.f_event = filt_sfsync,
+static struct syscall_helper_data sctp_syscalls[] = {
+	SYSCALL_INIT_HELPER(sctp_peeloff),
+	SYSCALL_INIT_HELPER(sctp_generic_sendmsg),
+	SYSCALL_INIT_HELPER(sctp_generic_sendmsg_iov),
+	SYSCALL_INIT_HELPER(sctp_generic_recvmsg),
+	SYSCALL_INIT_LAST
 };
 
 static void
-sfstat_init(const void *unused)
-{
-
-	COUNTER_ARRAY_ALLOC(sfstat, sizeof(struct sfstat) / sizeof(uint64_t),
-	    M_WAITOK);
-}
-SYSINIT(sfstat, SI_SUB_MBUF, SI_ORDER_FIRST, sfstat_init, NULL);
-
-static void
-sf_sync_init(const void *unused)
-{
-
-	zone_sfsync = uma_zcreate("sendfile_sync", sizeof(struct sendfile_sync),
-	    NULL, NULL,
-	    NULL, NULL,
-	    UMA_ALIGN_CACHE,
-	    0);
-	kqueue_add_filteropts(EVFILT_SENDFILE, &sendfile_filtops);
-}
-SYSINIT(sf_sync, SI_SUB_MBUF, SI_ORDER_FIRST, sf_sync_init, NULL);
-
-static int
-sfstat_sysctl(SYSCTL_HANDLER_ARGS)
-{
-	struct sfstat s;
-
-	COUNTER_ARRAY_COPY(sfstat, &s, sizeof(s) / sizeof(uint64_t));
-	if (req->newptr)
-		COUNTER_ARRAY_ZERO(sfstat, sizeof(s) / sizeof(uint64_t));
-	return (SYSCTL_OUT(req, &s, sizeof(s)));
-}
-SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW,
-    NULL, 0, sfstat_sysctl, "I", "sendfile statistics");
-
-/*
- * Convert a user file descriptor to a kernel file entry and check if required
- * capability rights are present.
- * A reference on the file entry is held upon returning.
- */
-static int
-getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp,
-    struct file **fpp, u_int *fflagp)
-{
-	struct file *fp;
-	int error;
-
-	error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL);
-	if (error != 0)
-		return (error);
-	if (fp->f_type != DTYPE_SOCKET) {
-		fdrop(fp, curthread);
-		return (ENOTSOCK);
-	}
-	if (fflagp != NULL)
-		*fflagp = fp->f_flag;
-	*fpp = fp;
-	return (0);
-}
-
-/*
- * System call interface to the socket abstraction.
- */
-#if defined(COMPAT_43)
-#define COMPAT_OLDSOCK
-#endif
-
-int
-sys_socket(td, uap)
-	struct thread *td;
-	struct socket_args /* {
-		int	domain;
-		int	type;
-		int	protocol;
-	} */ *uap;
-{
-	struct socket *so;
-	struct file *fp;
-	int fd, error, type, oflag, fflag;
-
-	AUDIT_ARG_SOCKET(uap->domain, uap->type, uap->protocol);
-
-	type = uap->type;
-	oflag = 0;
-	fflag = 0;
-	if ((type & SOCK_CLOEXEC) != 0) {
-		type &= ~SOCK_CLOEXEC;
-		oflag |= O_CLOEXEC;
-	}
-	if ((type & SOCK_NONBLOCK) != 0) {
-		type &= ~SOCK_NONBLOCK;
-		fflag |= FNONBLOCK;
-	}
-
-#ifdef MAC
-	error = mac_socket_check_create(td->td_ucred, uap->domain, type,
-	    uap->protocol);
-	if (error != 0)
-		return (error);
-#endif
-	error = falloc(td, &fp, &fd, oflag);
-	if (error != 0)
-		return (error);
-	/* An extra reference on `fp' has been held for us by falloc(). */
-	error = socreate(uap->domain, &so, type, uap->protocol,
-	    td->td_ucred, td);
-	if (error != 0) {
-		fdclose(td->td_proc->p_fd, fp, fd, td);
-	} else {
-		finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
-		if ((fflag & FNONBLOCK) != 0)
-			(void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
-		td->td_retval[0] = fd;
-	}
-	fdrop(fp, td);
-	return (error);
-}
-
-/* ARGSUSED */
-int
-sys_bind(td, uap)
-	struct thread *td;
-	struct bind_args /* {
-		int	s;
-		caddr_t	name;
-		int	namelen;
-	} */ *uap;
-{
-	struct sockaddr *sa;
-	int error;
-
-	error = getsockaddr(&sa, uap->name, uap->namelen);
-	if (error == 0) {
-		error = kern_bind(td, uap->s, sa);
-		free(sa, M_SONAME);
-	}
-	return (error);
-}
-
-static int
-kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
-{
-	struct socket *so;
-	struct file *fp;
-	cap_rights_t rights;
-	int error;
-
-	AUDIT_ARG_FD(fd);
-	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
-	error = getsock_cap(td->td_proc->p_fd, fd,
-	    cap_rights_init(&rights, CAP_BIND), &fp, NULL);
-	if (error != 0)
-		return (error);
-	so = fp->f_data;
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_STRUCT))
-		ktrsockaddr(sa);
-#endif
-#ifdef MAC
-	error = mac_socket_check_bind(td->td_ucred, so, sa);
-	if (error == 0) {
-#endif
-		if (dirfd == AT_FDCWD)
-			error = sobind(so, sa, td);
-		else
-			error = sobindat(dirfd, so, sa, td);
-#ifdef MAC
-	}
-#endif
-	fdrop(fp, td);
-	return (error);
-}
-
-int
-kern_bind(struct thread *td, int fd, struct sockaddr *sa)
-{
-
-	return (kern_bindat(td, AT_FDCWD, fd, sa));
-}
-
-/* ARGSUSED */
-int
-sys_bindat(td, uap)
-	struct thread *td;
-	struct bindat_args /* {
-		int	fd;
-		int	s;
-		caddr_t	name;
-		int	namelen;
-	} */ *uap;
-{
-	struct sockaddr *sa;
-	int error;
-
-	error = getsockaddr(&sa, uap->name, uap->namelen);
-	if (error == 0) {
-		error = kern_bindat(td, uap->fd, uap->s, sa);
-		free(sa, M_SONAME);
-	}
-	return (error);
-}
-
-/* ARGSUSED */
-int
-sys_listen(td, uap)
-	struct thread *td;
-	struct listen_args /* {
-		int	s;
-		int	backlog;
-	} */ *uap;
-{
-	struct socket *so;
-	struct file *fp;
-	cap_rights_t rights;
-	int error;
-
-	AUDIT_ARG_FD(uap->s);
-	error = getsock_cap(td->td_proc->p_fd, uap->s,
-	    cap_rights_init(&rights, CAP_LISTEN), &fp, NULL);
-	if (error == 0) {
-		so = fp->f_data;
-#ifdef MAC
-		error = mac_socket_check_listen(td->td_ucred, so);
-		if (error == 0)
-#endif
-			error = solisten(so, uap->backlog, td);
-		fdrop(fp, td);
-	}
-	return(error);
-}
-
-/*
- * accept1()
- */
-static int
-accept1(td, s, uname, anamelen, flags)
-	struct thread *td;
-	int s;
-	struct sockaddr *uname;
-	socklen_t *anamelen;
-	int flags;
-{
-	struct sockaddr *name;
-	socklen_t namelen;
-	struct file *fp;
-	int error;
-
-	if (uname == NULL)
-		return (kern_accept4(td, s, NULL, NULL, flags, NULL));
-
-	error = copyin(anamelen, &namelen, sizeof (namelen));
-	if (error != 0)
-		return (error);
-
-	error = kern_accept4(td, s, &name, &namelen, flags, &fp);
-
-	if (error != 0)
-		return (error);
-
-	if (error == 0 && uname != NULL) {
-#ifdef COMPAT_OLDSOCK
-		if (flags & ACCEPT4_COMPAT)
-			((struct osockaddr *)name)->sa_family =
-			    name->sa_family;
-#endif
-		error = copyout(name, uname, namelen);
-	}
-	if (error == 0)
-		error = copyout(&namelen, anamelen,
-		    sizeof(namelen));
-	if (error != 0)
-		fdclose(td->td_proc->p_fd, fp, td->td_retval[0], td);
-	fdrop(fp, td);
-	free(name, M_SONAME);
-	return (error);
-}
-
-int
-kern_accept(struct thread *td, int s, struct sockaddr **name,
-    socklen_t *namelen, struct file **fp)
-{
-	return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
-}
-
-int
-kern_accept4(struct thread *td, int s, struct sockaddr **name,
-    socklen_t *namelen, int flags, struct file **fp)
-{
-	struct filedesc *fdp;
-	struct file *headfp, *nfp = NULL;
-	struct sockaddr *sa = NULL;
-	struct socket *head, *so;
-	cap_rights_t rights;
-	u_int fflag;
-	pid_t pgid;
-	int error, fd, tmp;
-
-	if (name != NULL)
-		*name = NULL;
-

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list