diff mbox

[2/2] odp_packet_socket: add backwards compatible sendmmsg wrapper

Message ID 1408877638-18082-3-git-send-email-giladb@ezchip.com
State Accepted
Commit bb3e68e6dcf266444d52acccfa68ef5cf98d2daf
Headers show

Commit Message

Gilad Ben-Yossef Aug. 24, 2014, 10:53 a.m. UTC
From: Gilad Ben-Yossef <gilad@benyossef.com>

RHEL / CentOS 6.2 and above have sendmmsg kernel support but
no libc support.

Also, it is quite easy to emulate sendmmsg on top of sendmsg.

The following patch provides a sendmmsg wrapper as a weak symbol
that provides both support to call the syscall even if libc support
is missing, as well as an emulation in case no kernel support is
there.

This lets us drop the dependency on kernel version 3.0.

Signed-off-by: Gilad Ben-Yossef <giladb@ezchip.com>
---
 DEPENDENCIES                               |    4 +-
 platform/linux-generic/odp_packet_socket.c |   32 ++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/DEPENDENCIES b/DEPENDENCIES
index b4c04c9..9085b68 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -1,8 +1,8 @@ 
 Prerequisites for building the OpenDataPlane (ODP) API
 
-1. Linux kernel >= 3.0
+1. Linux kernel >= 2.6.32
 
-   Version 3.0+ needed for the sendmmsg() interface
+   Earlier versions may or may not work.
 
 2. autotools
 
diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c
index d44c333..9f05618 100644
--- a/platform/linux-generic/odp_packet_socket.c
+++ b/platform/linux-generic/odp_packet_socket.c
@@ -42,6 +42,38 @@ 
 #include <helper/odp_ip.h>
 #include <helper/odp_packet_helper.h>
 
+/** Provide a sendmmsg wrapper for systems with no libc or kernel support.
+ *  As it is implemented as a weak symbol, it has zero effect on systems
+ *  with both.
+ */
+int sendmmsg(int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) __attribute__((weak));
+int sendmmsg(int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
+{
+#ifdef SYS_sendmmsg
+	return syscall(SYS_sendmmsg, fd, vmessages, vlen, flags);
+#else
+	/* Emulate sendmmsg using sendmsg.
+	 * Note: this emulated version does break sendmmsg promise
+	 * that for blocking calls all the messages will be handled
+	 * so it's not a good general purpose sendmmsg emulator,
+	 * but for our purposes it suffices.
+	 */
+	ssize_t ret;
+
+	if (vlen) {
+		ret = sendmsg(fd, &vmessages->msg_hdr, flags);
+
+		if (ret != -1) {
+			vmessages->msg_len = ret;
+			return 1;
+		}
+	}
+
+	return -1;
+
+#endif
+}
+
 
 /** Raw sockets does not support packets fanout across different cpus,
  *  that's lead to same packet recieved in different thread. To avoid that