2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 15:25:22 +00:00

socket-util: Emulate recvmmsg() and sendmmsg() on Linux only.

These functions failed to build on OS X because MSG_WAITFORONE is not
defined there.  There are pitfalls for trying to define our own MSG_*
constants, since it's hard to pick a constant that is not used by the
system already.  Because OVS only uses recvmmsg() and sendmmsg() on
Linux, it seems easiest to just emulate them there.

Reported-by: Ilya Maximets <i.maximets@ovn.org>
Acked-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Ben Pfaff
2020-01-13 10:03:04 -08:00
parent 67eb811017
commit b9b7b989d1
2 changed files with 13 additions and 15 deletions

View File

@@ -104,27 +104,26 @@ int make_unix_socket(int style, bool nonblock,
const char *bind_path, const char *connect_path);
int get_unix_name_len(const struct sockaddr_un *sun, socklen_t sun_len);
/* Universal sendmmsg and recvmmsg support.
/* Universal sendmmsg and recvmmsg support on Linux.
*
* Some platforms, such as new enough Linux and FreeBSD, support sendmmsg and
* recvmmsg, but other platforms (or older ones) do not. We add the following
* infrastructure to allow all code to use sendmmsg and recvmmsg, regardless of
* platform support:
* New enough Linux supports sendmmsg and recvmmsg, but older versions do not.
* We add the following infrastructure to allow all code on Linux to use
* sendmmsg and recvmmsg, regardless of platform support:
*
* - For platforms that lack these functions entirely, we emulate them.
*
* - Some platforms have sendmmsg() and recvmmsg() in the C library but not in
* the kernel. For example, this is true if a Linux system has a newer glibc
* with an old kernel. To compensate, even if these functions appear to be
* available, we still wrap them with handlers that uses our emulation if the
* underlying function returns ENOSYS.
* - With newer glibc but an old kernel, sendmmsg() and recvmmsg() fail with
* ENOSYS. To compensate, even if these functions appear to be available, we
* wrap them with handlers that use our emulation in this case.
*/
#ifdef __linux__
#ifndef HAVE_STRUCT_MMSGHDR_MSG_LEN
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
#endif
#ifndef HAVE_SENDMMSG
int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
int recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *);
@@ -134,6 +133,7 @@ int wrap_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
#define recvmmsg wrap_recvmmsg
int wrap_recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *);
#endif
#endif /* __linux__ */
/* Helpers for calling ioctl() on an AF_INET socket. */
struct ifreq;