From f4e0e4e807709a4c1d02eda4bbe8a0e4f637b741 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Tue, 12 Jun 2018 19:23:57 +0200 Subject: ipcpd: Fix MTU handling in eth This fixes the MTU handling in eth. Buffers are now allocated to smaller size. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/eth/eth.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'src/ipcpd') diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index 8ef11530..c76ef60a 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -93,10 +93,9 @@ #include #endif -#define MAC_SIZE 6 #ifdef __linux__ #ifndef ETH_MAX_MTU /* In if_ether.h as of Linux 4.10. */ -#define ETH_MAX_MTU 65535 +#define ETH_MAX_MTU 0xFFFFU #endif /* ETH_MAX_MTU */ #ifdef BUILD_ETH_DIX #define ETH_MTU eth_data.mtu @@ -110,6 +109,7 @@ #define ETH_MTU_MAX ETH_MTU #endif /* __linux__ */ +#define MAC_SIZE 6 #define ETH_TYPE_LENGTH_SIZE sizeof(uint16_t) #define ETH_HEADER_SIZE (2 * MAC_SIZE + ETH_TYPE_LENGTH_SIZE) @@ -121,21 +121,22 @@ #define DIX_HEADER_SIZE (DIX_EID_SIZE + DIX_LENGTH_SIZE) #define ETH_HEADER_TOT_SIZE (ETH_HEADER_SIZE + DIX_HEADER_SIZE) #define MAX_EIDS (1 << (8 * DIX_EID_SIZE)) -#define ETH_MAX_SDU_SIZE (ETH_MTU_MAX - DIX_HEADER_SIZE) -#define ETH_FRAME_SIZE (ETH_HEADER_TOT_SIZE + ETH_MAX_SDU_SIZE) +#define ETH_MAX_SDU_SIZE (ETH_MTU - DIX_HEADER_SIZE) +#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + ETH_MTU_MAX) #elif defined(BUILD_ETH_LLC) #define THIS_TYPE IPCP_ETH_LLC #define MGMT_SAP 0x01 #define LLC_HEADER_SIZE 3 #define ETH_HEADER_TOT_SIZE (ETH_HEADER_SIZE + LLC_HEADER_SIZE) #define MAX_SAPS 64 -#define ETH_MAX_SDU_SIZE (ETH_MTU_MAX - LLC_HEADER_SIZE) -#define ETH_FRAME_SIZE (ETH_HEADER_TOT_SIZE + ETH_MAX_SDU_SIZE) +#define ETH_MAX_SDU_SIZE (ETH_MTU - LLC_HEADER_SIZE) +#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + ETH_MTU_MAX) #endif #define ALLOC_TIMEO 10 /* ms */ #define NAME_QUERY_TIMEO 2000 /* ms */ #define MGMT_TIMEO 100 /* ms */ +#define MGMT_FRAME_SIZE 512 #define FLOW_REQ 0 #define FLOW_REPLY 1 @@ -184,7 +185,7 @@ struct ef { struct mgmt_frame { struct list_head next; uint8_t r_addr[MAC_SIZE]; - uint8_t buf[ETH_FRAME_SIZE]; + uint8_t buf[MGMT_FRAME_SIZE]; }; struct { @@ -375,7 +376,7 @@ static int eth_ipcp_send_frame(const uint8_t * dst_addr, assert(frame); - if (len > ETH_MAX_SDU_SIZE) + if (len > (size_t) ETH_MAX_SDU_SIZE) return -1; e_frame = (struct eth_frame *) frame; @@ -840,10 +841,16 @@ 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_data.mtu)) + if (ipcp_sdb_reserve(&sdb, ETH_MTU)) continue; - buf = shm_du_buff_head(sdb); - frame_len = recv(eth_data.s_fd, buf, ETH_FRAME_SIZE, 0); + buf = shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE); + if (buf == NULL) { + log_dbg("Failed to allocate header."); + ipcp_sdb_release(sdb); + continue; + } + frame_len = recv(eth_data.s_fd, buf, + ETH_MTU + ETH_HEADER_TOT_SIZE, 0); #endif if (frame_len <= 0) { ipcp_sdb_release(sdb); @@ -894,11 +901,8 @@ static void * eth_ipcp_sdu_reader(void * o) if (ssap == MGMT_SAP && dsap == MGMT_SAP) { #endif - pthread_mutex_lock(ð_data.mgmt_lock); - frame = malloc(sizeof(*frame)); if (frame == NULL) { - pthread_mutex_unlock(ð_data.mgmt_lock); #ifndef HAVE_NETMAP ipcp_sdb_release(sdb); #endif @@ -907,6 +911,8 @@ static void * eth_ipcp_sdu_reader(void * o) memcpy(frame->buf, &e_frame->payload, length); memcpy(frame->r_addr, e_frame->src_hwaddr, MAC_SIZE); + pthread_mutex_unlock(ð_data.mgmt_lock); + list_add(&frame->next, ð_data.mgmt_frames); pthread_cond_signal(ð_data.mgmt_cond); pthread_mutex_unlock(ð_data.mgmt_lock); @@ -979,7 +985,7 @@ static void * eth_ipcp_sdu_writer(void * o) pthread_rwlock_rdlock(ð_data.flows_lock); while ((fd = fqueue_next(eth_data.fq)) >= 0) { if (ipcp_flow_read(fd, &sdb)) { - log_err("Bad read from fd %d.", fd); + log_dbg("Bad read from fd %d.", fd); continue; } @@ -987,7 +993,7 @@ static void * eth_ipcp_sdu_writer(void * o) if (shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE) == NULL) { - log_err("Failed to allocate header."); + log_dbg("Failed to allocate header."); ipcp_sdb_release(sdb); } #if defined(BUILD_ETH_DIX) -- cgit v1.2.3 From 39e0358161212c5d662208360c1fdcb68ee6b64a Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Wed, 13 Jun 2018 11:59:26 +0200 Subject: ipcpd: Get mtu using ioctl before hw address The SIOCGIFMTU command uses the ifr struct, which is a union, so it can't store the hw address and the MTU at the same time. We now call SIOCGIFMTU and set the MTU before SIOCGIFHWADDR. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/eth/eth.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/ipcpd') diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index c76ef60a..7bac64ca 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -1243,12 +1243,6 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf) return -1; } - if (ioctl(skfd, SIOCGIFHWADDR, &ifr)) { - log_err("Failed to get hwaddr."); - close(skfd); - return -1; - } - if (ioctl(skfd, SIOCGIFMTU, &ifr)) { log_err("Failed to get MTU."); close(skfd); @@ -1269,6 +1263,12 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf) #endif log_dbg("Layer MTU is %d.", eth_data.mtu); + if (ioctl(skfd, SIOCGIFHWADDR, &ifr)) { + log_err("Failed to get hwaddr."); + close(skfd); + return -1; + } + close(skfd); idx = if_nametoindex(conf->dev); -- cgit v1.2.3 From 47c922f1360990f2da8363aafa0798551a2128ef Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Wed, 13 Jun 2018 13:18:10 +0200 Subject: lib: Use macros for all time utility functions This replaces the time utility functions with macros. This avoids using library functions in the tools and also slightly speeds up the implementation. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- CMakeLists.txt | 2 +- include/ouroboros/time_utils.h | 74 ++++++++++++++++----- src/ipcpd/normal/dht.c | 1 + src/ipcpd/normal/dir.c | 1 + src/lib/CMakeLists.txt | 1 - src/lib/time_utils.c | 144 ----------------------------------------- src/tools/oping/oping.c | 1 + src/tools/time_utils.h | 75 +++++++++++++++------ 8 files changed, 118 insertions(+), 181 deletions(-) delete mode 100644 src/lib/time_utils.c (limited to 'src/ipcpd') diff --git a/CMakeLists.txt b/CMakeLists.txt index af051078..3b3ef9bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include(GNUInstallDirs) set(PACKAGE_VERSION_MAJOR 0) set(PACKAGE_VERSION_MINOR 11) -set(PACKAGE_VERSION_PATCH 8) +set(PACKAGE_VERSION_PATCH 9) set(PACKAGE_NAME "${CMAKE_PROJECT_NAME}") set(PACKAGE_DESCRIPTION "The Ouroboros prototype") diff --git a/include/ouroboros/time_utils.h b/include/ouroboros/time_utils.h index d62b4c06..1d02cb1f 100644 --- a/include/ouroboros/time_utils.h +++ b/include/ouroboros/time_utils.h @@ -36,7 +36,6 @@ #include #include -#include /* LONG_MAX */ /* functions for timespecs */ #define ts_diff_ns(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * BILLION \ @@ -53,29 +52,70 @@ + ((tx)->tv_usec - (t0)->tv_usec) / MILLION) /* functions for timespecs */ -int ts_add(const struct timespec * t, - const struct timespec * intv, - struct timespec * res); -int ts_diff(const struct timespec * t, - const struct timespec * intv, - struct timespec * res); +#define ts_add(t, intv, res) \ + do { \ + time_t nanos = 0; \ + nanos = (t)->tv_nsec + (intv)->tv_nsec; \ + (res)->tv_sec = (t)->tv_sec + (intv)->tv_sec; \ + while (nanos >= BILLION) { \ + nanos -= BILLION; \ + ++((res)->tv_sec); \ + } \ + (res)->tv_nsec = nanos; \ + } while (0); + +#define ts_diff(t, intv, res) \ + do { \ + time_t nanos = 0; \ + nanos = (t)->tv_nsec - (intv)->tv_nsec; \ + (res)->tv_sec = (t)->tv_sec - (intv)->tv_sec; \ + while (nanos < 0) { \ + nanos += BILLION; \ + --((res)->tv_sec); \ + } \ + (res)->tv_nsec = nanos; \ + } while (0); /* functions for timevals */ -int tv_add(const struct timeval * t, - const struct timeval * intv, - struct timeval * res); -int tv_diff(const struct timeval * t, - const struct timeval * intv, - struct timeval * res); +#define tv_add(t, intv, res) \ + do { \ + time_t micros = 0; \ + micros = (t)->tv_usec + (intv)->tv_usec; \ + (res)->tv_sec = (t)->tv_sec + (intv)->tv_sec; \ + while (micros >= MILLION) { \ + micros -= MILLION; \ + ++((res)->tv_sec); \ + } \ + (res)->tv_usec = micros; \ + } while (0); + +#define tv_diff(t, intv, res) \ + do { \ + time_t micros = 0; \ + micros = (t)->tv_usec - (intv)->tv_usec; \ + (res)->tv_sec = (t)->tv_sec - (intv)->tv_sec; \ + while (micros < 0) { \ + micros += MILLION; \ + --((res)->tv_sec); \ + } \ + (res)->tv_usec = micros; \ + } while (0); + /* copying a timeval into a timespec */ -int tv_to_ts(const struct timeval * src, - struct timespec * dst); +#define tv_to_ts(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000L; \ + } while (0); /* copying a timespec into a timeval (loss of resolution) */ -int ts_to_tv(const struct timespec * src, - struct timeval * dst); +#define ts_to_tv(ts, tv) \ + do { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000L; \ + } while (0); #endif /* OUROBOROS_TIME_UTILS_H */ diff --git a/src/ipcpd/normal/dht.c b/src/ipcpd/normal/dht.c index 069b89d5..a6f1928b 100644 --- a/src/ipcpd/normal/dht.c +++ b/src/ipcpd/normal/dht.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "kademlia.pb-c.h" typedef KadMsg kad_msg_t; diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c index 1c883974..345d220d 100644 --- a/src/ipcpd/normal/dir.c +++ b/src/ipcpd/normal/dir.c @@ -37,6 +37,7 @@ #include #include #include +#include #define KAD_B (hash_len(ipcpi.dir_hash_algo) * CHAR_BIT) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 973c2458..e7e07802 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -206,7 +206,6 @@ set(SOURCE_FILES_COMMON shm_rbuff.c shm_rdrbuff.c sockets.c - time_utils.c tpm.c utils.c ) diff --git a/src/lib/time_utils.c b/src/lib/time_utils.c deleted file mode 100644 index 0701e2d3..00000000 --- a/src/lib/time_utils.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2018 - * - * Time utilities - * - * Dimitri Staessens - * Sander Vrijders - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#define _POSIX_C_SOURCE 199309L - -#include -#include - -/* functions for timespecs */ - -/* add intv to t and store it in res*/ -int ts_add(const struct timespec * t, - const struct timespec * intv, - struct timespec * res) -{ - time_t nanos = 0; - - if (t == NULL || intv == NULL || res == NULL) - return -1; - - nanos = t->tv_nsec + intv->tv_nsec; - - res->tv_sec = t->tv_sec + intv->tv_sec; - while (nanos >= BILLION) { - nanos -= BILLION; - ++(res->tv_sec); - } - - res->tv_nsec = nanos; - - return 0; -} - -/* subtract intv from t and stores it in res */ -int ts_diff(const struct timespec * t, - const struct timespec * intv, - struct timespec * res) -{ - time_t nanos = 0; - - if (t == NULL || intv == NULL || res == NULL) - return -1; - - nanos = t->tv_nsec - intv->tv_nsec; - - res->tv_sec = t->tv_sec - intv->tv_sec; - while (nanos < 0) { - nanos += BILLION; - --(res->tv_sec); - } - res->tv_nsec = nanos; - - return 0; -} - -/* functions for timevals */ - -/* add intv to t and store it in res*/ -int tv_add(const struct timeval * t, - const struct timeval * intv, - struct timeval * res) -{ - time_t micros = 0; - - if (t == NULL || intv == NULL || res == NULL) - return -1; - - micros = t->tv_usec + intv->tv_usec; - - res->tv_sec = t->tv_sec + intv->tv_sec; - while (micros >= MILLION) { - micros -= MILLION; - ++(res->tv_sec); - } - res->tv_usec = micros; - - return 0; -} - -/* subtract intv from t and stores it in res */ -int tv_diff(const struct timeval * t, - const struct timeval * intv, - struct timeval * res) -{ - time_t micros = 0; - - if (t == NULL || intv == NULL || res == NULL) - return -1; - - micros = t->tv_usec - intv->tv_usec; - - res->tv_sec = t->tv_sec - intv->tv_sec; - while (micros < 0) { - micros += MILLION; - --(res->tv_sec); - } - res->tv_usec = micros; - - return 0; -} - -int tv_to_ts(const struct timeval * src, - struct timespec * dst) -{ - if (src == NULL || dst == NULL) - return -1; - - dst->tv_sec = src->tv_sec; - dst->tv_nsec = src->tv_usec * 1000L; - - return 0; -} - -/* copying a timespec into a timeval (loss of resolution) */ -int ts_to_tv(const struct timespec * src, - struct timeval * dst) -{ - if (src == NULL || dst == NULL) - return -1; - - dst->tv_sec = src->tv_sec; - dst->tv_usec = src->tv_nsec / 1000L; - - return 0; -} diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c index 18801c2d..e3e9116f 100644 --- a/src/tools/oping/oping.c +++ b/src/tools/oping/oping.c @@ -46,6 +46,7 @@ #include "time_utils.h" +#include #include #include #include diff --git a/src/tools/time_utils.h b/src/tools/time_utils.h index c9760a8b..f4f561bd 100644 --- a/src/tools/time_utils.h +++ b/src/tools/time_utils.h @@ -35,7 +35,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ - #ifndef OUROBOROS_TOOLS_TIME_UTILS_H #define OUROBOROS_TOOLS_TIME_UTILS_H @@ -52,7 +51,6 @@ #include #include -#include /* LONG_MAX */ /* functions for timespecs */ #define ts_diff_ns(t0, tx) (((tx)->tv_sec - (t0)->tv_sec) * BILLION \ @@ -69,29 +67,70 @@ + ((tx)->tv_usec - (t0)->tv_usec) / MILLION) /* functions for timespecs */ -int ts_add(const struct timespec * t, - const struct timespec * intv, - struct timespec * res); -int ts_diff(const struct timespec * t, - const struct timespec * intv, - struct timespec * res); +#define ts_add(t, intv, res) \ + do { \ + time_t nanos = 0; \ + nanos = (t)->tv_nsec + (intv)->tv_nsec; \ + (res)->tv_sec = (t)->tv_sec + (intv)->tv_sec; \ + while (nanos >= BILLION) { \ + nanos -= BILLION; \ + ++((res)->tv_sec); \ + } \ + (res)->tv_nsec = nanos; \ + } while (0); + +#define ts_diff(t, intv, res) \ + do { \ + time_t nanos = 0; \ + nanos = (t)->tv_nsec - (intv)->tv_nsec; \ + (res)->tv_sec = (t)->tv_sec - (intv)->tv_sec; \ + while (nanos < 0) { \ + nanos += BILLION; \ + --((res)->tv_sec); \ + } \ + (res)->tv_nsec = nanos; \ + } while (0); /* functions for timevals */ -int tv_add(const struct timeval * t, - const struct timeval * intv, - struct timeval * res); -int tv_diff(const struct timeval * t, - const struct timeval * intv, - struct timeval * res); +#define tv_add(t, intv, res) \ + do { \ + time_t micros = 0; \ + nanos = (t)->tv_usec + (intv)->tv_usec; \ + (res)->tv_sec = (t)->tv_sec + (intv)->tv_sec; \ + while (micros >= MILLION) { \ + micros -= MILLION; \ + ++((res)->tv_sec); \ + } \ + (res)->tv_nsec = nanos; \ + } while (0); + +#define tv_diff(t, intv, res) \ + do { \ + time_t micros = 0; \ + micros = (t)->tv_usec - (intv)->tv_usec; \ + (res)->tv_sec = (t)->tv_sec - (intv)->tv_sec; \ + while (micros < 0) { \ + micros += MILLION; \ + --((res)->tv_sec); \ + } \ + (res)->tv_usec = micros; \ + } while (0); + /* copying a timeval into a timespec */ -int tv_to_ts(const struct timeval * src, - struct timespec * dst); +#define tv_to_ts(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000L; \ + } while (0); /* copying a timespec into a timeval (loss of resolution) */ -int ts_to_tv(const struct timespec * src, - struct timeval * dst); +#define ts_to_tv(ts, tv) \ + do { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000L; \ + } while (0); #endif /* OUROBOROS_TOOLS_TIME_UTILS_H */ -- cgit v1.2.3