aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@benyossef.com>2014-08-24 13:53:58 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2014-08-26 18:25:53 +0400
commitbb3e68e6dcf266444d52acccfa68ef5cf98d2daf (patch)
treeeba99ce96d4b3033b7be4885bad8dadb158d76ff /platform
parentc597a6036f3ae7b2d015332b76c4b03ad9dcd0d4 (diff)
odp_packet_socket: add backwards compatible sendmmsg wrapper
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> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/odp_packet_socket.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c
index d44c333cd..9f05618f9 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