Does FreeBSD have sendmmsg or recvmmsg system calls?

Boris Astardzhiev boris.astardzhiev at gmail.com
Thu Jan 7 09:51:27 UTC 2016


Hello,

Here's my implementation of the two system calls. The patch is against HEAD
from a couple of days:
commit ff9e83788d7ed52342dcba4dff1e62fdf3cc985c
Author: ngie <ngie at FreeBSD.org>
Date:   Mon Jan 4 03:34:22 2016 +0000

    Remove free'ing of an uninitialized variable

    Just remove it completely from the test as it's initialized but unused
apart
    from the free(3) call

    Differential Revision: https://reviews.freebsd.org/D4769 (part of
larger diff)
    MFC after: 5 days
    Reported by: cppcheck
    Reviewed by: oshogbo
    Sponsored by: EMC / Isilon Storage Division

I've made brief tests using the examples in the manpages in Linux skipping
the timeout stuff:
http://man7.org/linux/man-pages/man2/sendmmsg.2.html
http://man7.org/linux/man-pages/man2/recvmmsg.2.html

I've tried to stick to the comments in the thread but any
suggestions/testings
are also welcomed so that I can fix the calls accordingly.

Regards,
Boris Astardzhiev


On Mon, Jan 4, 2016 at 11:07 PM, Mark Delany <c2h at romeo.emu.st> wrote:

> > You just repeat arguments for the text in my messages, which you removed
> > on reply.
>
> My goal is to get you to scruitinize.
>
> Thank you for helping.
>
>
> Mark.
> _______________________________________________
> freebsd-net at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe at freebsd.org"
>
-------------- next part --------------
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
index 5caf9a3..7e2a902 100644
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -200,8 +200,10 @@ enum {
 	INTERPOS_pselect,
 	INTERPOS_recvfrom,
 	INTERPOS_recvmsg,
+	INTERPOS_recvmmsg,
 	INTERPOS_select,
 	INTERPOS_sendmsg,
+	INTERPOS_sendmmsg,
 	INTERPOS_sendto,
 	INTERPOS_setcontext,
 	INTERPOS_sigaction,
@@ -289,6 +291,7 @@ struct fd_set;
 struct iovec;
 struct kevent;
 struct msghdr;
+struct mmsghdr;
 struct pollfd;
 struct rusage;
 struct sigaction;
@@ -334,9 +337,11 @@ __ssize_t	__sys_recv(int, void *, __size_t, int);
 __ssize_t	__sys_recvfrom(int, void *, __size_t, int, struct sockaddr *,
 		    __socklen_t *);
 __ssize_t	__sys_recvmsg(int, struct msghdr *, int);
+__ssize_t	__sys_recvmmsg(int, struct mmsghdr *, unsigned int, int);
 int		__sys_select(int, struct fd_set *, struct fd_set *,
 		    struct fd_set *, struct timeval *);
 __ssize_t	__sys_sendmsg(int, const struct msghdr *, int);
+__ssize_t	__sys_sendmmsg(int, const struct mmsghdr *, unsigned int, int);
 __ssize_t	__sys_sendto(int, const void *, __size_t, int,
 		    const struct sockaddr *, __socklen_t);
 int		__sys_setcontext(const struct __ucontext *);
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h
index 739d7b1..c95829e 100644
--- a/lib/libc/include/namespace.h
+++ b/lib/libc/include/namespace.h
@@ -208,6 +208,7 @@
 #define		readv				_readv
 #define		recvfrom			_recvfrom
 #define		recvmsg				_recvmsg
+#define		recvmmsg			_recvmmsg
 #define		select				_select
 #define		sem_close			_sem_close
 #define		sem_destroy			_sem_destroy
@@ -220,6 +221,7 @@
 #define		sem_unlink			_sem_unlink
 #define		sem_wait			_sem_wait
 #define		sendmsg				_sendmsg
+#define		sendmmsg			_sendmmsg
 #define		sendto				_sendto
 #define		setsockopt			_setsockopt
 /*#define		sigaction			_sigaction*/
diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h
index f31fa7a..0233348 100644
--- a/lib/libc/include/un-namespace.h
+++ b/lib/libc/include/un-namespace.h
@@ -189,6 +189,7 @@
 #undef		readv
 #undef		recvfrom
 #undef		recvmsg
+#undef		recvmmsg
 #undef		select
 #undef		sem_close
 #undef		sem_destroy
@@ -201,6 +202,7 @@
 #undef		sem_unlink
 #undef		sem_wait
 #undef		sendmsg
+#undef		sendmmsg
 #undef		sendto
 #undef		setsockopt
 #undef		sigaction
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index e4fe1b2..1c09fce 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -49,8 +49,10 @@ INTERPOSED = \
 	readv \
 	recvfrom \
 	recvmsg \
+	recvmmsg \
 	select \
 	sendmsg \
+	sendmmsg \
 	sendto \
 	setcontext \
 	sigprocmask \
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index 7b3257c..6cc3c6e 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -220,6 +220,7 @@ FBSD_1.0 {
 	reboot;
 	recvfrom;
 	recvmsg;
+	recvmmsg;
 	rename;
 	revoke;
 	rfork;
@@ -240,6 +241,7 @@ FBSD_1.0 {
 	semsys;
 	sendfile;
 	sendmsg;
+	sendmmsg;
 	sendto;
 	setaudit;
 	setaudit_addr;
@@ -851,6 +853,8 @@ FBSDprivate_1.0 {
 	__sys_recvfrom;
 	_recvmsg;
 	__sys_recvmsg;
+	_recvmmsg;
+	__sys_recvmmsg;
 	_rename;
 	__sys_rename;
 	_revoke;
@@ -891,6 +895,8 @@ FBSDprivate_1.0 {
 	__sys_sendfile;
 	_sendmsg;
 	__sys_sendmsg;
+	_sendmmsg;
+	__sys_sendmmsg;
 	_sendto;
 	__sys_sendto;
 	_setaudit;
diff --git a/lib/libc/sys/interposing_table.c b/lib/libc/sys/interposing_table.c
index 08dfbb1..c866a75 100644
--- a/lib/libc/sys/interposing_table.c
+++ b/lib/libc/sys/interposing_table.c
@@ -56,8 +56,10 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = {
 	SLOT(readv, __sys_readv),
 	SLOT(recvfrom, __sys_recvfrom),
 	SLOT(recvmsg, __sys_recvmsg),
+	SLOT(recvmmsg, __sys_recvmmsg),
 	SLOT(select, __sys_select),
 	SLOT(sendmsg, __sys_sendmsg),
+	SLOT(sendmmsg, __sys_sendmmsg),
 	SLOT(sendto, __sys_sendto),
 	SLOT(setcontext, __sys_setcontext),
 	SLOT(sigaction, __sys_sigaction),
diff --git a/lib/libc/sys/recvmmsg.c b/lib/libc/sys/recvmmsg.c
new file mode 100644
index 0000000..bbb0588
--- /dev/null
+++ b/lib/libc/sys/recvmmsg.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice(s), this list of conditions and the following disclaimer as
+ *    the first lines of this file unmodified other than the possible
+ *    addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice(s), this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/socket.h>
+#include "libc_private.h"
+
+__weak_reference(__sys_recvmmsg, __recvmmsg);
+
+#pragma weak recvmmsg
+ssize_t
+recvmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags)
+{
+
+	return (((int (*)(int, struct mmsghdr *, int, int))
+	    __libc_interposing[INTERPOS_recvmmsg])(s, msgvec, vlen, flags));
+}
diff --git a/lib/libc/sys/sendmmsg.c b/lib/libc/sys/sendmmsg.c
new file mode 100644
index 0000000..398f9ca
--- /dev/null
+++ b/lib/libc/sys/sendmmsg.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice(s), this list of conditions and the following disclaimer as
+ *    the first lines of this file unmodified other than the possible
+ *    addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice(s), this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/socket.h>
+#include "libc_private.h"
+
+__weak_reference(__sys_sendmmsg, __sendmmsg);
+
+#pragma weak sendmmsg
+ssize_t
+sendmmsg(int s, const struct mmsghdr *msgvec, unsigned int vlen, int flags)
+{
+
+	return (((int (*)(int, const struct mmsghdr *, int, int))
+	    __libc_interposing[INTERPOS_sendmmsg])(s, msgvec, vlen, flags));
+}
diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h
index 3c16c73..2fc887a 100644
--- a/sys/bsm/audit_kevents.h
+++ b/sys/bsm/audit_kevents.h
@@ -611,6 +611,8 @@
 #define	AUE_BINDAT		43207	/* TrustedBSD. */
 #define	AUE_CONNECTAT		43208	/* TrustedBSD. */
 #define	AUE_CHFLAGSAT		43209	/* FreeBSD-specific. */
+#define	AUE_SENDMMSG		43210
+#define	AUE_RECVMMSG		43211
 
 /*
  * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 09ec05d..401d785 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 285388 2015-07-11 15:22:11Z adrian 
+ * created from FreeBSD
  */
 
 #include "opt_compat.h"
@@ -590,4 +590,6 @@ struct sysent sysent[] = {
 	{ AS(utimensat_args), (sy_call_t *)sys_utimensat, AUE_FUTIMESAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC },	/* 547 = utimensat */
 	{ AS(numa_getaffinity_args), (sy_call_t *)sys_numa_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 548 = numa_getaffinity */
 	{ AS(numa_setaffinity_args), (sy_call_t *)sys_numa_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 549 = numa_setaffinity */
+	{ AS(sendmmsg_args), (sy_call_t *)sys_sendmmsg, AUE_SENDMMSG, NULL, 0, 0, 0, SY_THR_STATIC },	/* 550 = sendmmsg */
+	{ AS(recvmmsg_args), (sy_call_t *)sys_recvmmsg, AUE_RECVMMSG, NULL, 0, 0, 0, SY_THR_STATIC },	/* 551 = recvmmsg */
 };
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 1edb193..7e0d3840 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 285388 2015-07-11 15:22:11Z adrian 
+ * created from FreeBSD
  */
 
 const char *syscallnames[] = {
@@ -557,4 +557,6 @@ const char *syscallnames[] = {
 	"utimensat",			/* 547 = utimensat */
 	"numa_getaffinity",			/* 548 = numa_getaffinity */
 	"numa_setaffinity",			/* 549 = numa_setaffinity */
+	"sendmmsg",			/* 550 = sendmmsg */
+	"recvmmsg",			/* 551 = recvmmsg */
 };
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 6e6fb38..6190895 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -994,6 +994,10 @@
 549	AUE_NULL	STD	{ int numa_setaffinity(cpuwhich_t which, \
 				    id_t id, \
 				    const struct vm_domain_policy_entry *policy); }
+550	AUE_SENDMMSG	STD	{ int sendmmsg(int s, struct mmsghdr *msgvec,\
+				    unsigned int vlen, int flags); }
+551	AUE_RECVMMSG	STD	{ int recvmmsg(int s, struct mmsghdr *msgvec,\
+				    unsigned int vlen, int flags); }
 
 ; Please copy any additions and changes to the following compatability tables:
 ; sys/compat/freebsd32/syscalls.master
diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c
index 00a050f..7c0d862 100644
--- a/sys/kern/systrace_args.c
+++ b/sys/kern/systrace_args.c
@@ -3355,6 +3355,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
 		*n_args = 3;
 		break;
 	}
+	/* sendmmsg */
+	case 550: {
+		struct sendmmsg_args *p = params;
+		iarg[0] = p->s; /* int */
+		uarg[1] = (intptr_t) p->msgvec; /* struct mmsghdr * */
+		uarg[2] = p->vlen; /* unsigned int */
+		iarg[3] = p->flags; /* int */
+		*n_args = 4;
+		break;
+	}
+	/* recvmmsg */
+	case 551: {
+		struct recvmmsg_args *p = params;
+		iarg[0] = p->s; /* int */
+		uarg[1] = (intptr_t) p->msgvec; /* struct mmsghdr * */
+		uarg[2] = p->vlen; /* unsigned int */
+		iarg[3] = p->flags; /* int */
+		*n_args = 4;
+		break;
+	}
 	default:
 		*n_args = 0;
 		break;
@@ -8933,6 +8953,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
 			break;
 		};
 		break;
+	/* sendmmsg */
+	case 550:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "struct mmsghdr *";
+			break;
+		case 2:
+			p = "unsigned int";
+			break;
+		case 3:
+			p = "int";
+			break;
+		default:
+			break;
+		};
+		break;
+	/* recvmmsg */
+	case 551:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "struct mmsghdr *";
+			break;
+		case 2:
+			p = "unsigned int";
+			break;
+		case 3:
+			p = "int";
+			break;
+		default:
+			break;
+		};
+		break;
 	default:
 		break;
 	};
@@ -10866,6 +10924,16 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
 		if (ndx == 0 || ndx == 1)
 			p = "int";
 		break;
+	/* sendmmsg */
+	case 550:
+		if (ndx == 0 || ndx == 1)
+			p = "int";
+		break;
+	/* recvmmsg */
+	case 551:
+		if (ndx == 0 || ndx == 1)
+			p = "int";
+		break;
 	default:
 		break;
 	};
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index c33a2cf..7354b4f 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1038,6 +1038,82 @@ sys_sendmsg(td, uap)
 }
 
 int
+sys_sendmmsg(td, uap)
+	struct thread *td;
+	struct sendmmsg_args /* {
+		int	s;
+		struct mmsghdr	*msgvec;
+		unsigned int	vlen;
+		int	flags;
+	} */ *uap;
+{
+	struct mmsghdr *vec, *mmp;
+	struct msghdr *mp, msg;
+	struct iovec *iov;
+	unsigned int vlen, len;
+	int i, sent = 0, error;
+	struct socket *so = NULL;
+	struct file *fp;
+	cap_rights_t rights;
+
+	if (fget(td, uap->s, cap_rights_init(&rights, CAP_SEND), &fp) != 0)
+		return (EBADF);
+
+	so = fp->f_data;
+
+	vlen = uap->vlen;
+	if (vlen > UIO_MAXIOV)
+		vlen = UIO_MAXIOV;
+
+	len = vlen * sizeof(*uap->msgvec);
+	vec = malloc(len, M_TEMP, M_WAITOK);
+
+	error = copyin(uap->msgvec, vec, len);
+	if (error != 0)
+		goto out;
+
+	for (i = 0; i < vlen; i++) {
+		mmp = &vec[i];
+		mp = &mmp->msg_hdr;
+		msg = *mp;
+
+		error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
+		if (error != 0)
+			goto out;
+
+		msg.msg_iov = iov;
+#ifdef COMPAT_OLDSOCK
+		msg.msg_flags = 0;
+#endif
+		error = sendit(td, uap->s, &msg, uap->flags);
+		free(iov, M_IOV);
+		if (error != 0)
+			goto out;
+
+		error = copyout(&td->td_retval[0], &uap->msgvec[i].msg_len,
+		    sizeof(td->td_retval[0]));
+		if (error != 0)
+			goto out;
+
+		sent++;
+	}
+
+	td->td_retval[0] = sent;
+
+out:
+	if (error != 0 && sent != 0 && sent != vlen) {
+		so->so_error = error;
+		error = 0;
+		td->td_retval[0] = sent;
+	}
+
+	fdrop(fp, td);
+
+	free(vec, M_TEMP);
+	return (error);
+}
+
+int
 kern_recvit(td, s, mp, fromseg, controlp)
 	struct thread *td;
 	int s;
@@ -1363,6 +1439,91 @@ sys_recvmsg(td, uap)
 	return (error);
 }
 
+int
+sys_recvmmsg(td, uap)
+	struct thread *td;
+	struct recvmmsg_args /* {
+		int	s;
+		struct mmsghdr	*msgvec;
+		unsigned int	vlen;
+		int	flags;
+	} */ *uap;
+{
+	struct mmsghdr *vec, *mmp;
+	struct msghdr *mp, msg;
+	struct iovec *uiov, *iov;
+	unsigned int vlen, len;
+	int i, rcvd = 0, error;
+	struct socket *so = NULL;
+	struct file *fp;
+	cap_rights_t rights;
+
+	if (fget(td, uap->s, cap_rights_init(&rights, CAP_RECV), &fp) != 0)
+		return (EBADF);
+
+	so = fp->f_data;
+
+	vlen = uap->vlen;
+	if (vlen > UIO_MAXIOV)
+		vlen = UIO_MAXIOV;
+
+	len = vlen * sizeof(*uap->msgvec);
+	vec = malloc(len, M_TEMP, M_WAITOK);
+
+	error = copyin(uap->msgvec, vec, len);
+	if (error != 0)
+		goto out;
+
+	for (i = 0; i < vlen; i++) {
+		mmp = &vec[i];
+		mp = &mmp->msg_hdr;
+		msg = *mp;
+
+		error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
+		if (error != 0)
+			goto out;
+
+		msg.msg_flags = uap->flags;
+#ifdef COMPAT_OLDSOCK
+		msg.msg_flags &= ~MSG_COMPAT;
+#endif
+		uiov = msg.msg_iov;
+		msg.msg_iov = iov;
+
+		error = recvit(td, uap->s, &msg, NULL);
+		if (error == 0) {
+			msg.msg_iov = uiov;
+			error = copyout(&msg, &uap->msgvec[i].msg_hdr, sizeof(msg));
+			if (error != 0) {
+				free(iov, M_IOV);
+				goto out;
+			}
+			error = copyout(&td->td_retval[0], &uap->msgvec[i].msg_len,
+			    sizeof(td->td_retval[0]));
+			if (error != 0) {
+				free(iov, M_IOV);
+				goto out;
+			}
+		}
+		free(iov, M_IOV);
+		rcvd++;
+	}
+
+	td->td_retval[0] = rcvd;
+
+out:
+	if (error != 0 && rcvd != 0 && rcvd != vlen) {
+		so->so_error = error;
+		error = 0;
+		td->td_retval[0] = rcvd;
+	}
+
+	fdrop(fp, td);
+
+	free(vec, M_TEMP);
+	return (error);
+}
+
 /* ARGSUSED */
 int
 sys_shutdown(td, uap)
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 18e2de1..d352cd2 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -414,6 +414,11 @@ struct msghdr {
 	int		 msg_flags;		/* flags on received message */
 };
 
+struct mmsghdr {
+	struct msghdr	msg_hdr;		/* message header */
+	unsigned int	msg_len;		/* message length  */
+};
+
 #define	MSG_OOB		0x1		/* process out-of-band data */
 #define	MSG_PEEK	0x2		/* peek at incoming message */
 #define	MSG_DONTROUTE	0x4		/* send without using routing tables */
@@ -615,10 +620,12 @@ int	listen(int, int);
 ssize_t	recv(int, void *, size_t, int);
 ssize_t	recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict);
 ssize_t	recvmsg(int, struct msghdr *, int);
+ssize_t	recvmmsg(int, struct mmsghdr *, unsigned int, int);
 ssize_t	send(int, const void *, size_t, int);
 ssize_t	sendto(int, const void *,
 	    size_t, int, const struct sockaddr *, socklen_t);
 ssize_t	sendmsg(int, const struct msghdr *, int);
+ssize_t	sendmmsg(int, const struct mmsghdr *, unsigned int, int);
 #if __BSD_VISIBLE
 int	sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
 int	setfib(int);
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index bc72345..421a171 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 285388 2015-07-11 15:22:11Z adrian 
+ * created from FreeBSD
  */
 
 #define	SYS_syscall	0
@@ -467,4 +467,6 @@
 #define	SYS_utimensat	547
 #define	SYS_numa_getaffinity	548
 #define	SYS_numa_setaffinity	549
-#define	SYS_MAXSYSCALL	550
+#define	SYS_sendmmsg	550
+#define	SYS_recvmmsg	551
+#define	SYS_MAXSYSCALL	552
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index fe2cb35..229e915 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -1,7 +1,7 @@
 # FreeBSD system call names.
 # DO NOT EDIT-- this file is automatically generated.
 # $FreeBSD$
-# created from FreeBSD: head/sys/kern/syscalls.master 285388 2015-07-11 15:22:11Z adrian 
+# created from FreeBSD
 MIASM =  \
 	syscall.o \
 	exit.o \
@@ -414,4 +414,6 @@ MIASM =  \
 	futimens.o \
 	utimensat.o \
 	numa_getaffinity.o \
-	numa_setaffinity.o
+	numa_setaffinity.o \
+	sendmmsg.o \
+	recvmmsg.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 143f81d..e2b05a8 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 285388 2015-07-11 15:22:11Z adrian 
+ * created from FreeBSD
  */
 
 #ifndef _SYS_SYSPROTO_H_
@@ -1800,6 +1800,18 @@ struct numa_setaffinity_args {
 	char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
 	char policy_l_[PADL_(const struct vm_domain_policy_entry *)]; const struct vm_domain_policy_entry * policy; char policy_r_[PADR_(const struct vm_domain_policy_entry *)];
 };
+struct sendmmsg_args {
+	char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+	char msgvec_l_[PADL_(struct mmsghdr *)]; struct mmsghdr * msgvec; char msgvec_r_[PADR_(struct mmsghdr *)];
+	char vlen_l_[PADL_(unsigned int)]; unsigned int vlen; char vlen_r_[PADR_(unsigned int)];
+	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
+struct recvmmsg_args {
+	char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+	char msgvec_l_[PADL_(struct mmsghdr *)]; struct mmsghdr * msgvec; char msgvec_r_[PADR_(struct mmsghdr *)];
+	char vlen_l_[PADL_(unsigned int)]; unsigned int vlen; char vlen_r_[PADR_(unsigned int)];
+	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
 int	nosys(struct thread *, struct nosys_args *);
 void	sys_sys_exit(struct thread *, struct sys_exit_args *);
 int	sys_fork(struct thread *, struct fork_args *);
@@ -2190,6 +2202,8 @@ int	sys_futimens(struct thread *, struct futimens_args *);
 int	sys_utimensat(struct thread *, struct utimensat_args *);
 int	sys_numa_getaffinity(struct thread *, struct numa_getaffinity_args *);
 int	sys_numa_setaffinity(struct thread *, struct numa_setaffinity_args *);
+int	sys_sendmmsg(struct thread *, struct sendmmsg_args *);
+int	sys_recvmmsg(struct thread *, struct recvmmsg_args *);
 
 #ifdef COMPAT_43
 
@@ -2945,6 +2959,8 @@ int	freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *);
 #define	SYS_AUE_utimensat	AUE_FUTIMESAT
 #define	SYS_AUE_numa_getaffinity	AUE_NULL
 #define	SYS_AUE_numa_setaffinity	AUE_NULL
+#define	SYS_AUE_sendmmsg	AUE_SENDMMSG
+#define	SYS_AUE_recvmmsg	AUE_RECVMMSG
 
 #undef PAD_
 #undef PADL_


More information about the freebsd-net mailing list