From 22be1ea9cab402a921776a59ff9667bcb5e2c299 Mon Sep 17 00:00:00 2001
From: Dimitri Staessens <dimitri.staessens@ugent.be>
Date: Fri, 8 Jun 2018 14:42:10 +0200
Subject: ipcpd: Limit eth MTU to rdrb in single-block mode

When the SHM is in single block mode, the MTU may be bigger than a
block. The eth IPCPs reserved buffers the size of MTU, which is now
limited.

Signed-off-by: Dimitri Staessens <dimitri.staessens@ugent.be>
Signed-off-by: Sander Vrijders <sander.vrijders@ugent.be>
---
 src/ipcpd/config.h.in |  4 ++++
 src/ipcpd/eth/eth.c   | 13 ++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

(limited to 'src/ipcpd')

diff --git a/src/ipcpd/config.h.in b/src/ipcpd/config.h.in
index b7806f60..2b4bef78 100644
--- a/src/ipcpd/config.h.in
+++ b/src/ipcpd/config.h.in
@@ -32,6 +32,10 @@
 #define CONNECT_TIMEOUT     @CONNECT_TIMEOUT@
 
 #define SHM_BUFFER_SIZE     @SHM_BUFFER_SIZE@
+#define SHM_RDRB_BLOCK_SIZE @SHM_RDRB_BLOCK_SIZE@
+#define DU_BUFF_HEADSPACE   @DU_BUFF_HEADSPACE@
+#define DU_BUFF_TAILSPACE   @DU_BUFF_TAILSPACE@
+#cmakedefine                SHM_RDRB_MULTI_BLOCK
 
 #define IPCP_MIN_THREADS    @IPCP_MIN_THREADS@
 #define IPCP_ADD_THREADS    @IPCP_ADD_THREADS@
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index caf9d2df..8ef11530 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -840,7 +840,7 @@ static void * eth_ipcp_sdu_reader(void * o)
                 if (select(eth_data.s_fd + 1, &fds, NULL, NULL, NULL) < 0)
                         continue;
                 assert(FD_ISSET(eth_data.s_fd, &fds));
-                if (ipcp_sdb_reserve(&sdb, ETH_FRAME_SIZE))
+                if (ipcp_sdb_reserve(&sdb, eth_data.mtu))
                         continue;
                 buf = shm_du_buff_head(sdb);
                 frame_len = recv(eth_data.s_fd, buf, ETH_FRAME_SIZE, 0);
@@ -1179,6 +1179,9 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
         struct ifaddrs * ifa;
 #elif defined(__linux__)
         int              skfd;
+#endif
+#ifndef SHM_RDRB_MULTI_BLOCK
+        size_t           maxsz;
 #endif
         assert(conf);
         assert(conf->type == THIS_TYPE);
@@ -1250,6 +1253,14 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
 
         eth_data.mtu = MIN((int) ETH_MTU_MAX, ifr.ifr_mtu);
 
+#ifndef SHM_RDRB_MULTI_BLOCK
+        maxsz = SHM_RDRB_BLOCK_SIZE - 5 * sizeof(size_t) -
+                (DU_BUFF_HEADSPACE + DU_BUFF_TAILSPACE);
+        if ((size_t) eth_data.mtu > maxsz ) {
+                log_dbg("Layer MTU truncated to shm block size.");
+                eth_data.mtu = maxsz;
+        }
+#endif
         log_dbg("Layer MTU is %d.", eth_data.mtu);
 
         close(skfd);
-- 
cgit v1.2.3