summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/CMakeLists.txt72
-rw-r--r--src/ipcpd/broadcast/CMakeLists.txt41
-rw-r--r--src/ipcpd/broadcast/connmgr.c2
-rw-r--r--src/ipcpd/broadcast/dt.c62
-rw-r--r--src/ipcpd/broadcast/dt.h2
-rw-r--r--src/ipcpd/broadcast/main.c2
-rw-r--r--src/ipcpd/common/comp.h2
-rw-r--r--src/ipcpd/common/connmgr.c2
-rw-r--r--src/ipcpd/common/connmgr.h2
-rw-r--r--src/ipcpd/common/enroll.c2
-rw-r--r--src/ipcpd/common/enroll.h2
-rw-r--r--src/ipcpd/config.h.in17
-rw-r--r--src/ipcpd/eth/CMakeLists.txt155
-rw-r--r--src/ipcpd/eth/dix.c2
-rw-r--r--src/ipcpd/eth/eth.c75
-rw-r--r--src/ipcpd/eth/llc.c2
-rw-r--r--src/ipcpd/ipcp.c60
-rw-r--r--src/ipcpd/ipcp.h2
-rw-r--r--src/ipcpd/local/CMakeLists.txt43
-rw-r--r--src/ipcpd/local/main.c38
-rw-r--r--src/ipcpd/np1.h41
-rw-r--r--src/ipcpd/shim-data.c2
-rw-r--r--src/ipcpd/shim-data.h2
-rw-r--r--src/ipcpd/udp/CMakeLists.txt89
-rw-r--r--src/ipcpd/udp/udp.c35
-rw-r--r--src/ipcpd/udp/udp4.c2
-rw-r--r--src/ipcpd/udp/udp6.c2
-rw-r--r--src/ipcpd/unicast/CMakeLists.txt69
-rw-r--r--src/ipcpd/unicast/addr-auth.c2
-rw-r--r--src/ipcpd/unicast/addr-auth.h2
-rw-r--r--src/ipcpd/unicast/addr-auth/flat.c2
-rw-r--r--src/ipcpd/unicast/addr-auth/flat.h2
-rw-r--r--src/ipcpd/unicast/addr-auth/ops.h2
-rw-r--r--src/ipcpd/unicast/addr-auth/pol.h2
-rw-r--r--src/ipcpd/unicast/ca.c2
-rw-r--r--src/ipcpd/unicast/ca.h2
-rw-r--r--src/ipcpd/unicast/ca/mb-ecn.c2
-rw-r--r--src/ipcpd/unicast/ca/mb-ecn.h2
-rw-r--r--src/ipcpd/unicast/ca/nop.c2
-rw-r--r--src/ipcpd/unicast/ca/nop.h2
-rw-r--r--src/ipcpd/unicast/ca/ops.h2
-rw-r--r--src/ipcpd/unicast/ca/pol.h2
-rw-r--r--src/ipcpd/unicast/connmgr.c2
-rw-r--r--src/ipcpd/unicast/dir.c2
-rw-r--r--src/ipcpd/unicast/dir.h2
-rw-r--r--src/ipcpd/unicast/dir/dht.c424
-rw-r--r--src/ipcpd/unicast/dir/dht.h2
-rw-r--r--src/ipcpd/unicast/dir/dht.proto2
-rw-r--r--src/ipcpd/unicast/dir/ops.h2
-rw-r--r--src/ipcpd/unicast/dir/pol.h2
-rw-r--r--src/ipcpd/unicast/dir/tests/CMakeLists.txt44
-rw-r--r--src/ipcpd/unicast/dir/tests/dht_test.c47
-rw-r--r--src/ipcpd/unicast/dt.c48
-rw-r--r--src/ipcpd/unicast/dt.h8
-rw-r--r--src/ipcpd/unicast/fa.c85
-rw-r--r--src/ipcpd/unicast/fa.h4
-rw-r--r--src/ipcpd/unicast/main.c2
-rw-r--r--src/ipcpd/unicast/pff.c2
-rw-r--r--src/ipcpd/unicast/pff.h2
-rw-r--r--src/ipcpd/unicast/pff/alternate.c2
-rw-r--r--src/ipcpd/unicast/pff/alternate.h2
-rw-r--r--src/ipcpd/unicast/pff/multipath.c2
-rw-r--r--src/ipcpd/unicast/pff/multipath.h2
-rw-r--r--src/ipcpd/unicast/pff/ops.h2
-rw-r--r--src/ipcpd/unicast/pff/pft.c2
-rw-r--r--src/ipcpd/unicast/pff/pft.h2
-rw-r--r--src/ipcpd/unicast/pff/pol.h2
-rw-r--r--src/ipcpd/unicast/pff/simple.c2
-rw-r--r--src/ipcpd/unicast/pff/simple.h2
-rw-r--r--src/ipcpd/unicast/pff/tests/CMakeLists.txt38
-rw-r--r--src/ipcpd/unicast/pff/tests/pft_test.c2
-rw-r--r--src/ipcpd/unicast/psched.c14
-rw-r--r--src/ipcpd/unicast/psched.h6
-rw-r--r--src/ipcpd/unicast/routing.c2
-rw-r--r--src/ipcpd/unicast/routing.h2
-rw-r--r--src/ipcpd/unicast/routing/graph.c84
-rw-r--r--src/ipcpd/unicast/routing/graph.h2
-rw-r--r--src/ipcpd/unicast/routing/link-state.c88
-rw-r--r--src/ipcpd/unicast/routing/link-state.h2
-rw-r--r--src/ipcpd/unicast/routing/ops.h2
-rw-r--r--src/ipcpd/unicast/routing/pol.h2
-rw-r--r--src/ipcpd/unicast/routing/tests/CMakeLists.txt38
-rw-r--r--src/ipcpd/unicast/routing/tests/graph_test.c2
83 files changed, 789 insertions, 1050 deletions
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt
index b3b049e3..609da54a 100644
--- a/src/ipcpd/CMakeLists.txt
+++ b/src/ipcpd/CMakeLists.txt
@@ -1,60 +1,30 @@
-set(CONNMGR_RCV_TIMEOUT 1000 CACHE STRING
- "Timeout for the connection manager to wait for OCEP info (ms).")
-set(IPCP_DEBUG_LOCAL FALSE CACHE BOOL
- "Use PID as address for local debugging")
-set(IPCP_QOS_CUBE_BE_PRIO 50 CACHE STRING
- "Priority for best effort QoS cube (0-99)")
-set(IPCP_QOS_CUBE_VIDEO_PRIO 90 CACHE STRING
- "Priority for video QoS cube (0-99)")
-set(IPCP_QOS_CUBE_VOICE_PRIO 99 CACHE STRING
- "Priority for voice QoS cube (0-99)")
-set(IPCP_MIN_THREADS 4 CACHE STRING
- "Minimum number of worker threads in the IPCP")
-set(IPCP_ADD_THREADS 4 CACHE STRING
- "Number of extra threads to start when an IPCP faces thread starvation")
-set(IPCP_SCHED_THR_MUL 2 CACHE STRING
- "Number of scheduler threads per QoS cube")
-set(DISABLE_CORE_LOCK TRUE CACHE BOOL
- "Disable locking performance threads to a core")
-set(DHT_ENROLL_SLACK 50 CACHE STRING
- "DHT enrollment waiting time (0-999, ms)")
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
- set(IPCP_LINUX_TIMERSLACK_NS 1000 CACHE STRING
- "Slack value for high resolution timers on Linux systems.")
-endif ()
-
-if ((IPCP_QOS_CUBE_BE_PRIO LESS 0) OR (IPCP_QOS_CUBE_BE_PRIO GREATER 99))
- message(FATAL_ERROR "Invalid priority for best effort QoS cube")
-endif ()
-
-if ((IPCP_QOS_CUBE_VIDEO_PRIO LESS 0) OR (IPCP_QOS_CUBE_VIDEO_PRIO GREATER 99))
- message(FATAL_ERROR "Invalid priority for video QoS cube")
-endif ()
-
-if ((IPCP_QOS_CUBE_VOICE_PRIO LESS 0) OR (IPCP_QOS_CUBE_VOICE_PRIO GREATER 99))
- message(FATAL_ERROR "Invalid priority for voice QoS cube")
-endif ()
-
-if ((DHT_ENROLL_SLACK LESS 0) OR (DHT_ENROLL_SLACK GREATER 999))
- message(FATAL_ERROR "Invalid DHT slack value")
-endif ()
-
+# IPCP (IPC Process) daemons build configuration
+# Configuration options and validation are in cmake/config/ipcp/*.cmake
+# Common sources shared by all IPCPs (absolute paths for subdirectories)
set(IPCP_SOURCES
- # Add source files here
${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c
${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c
- )
+)
-set (COMMON_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/common/enroll.c
- )
+set(COMMON_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/common/enroll.c
+)
-add_subdirectory(local)
-add_subdirectory(eth)
-add_subdirectory(udp)
-add_subdirectory(unicast)
-add_subdirectory(broadcast)
+set(IPCP_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
+
+add_subdirectory(local)
+add_subdirectory(broadcast)
+add_subdirectory(unicast)
+if(HAVE_ETH)
+ add_subdirectory(eth)
+endif()
+add_subdirectory(udp)
diff --git a/src/ipcpd/broadcast/CMakeLists.txt b/src/ipcpd/broadcast/CMakeLists.txt
index d85f335e..6749f660 100644
--- a/src/ipcpd/broadcast/CMakeLists.txt
+++ b/src/ipcpd/broadcast/CMakeLists.txt
@@ -1,35 +1,20 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+# Broadcast IPCP build configuration
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-set(IPCP_BROADCAST_TARGET ipcpd-broadcast CACHE INTERNAL "")
-set(IPCP_BROADCAST_MPL 60 CACHE STRING
- "Default maximum packet lifetime for the broadcast IPCP, in seconds")
-
-set(SOURCE_FILES
- # Add source files here
+set(BROADCAST_SOURCES
connmgr.c
dt.c
main.c
- )
+)
+
+add_executable(${IPCP_BROADCAST_TARGET}
+ ${BROADCAST_SOURCES}
+ ${IPCP_SOURCES}
+ ${COMMON_SOURCES}
+)
-add_executable(ipcpd-broadcast ${SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES}
- ${LAYER_CONFIG_PROTO_SRCS})
-target_link_libraries(ipcpd-broadcast LINK_PUBLIC ouroboros-dev)
+target_include_directories(${IPCP_BROADCAST_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS})
+target_link_libraries(${IPCP_BROADCAST_TARGET} PRIVATE ouroboros-dev)
-include(AddCompileFlags)
-if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-broadcast -DCONFIG_OUROBOROS_DEBUG)
-endif ()
+ouroboros_target_debug_definitions(${IPCP_BROADCAST_TARGET})
-install(TARGETS ipcpd-broadcast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+install(TARGETS ${IPCP_BROADCAST_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
diff --git a/src/ipcpd/broadcast/connmgr.c b/src/ipcpd/broadcast/connmgr.c
index f297175d..a4d20ee7 100644
--- a/src/ipcpd/broadcast/connmgr.c
+++ b/src/ipcpd/broadcast/connmgr.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Handles connections between components
*
diff --git a/src/ipcpd/broadcast/dt.c b/src/ipcpd/broadcast/dt.c
index 938c9085..30e89a4f 100644
--- a/src/ipcpd/broadcast/dt.c
+++ b/src/ipcpd/broadcast/dt.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Forward loop for broadcast
*
@@ -58,14 +58,13 @@ struct nb {
};
struct {
- struct list_head nbs;
- size_t nbs_len;
- pthread_rwlock_t nbs_lock;
+ struct llist nbs;
+ pthread_rwlock_t lock;
- fset_t * set;
+ fset_t * set;
- pthread_t reader;
- pthread_t listener;
+ pthread_t reader;
+ pthread_t listener;
} fwd;
static int dt_add_nb(int fd)
@@ -73,12 +72,12 @@ static int dt_add_nb(int fd)
struct list_head * p;
struct nb * nb;
- pthread_rwlock_wrlock(&fwd.nbs_lock);
+ pthread_rwlock_wrlock(&fwd.lock);
- list_for_each(p, &fwd.nbs) {
+ llist_for_each(p, &fwd.nbs) {
struct nb * el = list_entry(p, struct nb, next);
if (el->fd == fd) {
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
log_warn("Already know neighbor on fd %d.", fd);
return 0;
}
@@ -86,18 +85,16 @@ static int dt_add_nb(int fd)
nb = malloc(sizeof(*nb));
if (nb == NULL) {
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
log_err("Failed to malloc neighbor struct.");
return -ENOMEM;
}
nb->fd = fd;
- list_add_tail(&nb->next, p);
+ llist_add_tail(&nb->next, &fwd.nbs);
- ++fwd.nbs_len;
-
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
log_dbg("Neighbor %d added.", fd);
@@ -109,21 +106,20 @@ static int dt_del_nb(int fd)
struct list_head * p;
struct list_head * h;
- pthread_rwlock_wrlock(&fwd.nbs_lock);
+ pthread_rwlock_wrlock(&fwd.lock);
- list_for_each_safe(p, h, &fwd.nbs) {
+ llist_for_each_safe(p, h, &fwd.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->fd == fd) {
- list_del(&nb->next);
- --fwd.nbs_len;
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ llist_del(&nb->next, &fwd.nbs);
+ pthread_rwlock_unlock(&fwd.lock);
log_dbg("Neighbor %d deleted.", nb->fd);
free(nb);
return 0;
}
}
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
log_err("Neighbor not found on fd %d.", fd);
@@ -157,11 +153,11 @@ static void dt_packet(uint8_t * buf,
{
struct list_head * p;
- pthread_rwlock_rdlock(&fwd.nbs_lock);
+ pthread_rwlock_rdlock(&fwd.lock);
- pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.nbs_lock);
+ pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.lock);
- list_for_each(p, &fwd.nbs) {
+ llist_for_each(p, &fwd.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->fd != in_fd)
flow_write(nb->fd, buf, len); /* FIXME: avoid copy. */
@@ -252,12 +248,12 @@ int dt_init(void)
strcpy(info.comp_name, DT);
strcpy(info.comp_name, DT_COMP);
- list_head_init(&fwd.nbs);
+ llist_init(&fwd.nbs);
if (notifier_reg(handle_event, NULL))
goto fail_notifier_reg;
- if (pthread_rwlock_init(&fwd.nbs_lock, NULL))
+ if (pthread_rwlock_init(&fwd.lock, NULL))
goto fail_lock_init;
fwd.set = fset_create();
@@ -273,8 +269,6 @@ int dt_init(void)
if (connmgr_comp_init(COMPID_DT, &info))
goto fail_connmgr_comp_init;
- fwd.nbs_len = 0;
-
return 0;
fail_connmgr_comp_init:
@@ -286,7 +280,7 @@ int dt_init(void)
fail_pthread_create_reader:
fset_destroy(fwd.set);
fail_fset_create:
- pthread_rwlock_destroy(&fwd.nbs_lock);
+ pthread_rwlock_destroy(&fwd.lock);
fail_lock_init:
notifier_unreg(handle_event);
fail_notifier_reg:
@@ -308,15 +302,15 @@ void dt_fini(void)
fset_destroy(fwd.set);
- pthread_rwlock_wrlock(&fwd.nbs_lock);
+ pthread_rwlock_wrlock(&fwd.lock);
- list_for_each_safe(p, h, &fwd.nbs) {
+ llist_for_each_safe(p, h, &fwd.nbs) {
struct nb * n = list_entry(p, struct nb, next);
- list_del(&n->next);
+ llist_del(&n->next, &fwd.nbs);
free(n);
}
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
- pthread_rwlock_destroy(&fwd.nbs_lock);
+ pthread_rwlock_destroy(&fwd.lock);
}
diff --git a/src/ipcpd/broadcast/dt.h b/src/ipcpd/broadcast/dt.h
index 8d3b83f8..2472831e 100644
--- a/src/ipcpd/broadcast/dt.h
+++ b/src/ipcpd/broadcast/dt.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Forward loop for broadcast
*
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c
index 151b38c8..b3cbdc79 100644
--- a/src/ipcpd/broadcast/main.c
+++ b/src/ipcpd/broadcast/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Broadcast IPC Process
*
diff --git a/src/ipcpd/common/comp.h b/src/ipcpd/common/comp.h
index f3790d9c..e1d025b6 100644
--- a/src/ipcpd/common/comp.h
+++ b/src/ipcpd/common/comp.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Components for the unicast/broadcast IPC process
*
diff --git a/src/ipcpd/common/connmgr.c b/src/ipcpd/common/connmgr.c
index 1bb8c932..48ad79ba 100644
--- a/src/ipcpd/common/connmgr.c
+++ b/src/ipcpd/common/connmgr.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Handles connections between components
*
diff --git a/src/ipcpd/common/connmgr.h b/src/ipcpd/common/connmgr.h
index 0710dbbf..f48ecd1b 100644
--- a/src/ipcpd/common/connmgr.h
+++ b/src/ipcpd/common/connmgr.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Handles the different AP connections
*
diff --git a/src/ipcpd/common/enroll.c b/src/ipcpd/common/enroll.c
index 8e5384a5..959cca07 100644
--- a/src/ipcpd/common/enroll.c
+++ b/src/ipcpd/common/enroll.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Enrollment Task
*
diff --git a/src/ipcpd/common/enroll.h b/src/ipcpd/common/enroll.h
index f26c31a3..f56adfc8 100644
--- a/src/ipcpd/common/enroll.h
+++ b/src/ipcpd/common/enroll.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Enrollment Task
*
diff --git a/src/ipcpd/config.h.in b/src/ipcpd/config.h.in
index d2af6440..0b4252e5 100644
--- a/src/ipcpd/config.h.in
+++ b/src/ipcpd/config.h.in
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process configuration
*
@@ -29,11 +29,9 @@
#define SOCKET_TIMEOUT @SOCKET_TIMEOUT@
#define CONNECT_TIMEOUT @CONNECT_TIMEOUT@
-#define SHM_BUFFER_SIZE @SHM_BUFFER_SIZE@
-#define SHM_RDRB_BLOCK_SIZE @SHM_RDRB_BLOCK_SIZE@
+#define SSM_POOL_BLOCK_SIZE @SSM_POOL_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@
@@ -47,11 +45,11 @@
#define QOS_PRIO_VOICE @IPCP_QOS_CUBE_VOICE_PRIO@
#define IPCP_SCHED_THR_MUL @IPCP_SCHED_THR_MUL@
#define PFT_SIZE @PFT_SIZE@
-#define DHT_ENROLL_SLACK @DHT_ENROLL_SLACK@
#define IPCP_UNICAST_MPL @IPCP_UNICAST_MPL@
#define CONNMGR_RCV_TIMEOUT @CONNMGR_RCV_TIMEOUT@
#cmakedefine DISABLE_CORE_LOCK
+#cmakedefine BUILD_CONTAINER
#cmakedefine IPCP_FLOW_STATS
#cmakedefine IPCP_DEBUG_LOCAL
#ifdef CONFIG_OUROBOROS_DEBUG
@@ -73,10 +71,11 @@
#cmakedefine HAVE_BPF
#cmakedefine HAVE_RAW_SOCKETS
#cmakedefine IPCP_ETH_QDISC_BYPASS
-#define IPCP_ETH_RD_THR @IPCP_ETH_RD_THR@
-#define IPCP_ETH_WR_THR @IPCP_ETH_WR_THR@
-#define IPCP_ETH_LO_MTU @IPCP_ETH_LO_MTU@
-#define IPCP_ETH_MPL @IPCP_ETH_MPL@
+#define IPCP_ETH_RD_THR @IPCP_ETH_RD_THR@
+#define IPCP_ETH_WR_THR @IPCP_ETH_WR_THR@
+#define IPCP_ETH_LO_MTU @IPCP_ETH_LO_MTU@
+#define IPCP_ETH_MGMT_FRAME_SIZE @IPCP_ETH_MGMT_FRAME_SIZE@
+#define IPCP_ETH_MPL @IPCP_ETH_MPL@
/* local */
#define IPCP_LOCAL_MPL @IPCP_LOCAL_MPL@
diff --git a/src/ipcpd/eth/CMakeLists.txt b/src/ipcpd/eth/CMakeLists.txt
index 44299a59..5a36352d 100644
--- a/src/ipcpd/eth/CMakeLists.txt
+++ b/src/ipcpd/eth/CMakeLists.txt
@@ -1,134 +1,21 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-find_path(NETMAP_C_INCLUDE_DIR
- net/netmap_user.h
- HINTS /usr/include /usr/local/include)
-
-mark_as_advanced(NETMAP_C_INCLUDE_DIR)
-
-# Check for raw sockets
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
- set(DISABLE_RAW_SOCKETS FALSE CACHE BOOL
- "Disable raw socket support for Ethernet IPCPs")
- if (NOT DISABLE_RAW_SOCKETS)
- message(STATUS "Raw socket support for Ethernet IPCPs enabled")
- set(HAVE_RAW_SOCKETS TRUE PARENT_SCOPE)
- set(HAVE_RAW_SOCKETS TRUE)
- set(HAVE_ETH TRUE)
- else ()
- message(STATUS "Raw socket support for Ethernet IPCPs disabled by user")
- unset(HAVE_RAW_SOCKETS PARENT_SCOPE)
- unset(HAVE_RAW_SOCKETS)
- endif ()
-endif ()
-
-# Check for BPF
-if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
- find_path(BPF_C_INCLUDE_DIR
- net/bpf.h
- HINTS /usr/include /usr/local/include)
-
- mark_as_advanced(BPF_C_INCLUDE_DIR)
-
- if (BPF_C_INCLUDE_DIR)
- set(DISABLE_BPF FALSE CACHE BOOL
- "Disable Berkeley Packet Filter support for Ethernet IPCPs")
- if (NOT DISABLE_BPF)
- message(STATUS "Berkeley Packet Filter support "
- "for Ethernet IPCPs enabled")
- set(HAVE_BPF TRUE PARENT_SCOPE)
- set(HAVE_BPF TRUE)
- set(HAVE_ETH TRUE)
- else ()
- message(STATUS "Berkeley Packet Filter support "
- "for Ethernet IPCPs disabled by user")
- unset(HAVE_BPF PARENT_SCOPE)
- unset(HAVE_BPF)
- endif ()
- endif ()
-endif ()
-
-# Check for netmap exclusively
-if (NOT HAVE_RAW_SOCKETS AND NOT HAVE_BPF AND NETMAP_C_INCLUDE_DIR)
- set(DISABLE_NETMAP FALSE CACHE BOOL
- "Disable netmap support for ETH IPCPs")
- if (NOT DISABLE_NETMAP)
- message(STATUS "Netmap support for Ethernet IPCPs enabled")
- set(HAVE_NETMAP TRUE PARENT_SCOPE)
- set(HAVE_ETH TRUE)
- else ()
- message(STATUS "Netmap support for Ethernet IPCPs disabled by user")
- unset(HAVE_NETMAP PARENT_SCOPE)
- endif ()
-endif ()
-
-if (HAVE_ETH)
- message(STATUS "Supported raw packet API found, building eth-llc and eth-dix")
-
- set(IPCP_ETH_RD_THR 1 CACHE STRING
- "Number of reader threads in Ethernet IPCP")
- set(IPCP_ETH_WR_THR 1 CACHE STRING
- "Number of writer threads in Ethernet IPCP")
- set(IPCP_ETH_QDISC_BYPASS false CACHE BOOL
- "Bypass the Qdisc in the kernel when using raw sockets")
- set(IPCP_ETH_LO_MTU 1500 CACHE STRING
- "Restrict Ethernet MTU over loopback interfaces")
- set(IPCP_ETH_MPL 100 CACHE STRING
- "Default maximum packet lifetime for the Ethernet IPCPs, in ms")
-
- set(ETH_LLC_SOURCES
- # Add source files here
- llc.c
- )
-
- set(ETH_DIX_SOURCES
- # Add source files here
- dix.c
- )
-
- set(IPCP_ETH_LLC_TARGET ipcpd-eth-llc CACHE INTERNAL "")
- set(IPCP_ETH_DIX_TARGET ipcpd-eth-dix CACHE INTERNAL "")
-
- add_executable(ipcpd-eth-llc ${ETH_LLC_SOURCES} ${IPCP_SOURCES})
- add_executable(ipcpd-eth-dix ${ETH_DIX_SOURCES} ${IPCP_SOURCES})
-
- if (HAVE_BPF AND NOT APPLE)
- target_include_directories(ipcpd-eth-llc PUBLIC ${BPF_C_INCLUDE_DIR})
- target_include_directories(ipcpd-eth-dix PUBLIC ${BPF_C_INCLUDE_DIR})
- endif ()
-
- if (HAVE_NETMAP AND NOT APPLE)
- set_target_properties(ipcpd-eth-llc PROPERTIES
- COMPILE_FLAGS "${CMAKE_C_FLAGS} -std=c99")
- set_target_properties(ipcpd-eth-dix PROPERTIES
- COMPILE_FLAGS "${CMAKE_C_FLAGS} -std=c99")
- target_include_directories(ipcpd-eth-llc PUBLIC
- ${NETMAP_C_INCLUDE_DIR})
- target_include_directories(ipcpd-eth-dix PUBLIC
- ${NETMAP_C_INCLUDE_DIR})
- endif ()
-
- target_link_libraries(ipcpd-eth-llc LINK_PUBLIC ouroboros-dev)
- target_link_libraries(ipcpd-eth-dix LINK_PUBLIC ouroboros-dev)
-
- include(AddCompileFlags)
- if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-eth-llc -DCONFIG_OUROBOROS_DEBUG)
- add_compile_flags(ipcpd-eth-dix -DCONFIG_OUROBOROS_DEBUG)
- endif ()
-
- install(TARGETS ipcpd-eth-llc ipcpd-eth-dix RUNTIME DESTINATION
- ${CMAKE_INSTALL_SBINDIR})
-endif ()
+# Ethernet IPCPs build configuration (LLC and DIX)
+# HAVE_ETH detection is in cmake/dependencies.cmake
+
+add_executable(${IPCP_ETH_LLC_TARGET} llc.c ${IPCP_SOURCES})
+add_executable(${IPCP_ETH_DIX_TARGET} dix.c ${IPCP_SOURCES})
+
+foreach(target ${IPCP_ETH_LLC_TARGET} ${IPCP_ETH_DIX_TARGET})
+ target_include_directories(${target} PRIVATE ${IPCP_INCLUDE_DIRS})
+ if(HAVE_BPF AND NOT APPLE)
+ target_include_directories(${target} PRIVATE ${BPF_C_INCLUDE_DIR})
+ endif()
+ if(HAVE_NETMAP AND NOT APPLE)
+ target_compile_options(${target} PRIVATE -std=c99)
+ target_include_directories(${target} PRIVATE ${NETMAP_C_INCLUDE_DIR})
+ endif()
+ target_link_libraries(${target} PRIVATE ouroboros-dev)
+ ouroboros_target_debug_definitions(${target})
+endforeach()
+
+install(TARGETS ${IPCP_ETH_LLC_TARGET} ${IPCP_ETH_DIX_TARGET}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
diff --git a/src/ipcpd/eth/dix.c b/src/ipcpd/eth/dix.c
index 37b9896d..cf8253bd 100644
--- a/src/ipcpd/eth/dix.c
+++ b/src/ipcpd/eth/dix.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC processes over Ethernet - DIX
*
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 0b6a91fb..4be7775e 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC processes over Ethernet
*
@@ -52,6 +52,7 @@
#include <ouroboros/pthread.h>
#include "ipcp.h"
+#include "np1.h"
#include "shim-data.h"
#include <signal.h>
@@ -138,7 +139,7 @@
#define NAME_QUERY_TIMEO 2000 /* ms */
#define MGMT_TIMEO 100 /* ms */
-#define MGMT_FRAME_SIZE 2048
+#define MGMT_FRAME_SIZE IPCP_ETH_MGMT_FRAME_SIZE
#define FLOW_REQ 0
#define FLOW_REPLY 1
@@ -474,6 +475,8 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr,
if (buf == NULL)
return -1;
+ memset(buf, 0, len + ETH_HEADER_TOT_SIZE + data->len);
+
msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE);
msg->code = FLOW_REQ;
#if defined(BUILD_ETH_DIX)
@@ -526,6 +529,8 @@ static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
if (buf == NULL)
return -1;
+ memset(buf, 0, sizeof(*msg) + ETH_HEADER_TOT_SIZE + data->len);
+
msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE);
msg->code = FLOW_REPLY;
@@ -664,6 +669,8 @@ static int eth_ipcp_name_query_req(const uint8_t * hash,
if (buf == NULL)
return -1;
+ memset(buf, 0, len + ETH_HEADER_TOT_SIZE);
+
msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE);
msg->code = NAME_QUERY_REPLY;
@@ -833,7 +840,7 @@ static void * eth_ipcp_packet_reader(void * o)
#if defined(HAVE_NETMAP)
struct nm_pkthdr hdr;
#else
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
fd_set fds;
int frame_len;
#endif
@@ -865,21 +872,21 @@ static void * eth_ipcp_packet_reader(void * o)
if (select(eth_data.bpf + 1, &fds, NULL, NULL, NULL))
continue;
assert(FD_ISSET(eth_data.bpf, &fds));
- if (ipcp_sdb_reserve(&sdb, BPF_LEN))
+ if (ipcp_spb_reserve(&spb, BPF_LEN))
continue;
- buf = shm_du_buff_head(sdb);
+ buf = ssm_pk_buff_head(spb);
frame_len = read(eth_data.bpf, buf, BPF_BLEN);
#elif defined(HAVE_RAW_SOCKETS)
FD_SET(eth_data.s_fd, &fds);
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_MTU))
+ if (ipcp_spb_reserve(&spb, ETH_MTU))
continue;
- buf = shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE);
+ buf = ssm_pk_buff_head_alloc(spb, ETH_HEADER_TOT_SIZE);
if (buf == NULL) {
log_dbg("Failed to allocate header.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
continue;
}
frame_len = recv(eth_data.s_fd, buf,
@@ -887,7 +894,7 @@ static void * eth_ipcp_packet_reader(void * o)
#endif
if (frame_len <= 0) {
log_dbg("Failed to receive frame.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
continue;
}
#endif
@@ -929,7 +936,13 @@ static void * eth_ipcp_packet_reader(void * o)
if (ssap == MGMT_SAP && dsap == MGMT_SAP) {
#endif
- ipcp_sdb_release(sdb); /* No need for the N+1 buffer. */
+ ipcp_spb_release(spb); /* No need for the N+1 buffer. */
+
+ if (length > MGMT_FRAME_SIZE) {
+ log_warn("Management frame size %u exceeds %u.",
+ length, MGMT_FRAME_SIZE);
+ goto fail_frame;
+ }
frame = malloc(sizeof(*frame));
if (frame == NULL) {
@@ -969,22 +982,22 @@ static void * eth_ipcp_packet_reader(void * o)
pthread_rwlock_unlock(&eth_data.flows_lock);
#ifndef HAVE_NETMAP
- shm_du_buff_head_release(sdb, ETH_HEADER_TOT_SIZE);
- shm_du_buff_truncate(sdb, length);
+ ssm_pk_buff_head_release(spb, ETH_HEADER_TOT_SIZE);
+ ssm_pk_buff_truncate(spb, length);
#else
- if (ipcp_sdb_reserve(&sdb, length))
+ if (ipcp_spb_reserve(&spb, length))
continue;
- buf = shm_du_buff_head(sdb);
+ buf = ssm_pk_buff_head(spb);
memcpy(buf, &e_frame->payload, length);
#endif
- if (np1_flow_write(fd, sdb) < 0)
- ipcp_sdb_release(sdb);
+ if (np1_flow_write(fd, spb, NP1_GET_POOL(fd)) < 0)
+ ipcp_spb_release(spb);
continue;
fail_frame:
#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
#endif
}
}
@@ -1000,7 +1013,7 @@ static void cleanup_writer(void * o)
static void * eth_ipcp_packet_writer(void * o)
{
int fd;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
size_t len;
#if defined(BUILD_ETH_DIX)
uint16_t deid;
@@ -1028,17 +1041,17 @@ static void * eth_ipcp_packet_writer(void * o)
if (fqueue_type(fq) != FLOW_PKT)
continue;
- if (np1_flow_read(fd, &sdb)) {
+ if (np1_flow_read(fd, &spb, NP1_GET_POOL(fd))) {
log_dbg("Bad read from fd %d.", fd);
continue;
}
- len = shm_du_buff_len(sdb);
+ len = ssm_pk_buff_len(spb);
- if (shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE)
+ if (ssm_pk_buff_head_alloc(spb, ETH_HEADER_TOT_SIZE)
== NULL) {
log_dbg("Failed to allocate header.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
continue;
}
@@ -1061,10 +1074,10 @@ static void * eth_ipcp_packet_writer(void * o)
#elif defined(BUILD_ETH_LLC)
dsap, ssap,
#endif
- shm_du_buff_head(sdb),
+ ssm_pk_buff_head(spb),
len))
log_dbg("Failed to send frame.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
}
}
@@ -1330,14 +1343,7 @@ static int eth_set_mtu(struct ifreq * ifr)
IPCP_ETH_LO_MTU);
eth_data.mtu = IPCP_ETH_LO_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);
return 0;
@@ -1491,9 +1497,6 @@ static int eth_ipcp_bootstrap(struct ipcp_config * conf)
char ifn[IFNAMSIZ];
#endif /* HAVE_NETMAP */
-#ifndef SHM_RDRB_MULTI_BLOCK
- size_t maxsz;
-#endif
assert(conf);
assert(conf->type == THIS_TYPE);
@@ -1650,6 +1653,8 @@ static int eth_ipcp_query(const uint8_t * hash)
if (buf == NULL)
return -1;
+ memset(buf, 0, len + ETH_HEADER_TOT_SIZE);
+
msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE);
msg->code = NAME_QUERY_REQ;
diff --git a/src/ipcpd/eth/llc.c b/src/ipcpd/eth/llc.c
index c900dcab..a772e86e 100644
--- a/src/ipcpd/eth/llc.c
+++ b/src/ipcpd/eth/llc.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC processes over Ethernet - LLC
*
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index ebb9b1c5..5ad2401f 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process main loop
*
@@ -52,6 +52,7 @@
#include <ouroboros/utils.h>
#include "ipcp.h"
+#include "np1.h"
#include <signal.h>
#include <string.h>
@@ -131,6 +132,8 @@ struct {
pthread_t acceptor;
} ipcpd;
+struct np1_state np1;
+
struct cmd {
struct list_head next;
@@ -205,7 +208,7 @@ static int ipcp_rib_read(const char * path,
char * buf,
size_t len)
{
- char * entry;
+ const char * entry;
if (len < LAYER_NAME_SIZE + 2) /* trailing \n */
return 0;
@@ -633,9 +636,11 @@ static void do_flow_alloc(pid_t pid,
uint8_t * dst,
qosspec_t qs,
const buffer_t * data,
+ uid_t uid,
ipcp_msg_t * ret_msg)
{
- int fd;
+ int fd;
+ struct ssm_pool * pool = NULL;
log_info("Allocating flow %d for %d to " HASH_FMT32 ".",
flow_id, pid, HASH_VAL32(dst));
@@ -662,6 +667,17 @@ static void do_flow_alloc(pid_t pid,
return;
}
+ if (uid != 0) {
+ pool = ssm_pool_open(uid);
+ if (pool == NULL) {
+ log_err("Failed to open PUP for uid %d.", uid);
+ ret_msg->result = -ENOMEM;
+ return;
+ }
+ }
+
+ NP1_SET_POOL(fd, pool);
+
ret_msg->result = ipcpd.ops->ipcp_flow_alloc(fd, dst, qs, data);
log_info("Finished allocating flow %d to " HASH_FMT32 ".",
@@ -672,9 +688,11 @@ static void do_flow_alloc(pid_t pid,
static void do_flow_join(pid_t pid,
int flow_id,
const uint8_t * dst,
+ uid_t uid,
ipcp_msg_t * ret_msg)
{
- int fd;
+ int fd;
+ struct ssm_pool * pool = NULL;
log_info("Joining layer " HASH_FMT32 ".", HASH_VAL32(dst));
@@ -699,6 +717,17 @@ static void do_flow_join(pid_t pid,
return;
}
+ if (uid != 0) {
+ pool = ssm_pool_open(uid);
+ if (pool == NULL) {
+ log_err("Failed to open PUP for uid %d.", uid);
+ ret_msg->result = -ENOMEM;
+ return;
+ }
+ }
+
+ NP1_SET_POOL(fd, pool);
+
ret_msg->result = ipcpd.ops->ipcp_flow_join(fd, dst);
log_info("Finished joining layer " HASH_FMT32 ".", HASH_VAL32(dst));
@@ -706,10 +735,12 @@ static void do_flow_join(pid_t pid,
static void do_flow_alloc_resp(int resp,
int flow_id,
+ uid_t uid,
const buffer_t * data,
ipcp_msg_t * ret_msg)
{
- int fd = -1;
+ int fd = -1;
+ struct ssm_pool * pool = NULL;
log_info("Responding %d to alloc on flow_id %d.", resp, flow_id);
@@ -737,6 +768,17 @@ static void do_flow_alloc_resp(int resp,
return;
}
+ if (uid != 0) {
+ pool = ssm_pool_open(uid);
+ if (pool == NULL) {
+ log_err("Failed to open PUP for uid %d.", uid);
+ ret_msg->result = -ENOMEM;
+ return;
+ }
+ }
+
+ NP1_SET_POOL(fd, pool);
+
ret_msg->result = ipcpd.ops->ipcp_flow_alloc_resp(fd, resp, data);
log_info("Finished responding %d to allocation request.",
@@ -857,12 +899,12 @@ static void * mainloop(void * o)
qs = qos_spec_msg_to_s(msg->qosspec);
do_flow_alloc(msg->pid, msg->flow_id,
msg->hash.data, qs,
- &data, &ret_msg);
+ &data, msg->uid, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_JOIN:
assert(msg->hash.len == ipcp_dir_hash_len());
do_flow_join(msg->pid, msg->flow_id,
- msg->hash.data, &ret_msg);
+ msg->hash.data, msg->uid, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP:
assert(msg->pk.len > 0 ? msg->pk.data != NULL
@@ -870,7 +912,7 @@ static void * mainloop(void * o)
data.len = msg->pk.len;
data.data = msg->pk.data;
do_flow_alloc_resp(msg->response, msg->flow_id,
- &data, &ret_msg);
+ msg->uid, &data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC:
do_flow_dealloc(msg->flow_id, msg->timeo_sec, &ret_msg);
@@ -1035,6 +1077,8 @@ int ipcp_init(int argc,
ipcpd.alloc_id = -1;
+ memset(&np1, 0, sizeof(np1));
+
pthread_condattr_destroy(&cattr);
ipcp_set_state(IPCP_INIT);
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index e8c31a32..26a780a3 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process structure
*
diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt
index f661e9ae..91f300a3 100644
--- a/src/ipcpd/local/CMakeLists.txt
+++ b/src/ipcpd/local/CMakeLists.txt
@@ -1,36 +1,17 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+# Local IPCP build configuration
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_executable(${IPCP_LOCAL_TARGET}
+ main.c
+ ${IPCP_SOURCES}
+)
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
+target_include_directories(${IPCP_LOCAL_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS})
+target_link_libraries(${IPCP_LOCAL_TARGET} PRIVATE ouroboros-dev)
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
+ouroboros_target_debug_definitions(${IPCP_LOCAL_TARGET})
-set(IPCP_LOCAL_TARGET ipcpd-local CACHE INTERNAL "")
-set(IPCP_LOCAL_MPL 100 CACHE STRING
- "Default maximum packet lifetime for the Ethernet IPCPs, in ms")
+if(IPCP_LOCAL_POLLING)
+ target_compile_definitions(${IPCP_LOCAL_TARGET} PRIVATE CONFIG_IPCP_LOCAL_POLLING)
+endif()
-set(LOCAL_SOURCES
- # Add source files here
- ${CMAKE_CURRENT_SOURCE_DIR}/main.c)
-
-add_executable(ipcpd-local ${LOCAL_SOURCES} ${IPCP_SOURCES})
-target_link_libraries(ipcpd-local LINK_PUBLIC ouroboros-common ouroboros-dev)
-
-include(AddCompileFlags)
-if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-local -DCONFIG_OUROBOROS_DEBUG)
-endif ()
-
-install(TARGETS ipcpd-local RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
-
-# Enable once ipcp-local has tests
-# if(BUILD_TESTS)
-# add_subdirectory(tests)
-# endif ()
+install(TARGETS ${IPCP_LOCAL_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index ffa6dc5a..377a7df3 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Local IPC process
*
@@ -40,6 +40,7 @@
#include <ouroboros/local-dev.h>
#include "ipcp.h"
+#include "np1.h"
#include "shim-data.h"
#include <string.h>
@@ -103,34 +104,41 @@ static void local_data_fini(void){
static void * local_ipcp_packet_loop(void * o)
{
+ int src_fd;
+ int dst_fd;
+ struct timespec * timeout;
+#ifdef CONFIG_IPCP_LOCAL_POLLING
+ struct timespec ts_poll = {0, 0};
+#endif
(void) o;
ipcp_lock_to_core();
- while (true) {
- int fd;
- ssize_t idx;
+#ifdef CONFIG_IPCP_LOCAL_POLLING
+ timeout = &ts_poll; /* Spin poll with zero timeout */
+#else
+ timeout = NULL; /* Block until event */
+#endif
- fevent(local_data.flows, local_data.fq, NULL);
+ while (true) {
+ fevent(local_data.flows, local_data.fq, timeout);
- while ((fd = fqueue_next(local_data.fq)) >= 0) {
+ while ((src_fd = fqueue_next(local_data.fq)) >= 0) {
if (fqueue_type(local_data.fq) != FLOW_PKT)
continue;
- idx = local_flow_read(fd);
- if (idx < 0)
- continue;
-
- assert(idx < (SHM_BUFFER_SIZE));
-
pthread_rwlock_rdlock(&local_data.lock);
- fd = local_data.in_out[fd];
+ dst_fd = local_data.in_out[src_fd];
pthread_rwlock_unlock(&local_data.lock);
- if (fd != -1)
- local_flow_write(fd, idx);
+ if (dst_fd == -1)
+ continue;
+
+ local_flow_transfer(src_fd, dst_fd,
+ NP1_GET_POOL(src_fd),
+ NP1_GET_POOL(dst_fd));
}
}
diff --git a/src/ipcpd/np1.h b/src/ipcpd/np1.h
new file mode 100644
index 00000000..b7792cb9
--- /dev/null
+++ b/src/ipcpd/np1.h
@@ -0,0 +1,41 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2026
+ *
+ * N+1 flow pool tracking for IPCPs
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#ifndef OUROBOROS_IPCPD_NP1_H
+#define OUROBOROS_IPCPD_NP1_H
+
+#include "config.h"
+
+#include <ouroboros/ssm_pool.h>
+
+#define NP1_LOAD(ptr) (__atomic_load_n((ptr), __ATOMIC_ACQUIRE))
+#define NP1_STORE(ptr, v) (__atomic_store_n((ptr), (v), __ATOMIC_RELEASE))
+#define NP1_GET_POOL(fd) (NP1_LOAD(&np1.pool[(fd)]))
+#define NP1_SET_POOL(fd, p) (NP1_STORE(&np1.pool[(fd)], (p)))
+
+struct np1_state {
+ struct ssm_pool * pool[SYS_MAX_FLOWS];
+};
+
+extern struct np1_state np1;
+
+#endif /* OUROBOROS_IPCPD_NP1_H */
diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c
index 8801213a..90a676da 100644
--- a/src/ipcpd/shim-data.c
+++ b/src/ipcpd/shim-data.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process utilities
*
diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h
index ea4ce413..fbadb4d4 100644
--- a/src/ipcpd/shim-data.h
+++ b/src/ipcpd/shim-data.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Utitilies for building IPC processes
*
diff --git a/src/ipcpd/udp/CMakeLists.txt b/src/ipcpd/udp/CMakeLists.txt
index 27e32094..a98f0919 100644
--- a/src/ipcpd/udp/CMakeLists.txt
+++ b/src/ipcpd/udp/CMakeLists.txt
@@ -1,81 +1,14 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+# UDP IPCPs build configuration (UDP4 and UDP6)
+# DDNS detection is in cmake/dependencies/udp/ddns.cmake
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_executable(${IPCP_UDP4_TARGET} udp4.c ${IPCP_SOURCES})
+add_executable(${IPCP_UDP6_TARGET} udp6.c ${IPCP_SOURCES})
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-set(IPCP_UDP4_TARGET ipcpd-udp4 CACHE INTERNAL "")
-set(IPCP_UDP6_TARGET ipcpd-udp6 CACHE INTERNAL "")
-
-set(UDP4_SOURCES
- # Add source files here
- udp4.c
-)
-
-set(UDP6_SOURCES
- # Add source files here
- udp6.c
-)
-
-add_executable(ipcpd-udp4 ${UDP4_SOURCES} ${IPCP_SOURCES})
-target_link_libraries(ipcpd-udp4 LINK_PUBLIC ouroboros-dev)
-
-add_executable(ipcpd-udp6 ${UDP6_SOURCES} ${IPCP_SOURCES})
-target_link_libraries(ipcpd-udp6 LINK_PUBLIC ouroboros-dev)
-
-
-# Find the nsupdate executable
-find_program(NSUPDATE_EXECUTABLE
- NAMES nsupdate
- DOC "The nsupdate tool that enables DDNS")
-
-# Find the nslookup executable
-find_program(NSLOOKUP_EXECUTABLE
- NAMES nslookup
- DOC "The nslookup tool that resolves DNS names")
-
-mark_as_advanced(NSLOOKUP_EXECUTABLE NSUPDATE_EXECUTABLE)
-
-if (NSLOOKUP_EXECUTABLE AND NSUPDATE_EXECUTABLE)
- set(DISABLE_DDNS FALSE CACHE BOOL "Disable DDNS support")
- if (NOT DISABLE_DNS)
- message(STATUS "DDNS support enabled")
- set(HAVE_DDNS TRUE CACHE INTERNAL "")
- else ()
- message(STATUS "DDNS support disabled by user")
- unset(HAVE_DDNS CACHE)
- endif ()
-else ()
- if (NSLOOKUP_EXECUTABLE)
- message(STATUS "Install nsupdate to enable DDNS support")
- elseif (NSUPDATE_EXECUTABLE)
- message(STATUS "Install nslookup to enable DDNS support")
- else ()
- message(STATUS "Install nslookup and nsupdate to enable DDNS support")
- endif ()
-endif ()
-
-set(IPCP_UDP_RD_THR 3 CACHE STRING
- "Number of reader threads in UDP IPCPs")
-set(IPCP_UDP_WR_THR 3 CACHE STRING
- "Number of writer threads in UDP IPCPs")
-set(IPCP_UDP_MPL 5000 CACHE STRING
- "Default maximum packet lifetime for the UDP IPCPs, in ms")
-
-include(AddCompileFlags)
-if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-udp4 -DCONFIG_OUROBOROS_DEBUG)
- add_compile_flags(ipcpd-udp6 -DCONFIG_OUROBOROS_DEBUG)
-endif ()
-
-install(TARGETS ipcpd-udp4 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
-install(TARGETS ipcpd-udp6 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+foreach(target ${IPCP_UDP4_TARGET} ${IPCP_UDP6_TARGET})
+ target_include_directories(${target} PRIVATE ${IPCP_INCLUDE_DIRS})
+ target_link_libraries(${target} PRIVATE ouroboros-dev)
+ ouroboros_target_debug_definitions(${target})
+endforeach()
+install(TARGETS ${IPCP_UDP4_TARGET} ${IPCP_UDP6_TARGET}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
diff --git a/src/ipcpd/udp/udp.c b/src/ipcpd/udp/udp.c
index be8069a4..452bbc1a 100644
--- a/src/ipcpd/udp/udp.c
+++ b/src/ipcpd/udp/udp.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process over UDP
*
@@ -34,6 +34,7 @@
#include <ouroboros/pthread.h>
#include "ipcp.h"
+#include "np1.h"
#include "shim-data.h"
#include <string.h>
@@ -208,6 +209,8 @@ static int udp_ipcp_port_alloc(const struct __SOCKADDR * r_saddr,
if (buf == NULL)
return -1;
+ memset(buf, 0, len + data->len);
+
msg = (struct mgmt_msg *) buf;
msg->eid = hton32(MGMT_EID);
msg->code = FLOW_REQ;
@@ -251,6 +254,8 @@ static int udp_ipcp_port_alloc_resp(const struct __SOCKADDR * r_saddr,
if (msg == NULL)
return -1;
+ memset(msg, 0, sizeof(*msg) + data->len);
+
msg->eid = hton32(MGMT_EID);
msg->code = FLOW_REPLY;
msg->s_eid = hton32(s_eid);
@@ -439,7 +444,7 @@ static void * udp_ipcp_packet_reader(void * o)
struct mgmt_frame * frame;
struct __SOCKADDR r_saddr;
socklen_t len;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
uint8_t * head;
len = sizeof(r_saddr);
@@ -483,13 +488,13 @@ static void * udp_ipcp_packet_reader(void * o)
n-= sizeof(eid);
- if (ipcp_sdb_reserve(&sdb, n))
+ if (ipcp_spb_reserve(&spb, n))
continue;
- head = shm_du_buff_head(sdb);
+ head = ssm_pk_buff_head(spb);
memcpy(head, data, n);
- if (np1_flow_write(eid, sdb) < 0)
- ipcp_sdb_release(sdb);
+ if (np1_flow_write(eid, spb, NP1_GET_POOL(eid)) < 0)
+ ipcp_spb_release(spb);
}
return (void *) 0;
@@ -500,9 +505,9 @@ static void cleanup_fqueue(void * fq)
fqueue_destroy((fqueue_t *) fq);
}
-static void cleanup_sdb(void * sdb)
+static void cleanup_spb(void * spb)
{
- ipcp_sdb_release((struct shm_du_buff *) sdb);
+ ipcp_spb_release((struct ssm_pk_buff *) spb);
}
static void * udp_ipcp_packet_writer(void * o)
@@ -525,29 +530,29 @@ static void * udp_ipcp_packet_writer(void * o)
int fd;
fevent(udp_data.np1_flows, fq, NULL);
while ((fd = fqueue_next(fq)) >= 0) {
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
uint8_t * buf;
uint16_t len;
if (fqueue_type(fq) != FLOW_PKT)
continue;
- if (np1_flow_read(fd, &sdb)) {
+ if (np1_flow_read(fd, &spb, NP1_GET_POOL(fd))) {
log_dbg("Bad read from fd %d.", fd);
continue;
}
- len = shm_du_buff_len(sdb);
+ len = ssm_pk_buff_len(spb);
if (len > IPCP_UDP_MAX_PACKET_SIZE) {
log_dbg("Packet length exceeds MTU.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
continue;
}
- buf = shm_du_buff_head_alloc(sdb, OUR_HEADER_LEN);
+ buf = ssm_pk_buff_head_alloc(spb, OUR_HEADER_LEN);
if (buf == NULL) {
log_dbg("Failed to allocate header.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
continue;
}
@@ -560,7 +565,7 @@ static void * udp_ipcp_packet_writer(void * o)
memcpy(buf, &eid, sizeof(eid));
- pthread_cleanup_push(cleanup_sdb, sdb);
+ pthread_cleanup_push(cleanup_spb, spb);
if (sendto(udp_data.s_fd, buf, len + OUR_HEADER_LEN,
SENDTO_FLAGS,
diff --git a/src/ipcpd/udp/udp4.c b/src/ipcpd/udp/udp4.c
index 07d5f818..ff57bc09 100644
--- a/src/ipcpd/udp/udp4.c
+++ b/src/ipcpd/udp/udp4.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process over UDP/IPv4
*
diff --git a/src/ipcpd/udp/udp6.c b/src/ipcpd/udp/udp6.c
index b7924a3f..2ceb95f0 100644
--- a/src/ipcpd/udp/udp6.c
+++ b/src/ipcpd/udp/udp6.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* IPC process over UDP/IPv6
*
diff --git a/src/ipcpd/unicast/CMakeLists.txt b/src/ipcpd/unicast/CMakeLists.txt
index a9155353..d3388112 100644
--- a/src/ipcpd/unicast/CMakeLists.txt
+++ b/src/ipcpd/unicast/CMakeLists.txt
@@ -1,42 +1,9 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+# Unicast IPCP build configuration
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+protobuf_generate_c(DHT_PROTO_SRCS DHT_PROTO_HDRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/dir/dht.proto")
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
-set(IPCP_UNICAST_TARGET ipcpd-unicast CACHE INTERNAL "")
-set(IPCP_UNICAST_MPL 10000 CACHE STRING
- "Default maximum packet lifetime for the unicast IPCP, in ms")
-set(DEBUG_PROTO_DHT FALSE CACHE BOOL
- "Add DHT protocol message output to debug logging")
-set(DEBUG_PROTO_LS FALSE CACHE BOOL
- "Add link state protocol message output to debug logging")
-
-protobuf_generate_c(DHT_PROTO_SRCS DHT_PROTO_HDRS dir/dht.proto)
-
-math(EXPR PFT_EXPR "1 << 12")
-set(PFT_SIZE ${PFT_EXPR} CACHE STRING
- "Size of the PDU forwarding table")
-if (HAVE_FUSE)
- set(IPCP_FLOW_STATS TRUE CACHE BOOL
- "Enable flow statistics tracking in IPCP")
- if (IPCP_FLOW_STATS)
- message(STATUS "IPCP flow statistics enabled")
- else ()
- message(STATUS "IPCP flow statistics disabled")
- endif ()
-endif ()
-
-set(IPCP_UNICAST_SOURCE_FILES
- # Add source files here
+set(UNICAST_SOURCES
addr-auth.c
ca.c
connmgr.c
@@ -47,7 +14,6 @@ set(IPCP_UNICAST_SOURCE_FILES
pff.c
routing.c
psched.c
- # Add policies last
addr-auth/flat.c
ca/mb-ecn.c
ca/nop.c
@@ -58,21 +24,26 @@ set(IPCP_UNICAST_SOURCE_FILES
pff/pft.c
routing/link-state.c
routing/graph.c
- )
+)
+
+add_executable(${IPCP_UNICAST_TARGET}
+ ${UNICAST_SOURCES}
+ ${IPCP_SOURCES}
+ ${COMMON_SOURCES}
+ ${DHT_PROTO_SRCS}
+)
-add_executable(ipcpd-unicast ${IPCP_UNICAST_SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES}
- ${DHT_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS})
-target_link_libraries(ipcpd-unicast LINK_PUBLIC ouroboros-dev)
+target_include_directories(${IPCP_UNICAST_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS})
+target_include_directories(${IPCP_UNICAST_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(${IPCP_UNICAST_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(${IPCP_UNICAST_TARGET} PRIVATE ouroboros-dev)
-include(AddCompileFlags)
-if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-unicast -DCONFIG_OUROBOROS_DEBUG)
-endif ()
+ouroboros_target_debug_definitions(${IPCP_UNICAST_TARGET})
-install(TARGETS ipcpd-unicast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+install(TARGETS ${IPCP_UNICAST_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
if(BUILD_TESTS)
+ add_subdirectory(dir/tests)
add_subdirectory(pff/tests)
add_subdirectory(routing/tests)
- add_subdirectory(dir/tests)
-endif ()
+endif()
diff --git a/src/ipcpd/unicast/addr-auth.c b/src/ipcpd/unicast/addr-auth.c
index 908a4aa1..27671d09 100644
--- a/src/ipcpd/unicast/addr-auth.c
+++ b/src/ipcpd/unicast/addr-auth.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Address authority
*
diff --git a/src/ipcpd/unicast/addr-auth.h b/src/ipcpd/unicast/addr-auth.h
index 0d2cd4c0..65567dc3 100644
--- a/src/ipcpd/unicast/addr-auth.h
+++ b/src/ipcpd/unicast/addr-auth.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Address authority
*
diff --git a/src/ipcpd/unicast/addr-auth/flat.c b/src/ipcpd/unicast/addr-auth/flat.c
index 34ca1cef..cf832279 100644
--- a/src/ipcpd/unicast/addr-auth/flat.c
+++ b/src/ipcpd/unicast/addr-auth/flat.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Policy for flat addresses in a distributed way
*
diff --git a/src/ipcpd/unicast/addr-auth/flat.h b/src/ipcpd/unicast/addr-auth/flat.h
index d4b672c7..b5c7e525 100644
--- a/src/ipcpd/unicast/addr-auth/flat.h
+++ b/src/ipcpd/unicast/addr-auth/flat.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Policy for flat addresses in a distributed way
*
diff --git a/src/ipcpd/unicast/addr-auth/ops.h b/src/ipcpd/unicast/addr-auth/ops.h
index 06b24cec..f5c4c611 100644
--- a/src/ipcpd/unicast/addr-auth/ops.h
+++ b/src/ipcpd/unicast/addr-auth/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Address authority policy ops
*
diff --git a/src/ipcpd/unicast/addr-auth/pol.h b/src/ipcpd/unicast/addr-auth/pol.h
index 844308c6..a33f1dd6 100644
--- a/src/ipcpd/unicast/addr-auth/pol.h
+++ b/src/ipcpd/unicast/addr-auth/pol.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Address Authority policies
*
diff --git a/src/ipcpd/unicast/ca.c b/src/ipcpd/unicast/ca.c
index 1fcc9bb2..a1751672 100644
--- a/src/ipcpd/unicast/ca.c
+++ b/src/ipcpd/unicast/ca.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Congestion Avoidance
*
diff --git a/src/ipcpd/unicast/ca.h b/src/ipcpd/unicast/ca.h
index ea803e17..47ea15a0 100644
--- a/src/ipcpd/unicast/ca.h
+++ b/src/ipcpd/unicast/ca.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Congestion avoidance
*
diff --git a/src/ipcpd/unicast/ca/mb-ecn.c b/src/ipcpd/unicast/ca/mb-ecn.c
index d9a204b0..b310c4fc 100644
--- a/src/ipcpd/unicast/ca/mb-ecn.c
+++ b/src/ipcpd/unicast/ca/mb-ecn.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Multi-bit ECN Congestion Avoidance
*
diff --git a/src/ipcpd/unicast/ca/mb-ecn.h b/src/ipcpd/unicast/ca/mb-ecn.h
index 9a2c8b49..1be27764 100644
--- a/src/ipcpd/unicast/ca/mb-ecn.h
+++ b/src/ipcpd/unicast/ca/mb-ecn.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Multi-bit ECN Congestion Avoidance
*
diff --git a/src/ipcpd/unicast/ca/nop.c b/src/ipcpd/unicast/ca/nop.c
index 617fc15b..e5cacf66 100644
--- a/src/ipcpd/unicast/ca/nop.c
+++ b/src/ipcpd/unicast/ca/nop.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Dummy Congestion Avoidance
*
diff --git a/src/ipcpd/unicast/ca/nop.h b/src/ipcpd/unicast/ca/nop.h
index 248b198d..8b892e61 100644
--- a/src/ipcpd/unicast/ca/nop.h
+++ b/src/ipcpd/unicast/ca/nop.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Dummy Congestion Avoidance
*
diff --git a/src/ipcpd/unicast/ca/ops.h b/src/ipcpd/unicast/ca/ops.h
index 3a7b7248..6d2ddf1d 100644
--- a/src/ipcpd/unicast/ca/ops.h
+++ b/src/ipcpd/unicast/ca/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Congestion avoidance policy ops
*
diff --git a/src/ipcpd/unicast/ca/pol.h b/src/ipcpd/unicast/ca/pol.h
index db0a1a11..bfb9cc2d 100644
--- a/src/ipcpd/unicast/ca/pol.h
+++ b/src/ipcpd/unicast/ca/pol.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Congestion avoidance policies
*
diff --git a/src/ipcpd/unicast/connmgr.c b/src/ipcpd/unicast/connmgr.c
index 07568fb5..f60f6fca 100644
--- a/src/ipcpd/unicast/connmgr.c
+++ b/src/ipcpd/unicast/connmgr.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Handles connections between components
*
diff --git a/src/ipcpd/unicast/dir.c b/src/ipcpd/unicast/dir.c
index 2b305626..a31a562f 100644
--- a/src/ipcpd/unicast/dir.c
+++ b/src/ipcpd/unicast/dir.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Directory Management
*
diff --git a/src/ipcpd/unicast/dir.h b/src/ipcpd/unicast/dir.h
index dbfde19f..2be7b10f 100644
--- a/src/ipcpd/unicast/dir.h
+++ b/src/ipcpd/unicast/dir.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Directory
*
diff --git a/src/ipcpd/unicast/dir/dht.c b/src/ipcpd/unicast/dir/dht.c
index 6b06def9..8eeea800 100644
--- a/src/ipcpd/unicast/dir/dht.c
+++ b/src/ipcpd/unicast/dir/dht.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Distributed Hash Table based on Kademlia
*
@@ -148,15 +148,8 @@ struct dht_entry {
uint8_t * key;
- struct {
- struct list_head list;
- size_t len;
- } vals; /* We don't own these, only replicate */
-
- struct {
- struct list_head list;
- size_t len;
- } lvals; /* We own these, must be republished */
+ struct llist vals; /* We don't own these, only replicate */
+ struct llist lvals; /* We own these, must be republished */
};
struct contact {
@@ -183,38 +176,24 @@ struct peer_entry {
struct dht_req {
struct list_head next;
- uint8_t * key;
- time_t t_exp;
+ uint8_t * key;
+ time_t t_exp;
- struct {
- struct list_head list;
- size_t len;
- } peers;
-
- struct {
- struct list_head list;
- size_t len;
- } cache;
+ struct llist peers;
+ struct llist cache;
};
struct bucket {
- struct {
- struct list_head list;
- size_t len;
- } contacts;
+ struct llist contacts;
+ struct llist alts;
- struct {
- struct list_head list;
- size_t len;
- } alts;
+ time_t t_refr;
- time_t t_refr;
+ size_t depth;
+ uint8_t mask;
- size_t depth;
- uint8_t mask;
-
- struct bucket * parent;
- struct bucket * children[1L << DHT_BETA];
+ struct bucket * parent;
+ struct bucket * children[1L << DHT_BETA];
};
struct cmd {
@@ -236,8 +215,8 @@ struct {
struct { /* Kademlia parameters */
uint32_t alpha; /* Number of concurrent requests */
size_t k; /* Number of replicas to store */
- time_t t_expire; /* Expiry time for values (s) */
- time_t t_refresh; /* Refresh time for contacts (s) */
+ time_t t_exp; /* Expiry time for values (s) */
+ time_t t_refr; /* Refresh time for contacts (s) */
time_t t_repl; /* Replication time for values (s) */
};
@@ -261,8 +240,7 @@ struct {
} contacts;
struct {
- struct list_head list;
- size_t len;
+ struct llist ll;
size_t vals;
size_t lvals;
} kv;
@@ -271,10 +249,9 @@ struct {
} db;
struct {
- struct list_head list;
- size_t len;
- pthread_cond_t cond;
- pthread_mutex_t mtx;
+ struct llist ll;
+ pthread_cond_t cond;
+ pthread_mutex_t mtx;
} reqs;
struct {
@@ -321,7 +298,7 @@ static int dht_rib_statfile(char * buf,
pthread_rwlock_rdlock(&dht.db.lock);
- keys = dht.db.kv.len;
+ keys = dht.db.kv.ll.len;
lvals = dht.db.kv.lvals;
vals = dht.db.kv.vals;
@@ -335,7 +312,7 @@ static int dht_rib_statfile(char * buf,
tmstr,
ADDR_VAL32(&dht.addr),
dht.alpha, dht.k,
- dht.t_expire, dht.t_refresh, dht.t_repl,
+ dht.t_exp, dht.t_refr, dht.t_repl,
keys, vals, lvals);
return strlen(buf);
@@ -350,14 +327,14 @@ static size_t dht_db_file_len(void)
pthread_rwlock_rdlock(&dht.db.lock);
- if (dht.db.kv.len == 0) {
+ if (llist_is_empty(&dht.db.kv.ll)) {
pthread_rwlock_unlock(&dht.db.lock);
sz += 14; /* No entries */
return sz;
}
sz += 39 * 3 + 1; /* tally + extra newline */
- sz += dht.db.kv.len * (25 + 19 + 23 + 1);
+ sz += dht.db.kv.ll.len * (25 + 19 + 23 + 1);
vals = dht.db.kv.vals + dht.db.kv.lvals;
@@ -382,7 +359,7 @@ static int dht_rib_dbfile(char * buf,
pthread_rwlock_rdlock(&dht.db.lock);
- if (dht.db.kv.len == 0) {
+ if (llist_is_empty(&dht.db.kv.ll)) {
i += snprintf(buf, len, " No entries.\n");
pthread_rwlock_unlock(&dht.db.lock);
return i;
@@ -393,9 +370,9 @@ static int dht_rib_dbfile(char * buf,
"Number of keys: %10zu\n"
"Number of local values: %10zu\n"
"Number of non-local values: %10zu\n\n",
- dht.db.kv.len, dht.db.kv.vals, dht.db.kv.lvals);
+ dht.db.kv.ll.len, dht.db.kv.vals, dht.db.kv.lvals);
- list_for_each(p, &dht.db.kv.list) {
+ llist_for_each(p, &dht.db.kv.ll) {
struct dht_entry * e = list_entry(p, struct dht_entry, next);
struct list_head * h;
@@ -403,7 +380,7 @@ static int dht_rib_dbfile(char * buf,
KEY_VAL(e->key));
i += snprintf(buf + i, len - i, " Local entries:\n");
- list_for_each(h, &e->vals.list) {
+ llist_for_each(h, &e->vals) {
struct val_entry * v;
v = list_entry(h, struct val_entry, next);
@@ -416,7 +393,7 @@ static int dht_rib_dbfile(char * buf,
i += snprintf(buf + i, len - i,
" " VAL_FMT
- ", t_replicated=%.*s, t_expire=%.*s\n",
+ ", t_replicated=%.*s, t_exp=%.*s\n",
VAL_VAL(v->val),
RIB_TM_STRLEN, tmstr,
RIB_TM_STRLEN, exstr);
@@ -426,7 +403,7 @@ static int dht_rib_dbfile(char * buf,
i += snprintf(buf + i, len - i, " Non-local entries:\n");
- list_for_each(h, &e->lvals.list) {
+ llist_for_each(h, &e->lvals) {
struct val_entry * v;
v= list_entry(h, struct val_entry, next);
@@ -439,7 +416,7 @@ static int dht_rib_dbfile(char * buf,
i += snprintf(buf + i, len - i,
" " VAL_FMT
- ", t_replicated=%.*s, t_expire=%.*s\n",
+ ", t_replicated=%.*s, t_exp=%.*s\n",
VAL_VAL(v->val),
RIB_TM_STRLEN, tmstr,
RIB_TM_STRLEN, exstr);
@@ -694,11 +671,8 @@ static struct dht_entry * dht_entry_create(const uint8_t * key)
goto fail_entry;
list_head_init(&e->next);
- list_head_init(&e->vals.list);
- list_head_init(&e->lvals.list);
-
- e->vals.len = 0;
- e->lvals.len = 0;
+ llist_init(&e->vals);
+ llist_init(&e->lvals);
e->key = dht_dup_key(key);
if (e->key == NULL)
@@ -718,25 +692,23 @@ static void dht_entry_destroy(struct dht_entry * e)
assert(e != NULL);
- list_for_each_safe(p, h, &e->vals.list) {
+ llist_for_each_safe(p, h, &e->vals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
- list_del(&v->next);
+ llist_del(&v->next, &e->vals);
val_entry_destroy(v);
- --e->vals.len;
--dht.db.kv.vals;
}
- list_for_each_safe(p, h, &e->lvals.list) {
+ llist_for_each_safe(p, h, &e->lvals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
- list_del(&v->next);
+ llist_del(&v->next, &e->lvals);
val_entry_destroy(v);
- --e->lvals.len;
--dht.db.kv.lvals;
}
free(e->key);
- assert(e->vals.len == 0 && e->lvals.len == 0);
+ assert(llist_is_empty(&e->vals) && llist_is_empty(&e->lvals));
free(e);
}
@@ -750,7 +722,7 @@ static struct val_entry * dht_entry_get_lval(const struct dht_entry * e,
assert(val.data != NULL);
assert(val.len > 0);
- list_for_each(p, &e->lvals.list) {
+ llist_for_each(p, &e->lvals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
if (bufcmp(&v->val, &val) == 0)
return v;
@@ -768,7 +740,7 @@ static struct val_entry * dht_entry_get_val(const struct dht_entry * e,
assert(val.data != NULL);
assert(val.len > 0);
- list_for_each(p, &e->vals.list) {
+ llist_for_each(p, &e->vals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
if (bufcmp(&v->val, &val) == 0)
return v;
@@ -805,8 +777,7 @@ static int dht_entry_update_val(struct dht_entry * e,
if (v == NULL)
return -ENOMEM;
- list_add_tail(&v->next, &e->vals.list);
- ++e->vals.len;
+ llist_add_tail(&v->next, &e->vals);
++dht.db.kv.vals;
return 0;
@@ -833,12 +804,11 @@ static int dht_entry_update_lval(struct dht_entry * e,
v = dht_entry_get_lval(e, val);
if (v == NULL) {
log_dbg(KV_FMT " Adding lval.", KV_VAL(e->key, val));
- v = val_entry_create(val, now.tv_sec + dht.t_expire);
+ v = val_entry_create(val, now.tv_sec + dht.t_exp);
if (v == NULL)
return -ENOMEM;
- list_add_tail(&v->next, &e->lvals.list);
- ++e->lvals.len;
+ llist_add_tail(&v->next, &e->lvals);
++dht.db.kv.lvals;
return 0;
@@ -862,9 +832,8 @@ static int dht_entry_remove_lval(struct dht_entry * e,
log_dbg(KV_FMT " Removing lval.", KV_VAL(e->key, val));
- list_del(&v->next);
+ llist_del(&v->next, &e->lvals);
val_entry_destroy(v);
- --e->lvals.len;
--dht.db.kv.lvals;
return 0;
@@ -881,15 +850,14 @@ static void dht_entry_remove_expired_vals(struct dht_entry * e)
clock_gettime(CLOCK_REALTIME_COARSE, &now);
- list_for_each_safe(p, h, &e->vals.list) {
+ llist_for_each_safe(p, h, &e->vals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
if (!IS_EXPIRED(v, &now))
continue;
log_dbg(KV_FMT " Value expired." , KV_VAL(e->key, v->val));
- list_del(&v->next);
+ llist_del(&v->next, &e->vals);
val_entry_destroy(v);
- --e->vals.len;
--dht.db.kv.vals;
}
}
@@ -900,7 +868,7 @@ static struct dht_entry * __dht_kv_find_entry(const uint8_t * key)
assert(key != NULL);
- list_for_each(p, &dht.db.kv.list) {
+ llist_for_each(p, &dht.db.kv.ll) {
struct dht_entry * e = list_entry(p, struct dht_entry, next);
if (!memcmp(key, e->key, dht.id.len))
return e;
@@ -919,16 +887,15 @@ static void dht_kv_remove_expired_entries(void)
pthread_rwlock_wrlock(&dht.db.lock);
- list_for_each_safe(p, h, &dht.db.kv.list) {
+ llist_for_each_safe(p, h, &dht.db.kv.ll) {
struct dht_entry * e = list_entry(p, struct dht_entry, next);
dht_entry_remove_expired_vals(e);
if (e->lvals.len > 0 || e->vals.len > 0)
continue;
log_dbg(KEY_FMT " Entry removed. ", KEY_VAL(e->key));
- list_del(&e->next);
+ llist_del(&e->next, &dht.db.kv.ll);
dht_entry_destroy(e);
- --dht.db.kv.len;
}
pthread_rwlock_unlock(&dht.db.lock);
@@ -987,15 +954,13 @@ static struct dht_req * dht_req_create(const uint8_t * key)
req->t_exp = now.tv_sec + DHT_T_RESP;
- list_head_init(&req->peers.list);
- req->peers.len = 0;
+ llist_init(&req->peers);
req->key = dht_dup_key(key);
if (req->key == NULL)
goto fail_dup_key;
- list_head_init(&req->cache.list);
- req->cache.len = 0;
+ llist_init(&req->cache);
return req;
@@ -1013,34 +978,32 @@ static void dht_req_destroy(struct dht_req * req)
assert(req);
assert(req->key);
- list_for_each_safe(p, h, &req->peers.list) {
+ llist_for_each_safe(p, h, &req->peers) {
struct peer_entry * e = list_entry(p, struct peer_entry, next);
- list_del(&e->next);
+ llist_del(&e->next, &req->peers);
free(e->id);
free(e);
- --req->peers.len;
}
- list_for_each_safe(p, h, &req->cache.list) {
+ llist_for_each_safe(p, h, &req->cache) {
struct val_entry * e = list_entry(p, struct val_entry, next);
- list_del(&e->next);
+ llist_del(&e->next, &req->cache);
val_entry_destroy(e);
- --req->cache.len;
}
free(req->key);
- assert(req->peers.len == 0);
+ assert(llist_is_empty(&req->peers));
free(req);
}
-static struct peer_entry * dht_req_get_peer(struct dht_req * req,
- struct peer_entry * e)
+static struct peer_entry * dht_req_get_peer(struct dht_req * req,
+ const struct peer_entry * e)
{
struct list_head * p;
- list_for_each(p, &req->peers.list) {
+ llist_for_each(p, &req->peers) {
struct peer_entry * x = list_entry(p, struct peer_entry, next);
if (x->addr == e->addr)
return x;
@@ -1050,8 +1013,8 @@ static struct peer_entry * dht_req_get_peer(struct dht_req * req,
}
#define IS_MAGIC(peer) ((peer)->cookie == dht.magic)
-void dht_req_add_peer(struct dht_req * req,
- struct peer_entry * e)
+static int dht_req_add_peer(struct dht_req * req,
+ const struct peer_entry * e)
{
struct peer_entry * x; /* existing */
struct list_head * p; /* iterator */
@@ -1063,16 +1026,17 @@ void dht_req_add_peer(struct dht_req * req,
/*
* Dedupe messages to the same peer, unless
- * 1) The previous request was FIND_NODE and now it's FIND_VALUE
- * 2) We urgently need contacts from emergency peer (magic cookie)
+ * 1) The previous was FIND_NODE and now it's FIND_VALUE
+ * 2) We urgently need contacts (magic cookie)
*/
x = dht_req_get_peer(req, e);
if (x != NULL && x->code >= e->code && !IS_MAGIC(e))
- goto skip;
+ return -1;
/* Find how this contact ranks in distance to the key */
- list_for_each(p, &req->peers.list) {
- struct peer_entry * y = list_entry(p, struct peer_entry, next);
+ llist_for_each(p, &req->peers) {
+ struct peer_entry * y;
+ y = list_entry(p, struct peer_entry, next);
if (IS_CLOSER(y->id, e->id)) {
pos++;
continue;
@@ -1080,36 +1044,32 @@ void dht_req_add_peer(struct dht_req * req,
break;
}
- /* Add a new peer to this request if we need to */
- if (pos < dht.alpha || !IS_MAGIC(e)) {
- x = malloc(sizeof(*x));
- if (x == NULL) {
- log_err("Failed to malloc peer entry.");
- goto skip;
- }
+ if (pos >= dht.alpha && IS_MAGIC(e))
+ return -1;
- x->cookie = e->cookie;
- x->addr = e->addr;
- x->code = e->code;
- x->t_sent = e->t_sent;
- x->id = dht_dup_key(e->id);
- if (x->id == NULL) {
- log_err("Failed to dup peer ID.");
- free(x);
- goto skip;
- }
+ x = malloc(sizeof(*x));
+ if (x == NULL) {
+ log_err("Failed to malloc peer entry.");
+ return -1;
+ }
- if (IS_MAGIC(e))
- list_add(&x->next, p);
- else
- list_add_tail(&x->next, p);
- ++req->peers.len;
- return;
+ x->cookie = e->cookie;
+ x->addr = e->addr;
+ x->code = e->code;
+ x->t_sent = e->t_sent;
+ x->id = dht_dup_key(e->id);
+ if (x->id == NULL) {
+ log_err("Failed to dup peer ID.");
+ free(x);
+ return -1;
}
- skip:
- list_del(&e->next);
- free(e->id);
- free(e);
+
+ if (IS_MAGIC(e))
+ llist_add_at(&x->next, p, &req->peers);
+ else
+ llist_add_tail_at(&x->next, p, &req->peers);
+
+ return 0;
}
static size_t dht_req_add_peers(struct dht_req * req,
@@ -1123,8 +1083,13 @@ static size_t dht_req_add_peers(struct dht_req * req,
assert(pl != NULL);
list_for_each_safe(p, h, pl) {
- struct peer_entry * e = list_entry(p, struct peer_entry, next);
- dht_req_add_peer(req, e);
+ struct peer_entry * e;
+ e = list_entry(p, struct peer_entry, next);
+ if (dht_req_add_peer(req, e) < 0) {
+ list_del(&e->next);
+ free(e->id);
+ free(e);
+ }
}
return n;
@@ -1137,7 +1102,7 @@ static bool dht_req_has_peer(struct dht_req * req,
assert(req != NULL);
- list_for_each(p, &req->peers.list) {
+ llist_for_each(p, &req->peers) {
struct peer_entry * e = list_entry(p, struct peer_entry, next);
if (e->cookie == cookie)
return true;
@@ -1209,7 +1174,7 @@ static struct dht_req * __dht_kv_req_get_req(const uint8_t * key)
{
struct list_head * p;
- list_for_each(p, &dht.reqs.list) {
+ llist_for_each(p, &dht.reqs.ll) {
struct dht_req * r = list_entry(p, struct dht_req, next);
if (memcmp(r->key, key, dht.id.len) == 0)
return r;
@@ -1228,7 +1193,7 @@ static struct dht_req * __dht_kv_get_req_cache(const uint8_t * key)
if (req == NULL)
return NULL;
- if (req->cache.len == 0)
+ if (llist_is_empty(&req->cache))
return NULL;
return req;
@@ -1244,8 +1209,7 @@ static void __dht_kv_req_remove(const uint8_t * key)
if (req == NULL)
return;
- list_del(&req->next);
- --dht.reqs.len;
+ llist_del(&req->next, &dht.reqs.ll);
dht_req_destroy(req);
}
@@ -1301,9 +1265,9 @@ static int dht_kv_update_req(const uint8_t * key,
req = __dht_kv_req_get_req(key);
if (req == NULL) {
- if (dht.reqs.len == DHT_MAX_REQS) {
+ if (dht.reqs.ll.len == DHT_MAX_REQS) {
log_err(KEY_FMT " Max reqs reached (%zu).",
- KEY_VAL(key), dht.reqs.len);
+ KEY_VAL(key), dht.reqs.ll.len);
peer_list_destroy(pl);
goto fail_req;
}
@@ -1312,8 +1276,7 @@ static int dht_kv_update_req(const uint8_t * key,
log_err(KEY_FMT "Failed to create req.", KEY_VAL(key));
goto fail_req;
}
- list_add_tail(&req->next, &dht.reqs.list);
- ++dht.reqs.len;
+ llist_add_tail(&req->next, &dht.reqs.ll);
}
if (req->cache.len > 0) /* Already have values */
@@ -1322,9 +1285,9 @@ static int dht_kv_update_req(const uint8_t * key,
dht_req_add_peers(req, pl);
req->t_exp = now.tv_sec + DHT_T_RESP;
- if (dht.reqs.len > DHT_WARN_REQS) {
+ if (dht.reqs.ll.len > DHT_WARN_REQS) {
log_warn("Number of outstanding requests (%zu) exceeds %u.",
- dht.reqs.len, DHT_WARN_REQS);
+ dht.reqs.ll.len, DHT_WARN_REQS);
}
pthread_mutex_unlock(&dht.reqs.mtx);
@@ -1368,8 +1331,7 @@ static int dht_kv_respond_req(uint8_t * key,
continue;
}
- list_add_tail(&e->next, &req->cache.list);
- ++req->cache.len;
+ llist_add_tail(&e->next, &req->cache);
}
pthread_cond_broadcast(&dht.reqs.cond);
@@ -1434,7 +1396,7 @@ static ssize_t dht_kv_wait_req(const uint8_t * key,
memset(*vals, 0, max * sizeof(**vals));
- list_for_each(p, &req->cache.list) {
+ llist_for_each(p, &req->cache) {
struct val_entry * v;
if (i == max)
break; /* We have enough values */
@@ -1535,10 +1497,10 @@ static ssize_t dht_kv_contact_list(const uint8_t * key,
goto fail_bucket;
}
- b->t_refr = t.tv_sec + dht.t_refresh;
+ b->t_refr = t.tv_sec + dht.t_refr;
if (b->contacts.len == dht.k || b->parent == NULL) {
- list_for_each(p, &b->contacts.list) {
+ llist_for_each(p, &b->contacts) {
struct contact * c;
struct contact * d;
c = list_entry(p, struct contact, next);
@@ -1554,7 +1516,7 @@ static ssize_t dht_kv_contact_list(const uint8_t * key,
} else {
struct bucket * d = b->parent;
for (i = 0; i < (1L << DHT_BETA) && len < dht.k; ++i) {
- list_for_each(p, &d->children[i]->contacts.list) {
+ llist_for_each(p, &d->children[i]->contacts) {
struct contact * c;
struct contact * d;
c = list_entry(p, struct contact, next);
@@ -1661,11 +1623,11 @@ static void __dht_kv_bucket_refresh_list(struct bucket * b,
__dht_kv_bucket_refresh_list(b->children[i], t, r);
}
- if (b->contacts.len == 0)
+ if (llist_is_empty(&b->contacts))
return;
- c = list_first_entry(&b->contacts.list, struct contact, next);
- if (t > c->t_seen + dht.t_refresh) {
+ c = llist_first_entry(&b->contacts, struct contact, next);
+ if (t > c->t_seen + dht.t_refr) {
d = contact_create(c->id, c->addr);
if (d != NULL)
list_add(&d->next, r);
@@ -1682,14 +1644,12 @@ static struct bucket * bucket_create(void)
if (b == NULL)
return NULL;
- list_head_init(&b->contacts.list);
- b->contacts.len = 0;
+ llist_init(&b->contacts);
- list_head_init(&b->alts.list);
- b->alts.len = 0;
+ llist_init(&b->alts);
clock_gettime(CLOCK_REALTIME_COARSE, &t);
- b->t_refr = t.tv_sec + dht.t_refresh;
+ b->t_refr = t.tv_sec + dht.t_refr;
for (i = 0; i < (1L << DHT_BETA); ++i)
b->children[i] = NULL;
@@ -1713,18 +1673,16 @@ static void bucket_destroy(struct bucket * b)
if (b->children[i] != NULL)
bucket_destroy(b->children[i]);
- list_for_each_safe(p, h, &b->contacts.list) {
+ llist_for_each_safe(p, h, &b->contacts) {
struct contact * c = list_entry(p, struct contact, next);
- list_del(&c->next);
+ llist_del(&c->next, &b->contacts);
contact_destroy(c);
- --b->contacts.len;
}
- list_for_each_safe(p, h, &b->alts.list) {
+ llist_for_each_safe(p, h, &b->alts) {
struct contact * c = list_entry(p, struct contact, next);
- list_del(&c->next);
+ llist_del(&c->next, &b->alts);
contact_destroy(c);
- --b->alts.len;
}
free(b);
@@ -1759,13 +1717,11 @@ static int move_contacts(struct bucket * b,
assert(b != NULL);
assert(c != NULL);
- list_for_each_safe(p, h, &b->contacts.list) {
+ llist_for_each_safe(p, h, &b->contacts) {
d = list_entry(p, struct contact, next);
if (bucket_has_id(c, d->id)) {
- list_del(&d->next);
- --b->contacts.len;
- list_add_tail(&d->next, &c->contacts.list);
- ++c->contacts.len;
+ llist_del(&d->next, &b->contacts);
+ llist_add_tail(&d->next, &c->contacts);
}
}
@@ -1779,8 +1735,8 @@ static int split_bucket(struct bucket * b)
size_t b_len;
assert(b);
- assert(b->alts.len == 0);
- assert(b->contacts.len != 0);
+ assert(llist_is_empty(&b->alts));
+ assert(!llist_is_empty(&b->contacts));
assert(b->children[0] == NULL);
b_len = b->contacts.len;
@@ -1836,39 +1792,33 @@ static int dht_kv_update_contacts(const uint8_t * id,
goto fail_update;
}
- list_for_each_safe(p, h, &b->contacts.list) {
+ llist_for_each_safe(p, h, &b->contacts) {
struct contact * d = list_entry(p, struct contact, next);
if (d->addr == addr) {
- list_del(&d->next);
+ llist_del(&d->next, &b->contacts);
contact_destroy(d);
- --b->contacts.len;
}
}
if (b->contacts.len == dht.k) {
if (bucket_has_id(b, dht.id.data)) {
- list_add_tail(&c->next, &b->contacts.list);
- ++b->contacts.len;
+ llist_add_tail(&c->next, &b->contacts);
if (split_bucket(b)) {
- list_del(&c->next);
+ llist_del(&c->next, &b->contacts);
contact_destroy(c);
- --b->contacts.len;
}
} else if (b->alts.len == dht.k) {
struct contact * d;
- d = list_first_entry(&b->alts.list,
+ d = llist_first_entry(&b->alts,
struct contact, next);
- list_del(&d->next);
+ llist_del(&d->next, &b->alts);
contact_destroy(d);
- list_add_tail(&c->next, &b->alts.list);
- ++b->alts.len;
+ llist_add_tail(&c->next, &b->alts);
} else {
- list_add_tail(&c->next, &b->alts.list);
- ++b->alts.len;
+ llist_add_tail(&c->next, &b->alts);
}
} else {
- list_add_tail(&c->next, &b->contacts.list);
- ++b->contacts.len;
+ llist_add_tail(&c->next, &b->contacts);
}
pthread_rwlock_unlock(&dht.db.lock);
@@ -2116,7 +2066,7 @@ static ssize_t dht_kv_retrieve(const uint8_t * key,
i = 0;
- list_for_each(p, &e->vals.list) {
+ llist_for_each(p, &e->vals) {
struct val_entry * v;
if (i == n)
break; /* We have enough values */
@@ -2129,7 +2079,7 @@ static ssize_t dht_kv_retrieve(const uint8_t * key,
memcpy((*vals)[i++].data, v->val.data, v->val.len);
}
- list_for_each(p, &e->lvals.list) {
+ llist_for_each(p, &e->lvals) {
struct val_entry * v;
if (i == n)
break; /* We have enough values */
@@ -2266,7 +2216,7 @@ static int dht_send_msg(dht_msg_t * msg,
uint64_t addr)
{
size_t len;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
if (msg == NULL)
return 0;
@@ -2279,21 +2229,21 @@ static int dht_send_msg(dht_msg_t * msg,
goto fail_msg;
}
- if (ipcp_sdb_reserve(&sdb, len)) {
- log_warn("%s failed to get sdb.", DHT_CODE(msg));
+ if (ipcp_spb_reserve(&spb, len)) {
+ log_warn("%s failed to get spb.", DHT_CODE(msg));
goto fail_msg;
}
- dht_msg__pack(msg, shm_du_buff_head(sdb));
+ dht_msg__pack(msg, ssm_pk_buff_head(spb));
- if (dt_write_packet(addr, QOS_CUBE_BE, dht.eid, sdb) < 0) {
+ if (dt_write_packet(addr, QOS_CUBE_BE, dht.eid, spb) < 0) {
log_warn("%s write failed", DHT_CODE(msg));
goto fail_send;
}
return 0;
fail_send:
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
fail_msg:
return -1;
}
@@ -2584,15 +2534,14 @@ static void __add_dht_kv_entry(struct dht_entry * e)
assert(e != NULL);
- list_for_each(p, &dht.db.kv.list) {
+ llist_for_each(p, &dht.db.kv.ll) {
struct dht_entry * d = list_entry(p, struct dht_entry, next);
if (IS_CLOSER(d->key, e->key))
continue;
break;
}
- list_add_tail(&e->next, p);
- ++dht.db.kv.len;
+ llist_add_tail_at(&e->next, p, &dht.db.kv.ll);
}
/* incoming store message */
@@ -2629,9 +2578,8 @@ static int dht_kv_store(const uint8_t * key,
return 0;
fail_add:
if (new) {
- list_del(&e->next);
+ llist_del(&e->next, &dht.db.kv.ll);
dht_entry_destroy(e);
- --dht.db.kv.len;
}
fail:
pthread_rwlock_unlock(&dht.db.lock);
@@ -2669,14 +2617,13 @@ static int dht_kv_publish(const uint8_t * key,
pthread_rwlock_unlock(&dht.db.lock);
- dht_kv_store_remote(key, val, now.tv_sec + dht.t_expire);
+ dht_kv_store_remote(key, val, now.tv_sec + dht.t_exp);
return 0;
fail_add:
if (new) {
- list_del(&e->next);
+ llist_del(&e->next, &dht.db.kv.ll);
dht_entry_destroy(e);
- --dht.db.kv.len;
}
fail:
pthread_rwlock_unlock(&dht.db.lock);
@@ -2858,7 +2805,7 @@ static void do_dht_kv_store(const dht_store_msg_t * store)
key = store->key.data;
exp = store->exp;
- if (dht_kv_store(store->key.data, val, store->exp) < 0) {
+ if (dht_kv_store(key, val, store->exp) < 0) {
log_err(KV_FMT " Failed to store.", KV_VAL(key, val));
return;
}
@@ -3189,7 +3136,7 @@ static void * dht_handle_packet(void * o)
}
#ifndef __DHT_TEST__
static void dht_post_packet(void * comp,
- struct shm_du_buff * sdb)
+ struct ssm_pk_buff * spb)
{
struct cmd * cmd;
@@ -3201,17 +3148,17 @@ static void dht_post_packet(void * comp,
goto fail_cmd;
}
- cmd->cbuf.data = malloc(shm_du_buff_len(sdb));
+ cmd->cbuf.data = malloc(ssm_pk_buff_len(spb));
if (cmd->cbuf.data == NULL) {
log_err("Command buffer malloc failed.");
goto fail_buf;
}
- cmd->cbuf.len = shm_du_buff_len(sdb);
+ cmd->cbuf.len = ssm_pk_buff_len(spb);
- memcpy(cmd->cbuf.data, shm_du_buff_head(sdb), cmd->cbuf.len);
+ memcpy(cmd->cbuf.data, ssm_pk_buff_head(spb), cmd->cbuf.len);
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
pthread_mutex_lock(&dht.cmds.mtx);
@@ -3226,7 +3173,7 @@ static void dht_post_packet(void * comp,
fail_buf:
free(cmd);
fail_cmd:
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
return;
}
#endif
@@ -3449,15 +3396,14 @@ static void dht_kv_remove_expired_reqs(void)
pthread_mutex_lock(&dht.reqs.mtx);
- list_for_each_safe(p, h, &dht.reqs.list) {
+ llist_for_each_safe(p, h, &dht.reqs.ll) {
struct dht_req * e;
e = list_entry(p, struct dht_req, next);
if (IS_EXPIRED(e, &now)) {
log_dbg(KEY_FMT " Removing expired request.",
KEY_VAL(e->key));
- list_del(&e->next);
+ llist_del(&e->next, &dht.reqs.ll);
dht_req_destroy(e);
- --dht.reqs.len;
}
}
@@ -3489,7 +3435,7 @@ static void dht_entry_get_repl_lists(const struct dht_entry * e,
struct list_head * p;
struct val_entry * n;
- list_for_each(p, &e->vals.list) {
+ llist_for_each(p, &e->vals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
if (MUST_REPLICATE(v, now) && !IS_EXPIRED(v, now)) {
n = val_entry_create(v->val, v->t_exp);
@@ -3500,11 +3446,11 @@ static void dht_entry_get_repl_lists(const struct dht_entry * e,
}
}
- list_for_each(p, &e->lvals.list) {
+ llist_for_each(p, &e->lvals) {
struct val_entry * v = list_entry(p, struct val_entry, next);
if (MUST_REPLICATE(v, now) && MUST_REPUBLISH(v, now)) {
/* Add expire time here, to allow creating val_entry */
- n = val_entry_create(v->val, now->tv_sec + dht.t_expire);
+ n = val_entry_create(v->val, now->tv_sec + dht.t_exp);
if (n == NULL)
continue;
@@ -3533,10 +3479,10 @@ static int dht_kv_next_values(uint8_t * key,
pthread_rwlock_rdlock(&dht.db.lock);
- if (dht.db.kv.len == 0)
+ if (llist_is_empty(&dht.db.kv.ll))
goto no_entries;
- list_for_each_safe(p, h, &dht.db.kv.list) {
+ llist_for_each_safe(p, h, &dht.db.kv.ll) {
e = list_entry(p, struct dht_entry, next);
if (IS_CLOSER(e->key, key))
continue; /* Already processed */
@@ -3578,7 +3524,7 @@ static void dht_kv_republish_value(const uint8_t * key,
assert(MUST_REPLICATE(v, now));
if (MUST_REPUBLISH(v, now))
- assert(v->t_exp >= now->tv_sec + dht.t_expire);
+ assert(v->t_exp >= now->tv_sec + dht.t_exp);
if (dht_kv_store_remote(key, v->val, v->t_exp) == 0) {
log_dbg(KV_FMT " Republished.", KV_VAL(key, v->val));
@@ -3786,8 +3732,8 @@ static void * work(void * o)
nanosleep(&now, NULL);
}
- intv = gcd(dht.t_expire, (dht.t_expire - DHT_N_REPUB * dht.t_repl));
- intv = gcd(intv, gcd(dht.t_repl, dht.t_refresh)) / 2;
+ intv = gcd(dht.t_exp, (dht.t_exp - DHT_N_REPUB * dht.t_repl));
+ intv = gcd(intv, gcd(dht.t_repl, dht.t_refr)) / 2;
intv = MAX(1, intv / n);
log_dbg("DHT worker starting %ld seconds interval.", intv * n);
@@ -3868,13 +3814,13 @@ int dht_init(struct dir_dht_config * conf)
dht.id.len = DHT_TEST_KEY_LEN;
dht.addr = DHT_TEST_ADDR;
#endif
- dht.t0 = now.tv_sec;
- dht.alpha = conf->params.alpha;
- dht.k = conf->params.k;
- dht.t_expire = conf->params.t_expire;
- dht.t_refresh = conf->params.t_refresh;
- dht.t_repl = conf->params.t_replicate;
- dht.peer = conf->peer;
+ dht.t0 = now.tv_sec;
+ dht.alpha = conf->params.alpha;
+ dht.k = conf->params.k;
+ dht.t_exp = conf->params.t_expire;
+ dht.t_refr = conf->params.t_refresh;
+ dht.t_repl = conf->params.t_replicate;
+ dht.peer = conf->peer;
dht.magic = generate_cookie();
@@ -3899,8 +3845,7 @@ int dht_init(struct dir_dht_config * conf)
goto fail_cmds_cond;
}
- list_head_init(&dht.reqs.list);
- dht.reqs.len = 0;
+ llist_init(&dht.reqs.ll);
if (pthread_mutex_init(&dht.reqs.mtx, NULL)) {
log_err("Failed to initialize request mutex.");
@@ -3922,8 +3867,7 @@ int dht_init(struct dir_dht_config * conf)
goto fail_reqs_cond;
}
- list_head_init(&dht.db.kv.list);
- dht.db.kv.len = 0;
+ llist_init(&dht.db.kv.ll);
dht.db.kv.vals = 0;
dht.db.kv.lvals = 0;
@@ -3960,9 +3904,9 @@ int dht_init(struct dir_dht_config * conf)
log_dbg(" address: " ADDR_FMT32 ".", ADDR_VAL32(&dht.addr));
log_dbg(" peer: " ADDR_FMT32 ".", ADDR_VAL32(&dht.peer));
log_dbg(" magic cookie: " HASH_FMT64 ".", HASH_VAL64(&dht.magic));
- log_info(" parameters: alpha=%u, k=%zu, t_expire=%ld, "
- "t_refresh=%ld, t_replicate=%ld.",
- dht.alpha, dht.k, dht.t_expire, dht.t_refresh, dht.t_repl);
+ log_info(" parameters: alpha=%u, k=%zu, t_exp=%ld, "
+ "t_refr=%ld, t_replicate=%ld.",
+ dht.alpha, dht.k, dht.t_exp, dht.t_refr, dht.t_repl);
#endif
dht.state = DHT_INIT;
@@ -4015,11 +3959,10 @@ void dht_fini(void)
pthread_mutex_lock(&dht.reqs.mtx);
- list_for_each_safe(p, h, &dht.reqs.list) {
+ llist_for_each_safe(p, h, &dht.reqs.ll) {
struct dht_req * r = list_entry(p, struct dht_req, next);
- list_del(&r->next);
+ llist_del(&r->next, &dht.reqs.ll);
dht_req_destroy(r);
- dht.reqs.len--;
}
pthread_mutex_unlock(&dht.reqs.mtx);
@@ -4029,11 +3972,10 @@ void dht_fini(void)
pthread_rwlock_wrlock(&dht.db.lock);
- list_for_each_safe(p, h, &dht.db.kv.list) {
+ llist_for_each_safe(p, h, &dht.db.kv.ll) {
struct dht_entry * e = list_entry(p, struct dht_entry, next);
- list_del(&e->next);
+ llist_del(&e->next, &dht.db.kv.ll);
dht_entry_destroy(e);
- dht.db.kv.len--;
}
if (dht.db.contacts.root != NULL)
@@ -4043,10 +3985,10 @@ void dht_fini(void)
pthread_rwlock_destroy(&dht.db.lock);
- assert(dht.db.kv.len == 0);
+ assert(llist_is_empty(&dht.db.kv.ll));
assert(dht.db.kv.vals == 0);
assert(dht.db.kv.lvals == 0);
- assert(dht.reqs.len == 0);
+ assert(llist_is_empty(&dht.reqs.ll));
freebuf(dht.id);
}
diff --git a/src/ipcpd/unicast/dir/dht.h b/src/ipcpd/unicast/dir/dht.h
index 852a5130..ed3bb9f0 100644
--- a/src/ipcpd/unicast/dir/dht.h
+++ b/src/ipcpd/unicast/dir/dht.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Distributed Hash Table based on Kademlia
*
diff --git a/src/ipcpd/unicast/dir/dht.proto b/src/ipcpd/unicast/dir/dht.proto
index ea74805f..02b6b341 100644
--- a/src/ipcpd/unicast/dir/dht.proto
+++ b/src/ipcpd/unicast/dir/dht.proto
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* DHT protocol, based on Kademlia
*
diff --git a/src/ipcpd/unicast/dir/ops.h b/src/ipcpd/unicast/dir/ops.h
index 8c6e5eb5..6c336ee0 100644
--- a/src/ipcpd/unicast/dir/ops.h
+++ b/src/ipcpd/unicast/dir/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Directory policy ops
*
diff --git a/src/ipcpd/unicast/dir/pol.h b/src/ipcpd/unicast/dir/pol.h
index eae4b2e7..8ccf4f95 100644
--- a/src/ipcpd/unicast/dir/pol.h
+++ b/src/ipcpd/unicast/dir/pol.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Directory policies
*
diff --git a/src/ipcpd/unicast/dir/tests/CMakeLists.txt b/src/ipcpd/unicast/dir/tests/CMakeLists.txt
index 897f1ec2..eded823f 100644
--- a/src/ipcpd/unicast/dir/tests/CMakeLists.txt
+++ b/src/ipcpd/unicast/dir/tests/CMakeLists.txt
@@ -3,38 +3,36 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR
get_filename_component(CURRENT_BINARY_PARENT_DIR
${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
+compute_test_prefix()
+
create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
# Add new tests here
dht_test.c
- )
+)
-protobuf_generate_c(DHT_PROTO_SRCS KAD_PROTO_HDRS ../dht.proto)
+protobuf_generate_c(DHT_PROTO_SRCS KAD_PROTO_HDRS ${CURRENT_SOURCE_PARENT_DIR}/dht.proto)
add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests}
${DHT_PROTO_SRCS})
-target_link_libraries(${PARENT_DIR}_test ouroboros-common)
-add_dependencies(check ${PARENT_DIR}_test)
+target_include_directories(${PARENT_DIR}_test PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CURRENT_SOURCE_PARENT_DIR}
+ ${CURRENT_BINARY_PARENT_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+ ${CMAKE_SOURCE_DIR}/src/ipcpd
+ ${CMAKE_BINARY_DIR}/src/ipcpd
+ ${CMAKE_SOURCE_DIR}/src/ipcpd/unicast
+ ${CMAKE_BINARY_DIR}/src/ipcpd/unicast
+)
+
+disable_test_logging_for_target(${PARENT_DIR}_test)
-set(tests_to_run ${${PARENT_DIR}_tests})
-if(CMAKE_VERSION VERSION_LESS "3.29.0")
- remove(tests_to_run test_suite.c)
-else ()
- list(POP_FRONT tests_to_run)
-endif()
+target_link_libraries(${PARENT_DIR}_test ouroboros-common)
+add_dependencies(build_tests ${PARENT_DIR}_test)
-foreach (test ${tests_to_run})
- get_filename_component(test_name ${test} NAME_WE)
- add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
-endforeach (test)
+ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests})
diff --git a/src/ipcpd/unicast/dir/tests/dht_test.c b/src/ipcpd/unicast/dir/tests/dht_test.c
index cb6b0f9f..1f7026b3 100644
--- a/src/ipcpd/unicast/dir/tests/dht_test.c
+++ b/src/ipcpd/unicast/dir/tests/dht_test.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Unit tests of the DHT
*
@@ -27,7 +27,7 @@
#define _POSIX_C_SOURCE 200112L
#endif
-#include <ouroboros/test.h>
+#include <test/test.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
@@ -46,10 +46,9 @@
/* forward declare for use in the dht code */
/* Packet sink for DHT tests */
struct {
- bool enabled;
+ bool enabled;
- struct list_head list;
- size_t len;
+ struct llist msgs;
} sink;
struct message {
@@ -66,8 +65,6 @@ static int sink_send_msg(buffer_t * pkt,
assert(pkt != NULL);
assert(addr != 0);
- assert(!list_is_empty(&sink.list) || sink.len == 0);
-
if (!sink.enabled)
goto finish;
@@ -83,9 +80,8 @@ static int sink_send_msg(buffer_t * pkt,
m->dst = addr;
- list_add_tail(&m->next, &sink.list);
+ llist_add_tail(&m->next, &sink.msgs);
- ++sink.len;
finish:
freebuf(*pkt);
@@ -103,8 +99,7 @@ static int sink_send_msg(buffer_t * pkt,
static void sink_init(void)
{
- list_head_init(&sink.list);
- sink.len = 0;
+ llist_init(&sink.msgs);
sink.enabled = true;
}
@@ -113,22 +108,20 @@ static void sink_clear(void)
struct list_head * p;
struct list_head * h;
- list_for_each_safe(p, h, &sink.list) {
+ llist_for_each_safe(p, h, &sink.msgs) {
struct message * m = list_entry(p, struct message, next);
- list_del(&m->next);
+ llist_del(&m->next, &sink.msgs);
dht_msg__free_unpacked((dht_msg_t *) m->msg, NULL);
free(m);
- --sink.len;
}
- assert(list_is_empty(&sink.list));
+ assert(llist_is_empty(&sink.msgs));
}
static void sink_fini(void)
{
sink_clear();
-
- assert(list_is_empty(&sink.list) || sink.len != 0);
+ sink.enabled = false;
}
static dht_msg_t * sink_read(void)
@@ -136,16 +129,12 @@ static dht_msg_t * sink_read(void)
struct message * m;
dht_msg_t * msg;
- assert(!list_is_empty(&sink.list) || sink.len == 0);
-
- if (list_is_empty(&sink.list))
+ if (llist_is_empty(&sink.msgs))
return NULL;
- m = list_first_entry(&sink.list, struct message, next);
-
- --sink.len;
+ m = llist_first_entry(&sink.msgs, struct message, next);
- list_del(&m->next);
+ llist_del(&m->next, &sink.msgs);
msg = m->msg;
@@ -978,7 +967,7 @@ static int test_dht_kv_find_node_rsp_msg_contacts(void)
}
if ((size_t) n < dht.k) {
- printf("Failed to get enough contacts (%zu < %zu).\n", n, dht.k);
+ printf("Failed to get all contacts (%zu < %zu).\n", n, dht.k);
goto fail_fill;
}
@@ -1204,7 +1193,7 @@ static int test_dht_kv_find_value_rsp_msg_contacts(void)
}
if ((size_t) n < dht.k) {
- printf("Failed to get enough contacts (%zu < %zu).\n", n, dht.k);
+ printf("Failed to get all contacts (%zu < %zu).\n", n, dht.k);
goto fail_fill;
}
@@ -1591,7 +1580,7 @@ static int test_dht_reg_unreg(void)
goto fail_reg;
}
- if (sink.len != 0) {
+ if (!llist_is_empty(&sink.msgs)) {
printf("Packet sent without contacts!");
goto fail_msg;
}
@@ -1642,7 +1631,7 @@ static int test_dht_reg_unreg_contacts(void)
goto fail_reg;
}
- if (sink.len != dht.alpha) {
+ if (sink.msgs.len != dht.alpha) {
printf("Packet sent to too few contacts!\n");
goto fail_msg;
}
@@ -1784,7 +1773,7 @@ static int test_dht_query(void)
goto fail_get;
}
- if (sink.len != 0) {
+ if (!llist_is_empty(&sink.msgs)) {
printf("Packet sent without contacts!");
goto fail_test;
}
diff --git a/src/ipcpd/unicast/dt.c b/src/ipcpd/unicast/dt.c
index e2679ffe..252477f4 100644
--- a/src/ipcpd/unicast/dt.c
+++ b/src/ipcpd/unicast/dt.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Data Transfer Component
*
@@ -68,7 +68,7 @@
#endif
struct comp_info {
- void (* post_packet)(void * comp, struct shm_du_buff * sdb);
+ void (* post_packet)(void * comp, struct ssm_pk_buff * spb);
void * comp;
char * name;
};
@@ -135,11 +135,11 @@ static void dt_pci_des(uint8_t * head,
memcpy(&dt_pci->eid, head + dt_pci_info.eid_o, dt_pci_info.eid_size);
}
-static void dt_pci_shrink(struct shm_du_buff * sdb)
+static void dt_pci_shrink(struct ssm_pk_buff * spb)
{
- assert(sdb);
+ assert(spb);
- shm_du_buff_head_release(sdb, dt_pci_info.head_size);
+ ssm_pk_buff_head_release(spb, dt_pci_info.head_size);
}
struct {
@@ -429,7 +429,7 @@ static void handle_event(void * self,
static void packet_handler(int fd,
qoscube_t qc,
- struct shm_du_buff * sdb)
+ struct ssm_pk_buff * spb)
{
struct dt_pci dt_pci;
int ret;
@@ -437,7 +437,7 @@ static void packet_handler(int fd,
uint8_t * head;
size_t len;
- len = shm_du_buff_len(sdb);
+ len = ssm_pk_buff_len(spb);
#ifndef IPCP_FLOW_STATS
(void) fd;
@@ -451,13 +451,13 @@ static void packet_handler(int fd,
#endif
memset(&dt_pci, 0, sizeof(dt_pci));
- head = shm_du_buff_head(sdb);
+ head = ssm_pk_buff_head(spb);
dt_pci_des(head, &dt_pci);
if (dt_pci.dst_addr != dt.addr) {
if (dt_pci.ttl == 0) {
log_dbg("TTL was zero.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
#ifdef IPCP_FLOW_STATS
pthread_mutex_lock(&dt.stat[fd].lock);
@@ -474,7 +474,7 @@ static void packet_handler(int fd,
if (ofd < 0) {
log_dbg("No next hop for %" PRIu64 ".",
dt_pci.dst_addr);
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
#ifdef IPCP_FLOW_STATS
pthread_mutex_lock(&dt.stat[fd].lock);
@@ -488,12 +488,12 @@ static void packet_handler(int fd,
(void) ca_calc_ecn(ofd, head + dt_pci_info.ecn_o, qc, len);
- ret = ipcp_flow_write(ofd, sdb);
+ ret = ipcp_flow_write(ofd, spb);
if (ret < 0) {
log_dbg("Failed to write packet to fd %d.", ofd);
if (ret == -EFLOWDOWN)
notifier_event(NOTIFY_DT_FLOW_DOWN, &ofd);
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
#ifdef IPCP_FLOW_STATS
pthread_mutex_lock(&dt.stat[ofd].lock);
@@ -513,17 +513,17 @@ static void packet_handler(int fd,
pthread_mutex_unlock(&dt.stat[ofd].lock);
#endif
} else {
- dt_pci_shrink(sdb);
+ dt_pci_shrink(spb);
if (dt_pci.eid >= PROG_RES_FDS) {
uint8_t ecn = *(head + dt_pci_info.ecn_o);
- fa_np1_rcv(dt_pci.eid, ecn, sdb);
+ fa_np1_rcv(dt_pci.eid, ecn, spb);
return;
}
if (dt.comps[dt_pci.eid].post_packet == NULL) {
log_err("No registered component on eid %" PRIu64 ".",
dt_pci.eid);
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
return;
}
#ifdef IPCP_FLOW_STATS
@@ -541,7 +541,7 @@ static void packet_handler(int fd,
pthread_mutex_unlock(&dt.stat[dt_pci.eid].lock);
#endif
dt.comps[dt_pci.eid].post_packet(dt.comps[dt_pci.eid].comp,
- sdb);
+ spb);
}
}
@@ -758,7 +758,7 @@ void dt_stop(void)
}
int dt_reg_comp(void * comp,
- void (* func)(void * func, struct shm_du_buff *),
+ void (* func)(void * func, struct ssm_pk_buff *),
char * name)
{
int eid;
@@ -809,7 +809,7 @@ void dt_unreg_comp(int eid)
int dt_write_packet(uint64_t dst_addr,
qoscube_t qc,
uint64_t eid,
- struct shm_du_buff * sdb)
+ struct ssm_pk_buff * spb)
{
struct dt_pci dt_pci;
int fd;
@@ -817,12 +817,12 @@ int dt_write_packet(uint64_t dst_addr,
uint8_t * head;
size_t len;
- assert(sdb);
+ assert(spb);
assert(dst_addr != dt.addr);
- len = shm_du_buff_len(sdb);
-
#ifdef IPCP_FLOW_STATS
+ len = ssm_pk_buff_len(spb);
+
if (eid < PROG_RES_FDS) {
pthread_mutex_lock(&dt.stat[eid].lock);
@@ -849,13 +849,13 @@ int dt_write_packet(uint64_t dst_addr,
return -EPERM;
}
- head = shm_du_buff_head_alloc(sdb, dt_pci_info.head_size);
+ head = ssm_pk_buff_head_alloc(spb, dt_pci_info.head_size);
if (head == NULL) {
log_dbg("Failed to allocate DT header.");
goto fail_write;
}
- len = shm_du_buff_len(sdb);
+ len = ssm_pk_buff_len(spb);
dt_pci.dst_addr = dst_addr;
dt_pci.qc = qc;
@@ -866,7 +866,7 @@ int dt_write_packet(uint64_t dst_addr,
dt_pci_ser(head, &dt_pci);
- ret = ipcp_flow_write(fd, sdb);
+ ret = ipcp_flow_write(fd, spb);
if (ret < 0) {
log_dbg("Failed to write packet to fd %d.", fd);
if (ret == -EFLOWDOWN)
diff --git a/src/ipcpd/unicast/dt.h b/src/ipcpd/unicast/dt.h
index 2c5b7978..a484377d 100644
--- a/src/ipcpd/unicast/dt.h
+++ b/src/ipcpd/unicast/dt.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Data Transfer component
*
@@ -25,7 +25,7 @@
#include <ouroboros/ipcp.h>
#include <ouroboros/qoscube.h>
-#include <ouroboros/shm_rdrbuff.h>
+#include <ouroboros/ssm_pool.h>
#define DT_COMP "Data Transfer"
#define DT_PROTO "dtp"
@@ -40,7 +40,7 @@ int dt_start(void);
void dt_stop(void);
int dt_reg_comp(void * comp,
- void (* func)(void * comp, struct shm_du_buff * sdb),
+ void (* func)(void * comp, struct ssm_pk_buff * spb),
char * name);
void dt_unreg_comp(int eid);
@@ -48,6 +48,6 @@ void dt_unreg_comp(int eid);
int dt_write_packet(uint64_t dst_addr,
qoscube_t qc,
uint64_t eid,
- struct shm_du_buff * sdb);
+ struct ssm_pk_buff * spb);
#endif /* OUROBOROS_IPCPD_UNICAST_DT_H */
diff --git a/src/ipcpd/unicast/fa.c b/src/ipcpd/unicast/fa.c
index ac168bd9..ddf78e22 100644
--- a/src/ipcpd/unicast/fa.c
+++ b/src/ipcpd/unicast/fa.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Flow allocator of the IPC Process
*
@@ -48,6 +48,7 @@
#include "ipcp.h"
#include "dt.h"
#include "ca.h"
+#include "np1.h"
#include <inttypes.h>
#include <stdlib.h>
@@ -85,7 +86,7 @@ struct fa_msg {
struct cmd {
struct list_head next;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
};
struct fa_flow {
@@ -330,7 +331,7 @@ static uint64_t gen_eid(int fd)
static void packet_handler(int fd,
qoscube_t qc,
- struct shm_du_buff * sdb)
+ struct ssm_pk_buff * spb)
{
struct fa_flow * flow;
uint64_t r_addr;
@@ -342,7 +343,7 @@ static void packet_handler(int fd,
pthread_rwlock_wrlock(&fa.flows_lock);
- len = shm_du_buff_len(sdb);
+ len = ssm_pk_buff_len(spb);
#ifdef IPCP_FLOW_STATS
++flow->p_snd;
@@ -357,8 +358,8 @@ static void packet_handler(int fd,
ca_wnd_wait(wnd);
- if (dt_write_packet(r_addr, qc, r_eid, sdb)) {
- ipcp_sdb_release(sdb);
+ if (dt_write_packet(r_addr, qc, r_eid, spb)) {
+ ipcp_spb_release(spb);
log_dbg("Failed to forward packet.");
#ifdef IPCP_FLOW_STATS
pthread_rwlock_wrlock(&fa.flows_lock);
@@ -411,7 +412,7 @@ static void fa_flow_fini(struct fa_flow * flow)
}
static void fa_post_packet(void * comp,
- struct shm_du_buff * sdb)
+ struct ssm_pk_buff * spb)
{
struct cmd * cmd;
@@ -422,11 +423,11 @@ static void fa_post_packet(void * comp,
cmd = malloc(sizeof(*cmd));
if (cmd == NULL) {
log_err("Command failed. Out of memory.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
return;
}
- cmd->sdb = sdb;
+ cmd->spb = spb;
pthread_mutex_lock(&fa.mtx);
@@ -454,16 +455,16 @@ static size_t fa_wait_for_fa_msg(struct fa_msg * msg)
pthread_cleanup_pop(true);
- len = shm_du_buff_len(cmd->sdb);
+ len = ssm_pk_buff_len(cmd->spb);
if (len > MSGBUFSZ || len < sizeof(*msg)) {
log_warn("Invalid flow allocation message (len: %zd).", len);
free(cmd);
return 0; /* No valid message */
}
- memcpy(msg, shm_du_buff_head(cmd->sdb), len);
+ memcpy(msg, ssm_pk_buff_head(cmd->spb), len);
- ipcp_sdb_release(cmd->sdb);
+ ipcp_spb_release(cmd->spb);
free(cmd);
@@ -687,13 +688,21 @@ void fa_fini(void)
pthread_rwlock_destroy(&fa.flows_lock);
}
+static int np1_flow_read_fa(int fd,
+ struct ssm_pk_buff ** spb)
+{
+ return np1_flow_read(fd, spb, NP1_GET_POOL(fd));
+}
+
int fa_start(void)
{
+#ifndef BUILD_CONTAINER
struct sched_param par;
int pol;
int max;
+#endif
- fa.psched = psched_create(packet_handler, np1_flow_read);
+ fa.psched = psched_create(packet_handler, np1_flow_read_fa);
if (fa.psched == NULL) {
log_err("Failed to start packet scheduler.");
goto fail_psched;
@@ -704,6 +713,7 @@ int fa_start(void)
goto fail_thread;
}
+#ifndef BUILD_CONTAINER
if (pthread_getschedparam(fa.worker, &pol, &par)) {
log_err("Failed to get worker thread scheduling parameters.");
goto fail_sched;
@@ -721,12 +731,15 @@ int fa_start(void)
log_err("Failed to set scheduler priority to maximum.");
goto fail_sched;
}
+#endif
return 0;
+#ifndef BUILD_CONTAINER
fail_sched:
pthread_cancel(fa.worker);
pthread_join(fa.worker, NULL);
+#endif
fail_thread:
psched_destroy(fa.psched);
fail_psched:
@@ -747,7 +760,7 @@ int fa_alloc(int fd,
const buffer_t * data)
{
struct fa_msg * msg;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
struct fa_flow * flow;
uint64_t addr;
qoscube_t qc = QOS_CUBE_BE;
@@ -760,10 +773,10 @@ int fa_alloc(int fd,
len = sizeof(*msg) + ipcp_dir_hash_len();
- if (ipcp_sdb_reserve(&sdb, len + data->len))
+ if (ipcp_spb_reserve(&spb, len + data->len))
return -1;
- msg = (struct fa_msg *) shm_du_buff_head(sdb);
+ msg = (struct fa_msg *) ssm_pk_buff_head(spb);
memset(msg, 0, sizeof(*msg));
eid = gen_eid(fd);
@@ -782,11 +795,11 @@ int fa_alloc(int fd,
memcpy(msg + 1, dst, ipcp_dir_hash_len());
if (data->len > 0)
- memcpy(shm_du_buff_head(sdb) + len, data->data, data->len);
+ memcpy(ssm_pk_buff_head(spb) + len, data->data, data->len);
- if (dt_write_packet(addr, qc, fa.eid, sdb)) {
+ if (dt_write_packet(addr, qc, fa.eid, spb)) {
log_err("Failed to send flow allocation request packet.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
return -1;
}
@@ -808,7 +821,7 @@ int fa_alloc_resp(int fd,
const buffer_t * data)
{
struct fa_msg * msg;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
struct fa_flow * flow;
qoscube_t qc = QOS_CUBE_BE;
@@ -819,13 +832,13 @@ int fa_alloc_resp(int fd,
goto fail_alloc_resp;
}
- if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + data->len)) {
- log_err("Failed to reserve sdb (%zu bytes).",
+ if (ipcp_spb_reserve(&spb, sizeof(*msg) + data->len)) {
+ log_err("Failed to reserve spb (%zu bytes).",
sizeof(*msg) + data->len);
goto fail_reserve;
}
- msg = (struct fa_msg *) shm_du_buff_head(sdb);
+ msg = (struct fa_msg *) ssm_pk_buff_head(spb);
memset(msg, 0, sizeof(*msg));
msg->code = FLOW_REPLY;
@@ -840,7 +853,7 @@ int fa_alloc_resp(int fd,
pthread_rwlock_unlock(&fa.flows_lock);
- if (dt_write_packet(flow->r_addr, qc, fa.eid, sdb)) {
+ if (dt_write_packet(flow->r_addr, qc, fa.eid, spb)) {
log_err("Failed to send flow allocation response packet.");
goto fail_packet;
}
@@ -856,7 +869,7 @@ int fa_alloc_resp(int fd,
return 0;
fail_packet:
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
fail_reserve:
pthread_rwlock_wrlock(&fa.flows_lock);
fa_flow_fini(flow);
@@ -887,17 +900,17 @@ static int fa_update_remote(int fd,
uint16_t ece)
{
struct fa_msg * msg;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
qoscube_t qc = QOS_CUBE_BE;
struct fa_flow * flow;
uint64_t r_addr;
- if (ipcp_sdb_reserve(&sdb, sizeof(*msg))) {
- log_err("Failed to reserve sdb (%zu bytes).", sizeof(*msg));
+ if (ipcp_spb_reserve(&spb, sizeof(*msg))) {
+ log_err("Failed to reserve spb (%zu bytes).", sizeof(*msg));
return -1;
}
- msg = (struct fa_msg *) shm_du_buff_head(sdb);
+ msg = (struct fa_msg *) ssm_pk_buff_head(spb);
memset(msg, 0, sizeof(*msg));
@@ -916,9 +929,9 @@ static int fa_update_remote(int fd,
pthread_rwlock_unlock(&fa.flows_lock);
- if (dt_write_packet(r_addr, qc, fa.eid, sdb)) {
+ if (dt_write_packet(r_addr, qc, fa.eid, spb)) {
log_err("Failed to send flow update packet.");
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
return -1;
}
@@ -927,7 +940,7 @@ static int fa_update_remote(int fd,
void fa_np1_rcv(uint64_t eid,
uint8_t ecn,
- struct shm_du_buff * sdb)
+ struct ssm_pk_buff * spb)
{
struct fa_flow * flow;
bool update;
@@ -935,7 +948,7 @@ void fa_np1_rcv(uint64_t eid,
int fd;
size_t len;
- len = shm_du_buff_len(sdb);
+ len = ssm_pk_buff_len(spb);
pthread_rwlock_wrlock(&fa.flows_lock);
@@ -943,7 +956,7 @@ void fa_np1_rcv(uint64_t eid,
if (fd < 0) {
pthread_rwlock_unlock(&fa.flows_lock);
log_dbg("Received packet for unknown EID %" PRIu64 ".", eid);
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
return;
}
@@ -957,9 +970,9 @@ void fa_np1_rcv(uint64_t eid,
pthread_rwlock_unlock(&fa.flows_lock);
- if (ipcp_flow_write(fd, sdb) < 0) {
+ if (np1_flow_write(fd, spb, NP1_GET_POOL(fd)) < 0) {
log_dbg("Failed to write to flow %d.", fd);
- ipcp_sdb_release(sdb);
+ ipcp_spb_release(spb);
#ifdef IPCP_FLOW_STATS
pthread_rwlock_wrlock(&fa.flows_lock);
++flow->p_rcv_f;
diff --git a/src/ipcpd/unicast/fa.h b/src/ipcpd/unicast/fa.h
index 1e716966..0c19dc25 100644
--- a/src/ipcpd/unicast/fa.h
+++ b/src/ipcpd/unicast/fa.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Flow allocator of the IPC Process
*
@@ -47,6 +47,6 @@ int fa_dealloc(int fd);
void fa_np1_rcv(uint64_t eid,
uint8_t ecn,
- struct shm_du_buff * sdb);
+ struct ssm_pk_buff * spb);
#endif /* OUROBOROS_IPCPD_UNICAST_FA_H */
diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c
index 7989d3e1..583a04ff 100644
--- a/src/ipcpd/unicast/main.c
+++ b/src/ipcpd/unicast/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Unicast IPC Process
*
diff --git a/src/ipcpd/unicast/pff.c b/src/ipcpd/unicast/pff.c
index 9b2aa2b4..c8c3126f 100644
--- a/src/ipcpd/unicast/pff.c
+++ b/src/ipcpd/unicast/pff.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* PDU Forwarding Function
*
diff --git a/src/ipcpd/unicast/pff.h b/src/ipcpd/unicast/pff.h
index f44e5531..2eb42ce6 100644
--- a/src/ipcpd/unicast/pff.h
+++ b/src/ipcpd/unicast/pff.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* PDU Forwarding Function
*
diff --git a/src/ipcpd/unicast/pff/alternate.c b/src/ipcpd/unicast/pff/alternate.c
index 85e85914..be1c35c0 100644
--- a/src/ipcpd/unicast/pff/alternate.c
+++ b/src/ipcpd/unicast/pff/alternate.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Policy for PFF with alternate next hops
*
diff --git a/src/ipcpd/unicast/pff/alternate.h b/src/ipcpd/unicast/pff/alternate.h
index 96207e74..ae3758dc 100644
--- a/src/ipcpd/unicast/pff/alternate.h
+++ b/src/ipcpd/unicast/pff/alternate.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Policy for PFF with alternate next hops
*
diff --git a/src/ipcpd/unicast/pff/multipath.c b/src/ipcpd/unicast/pff/multipath.c
index cbab0f5f..c636e789 100644
--- a/src/ipcpd/unicast/pff/multipath.c
+++ b/src/ipcpd/unicast/pff/multipath.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Policy for PFF supporting multipath routing
*
diff --git a/src/ipcpd/unicast/pff/multipath.h b/src/ipcpd/unicast/pff/multipath.h
index 0eb03476..5329f7fc 100644
--- a/src/ipcpd/unicast/pff/multipath.h
+++ b/src/ipcpd/unicast/pff/multipath.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Policy for PFF supporting multipath routing
*
diff --git a/src/ipcpd/unicast/pff/ops.h b/src/ipcpd/unicast/pff/ops.h
index 16a31273..e4cabd11 100644
--- a/src/ipcpd/unicast/pff/ops.h
+++ b/src/ipcpd/unicast/pff/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Pff policy ops
*
diff --git a/src/ipcpd/unicast/pff/pft.c b/src/ipcpd/unicast/pff/pft.c
index 8c436113..a0d70799 100644
--- a/src/ipcpd/unicast/pff/pft.c
+++ b/src/ipcpd/unicast/pff/pft.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Packet forwarding table (PFT) with chaining on collisions
*
diff --git a/src/ipcpd/unicast/pff/pft.h b/src/ipcpd/unicast/pff/pft.h
index 711dabcb..3bb9cff7 100644
--- a/src/ipcpd/unicast/pff/pft.h
+++ b/src/ipcpd/unicast/pff/pft.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Packet forwarding table (PFT) with chaining on collisions
*
diff --git a/src/ipcpd/unicast/pff/pol.h b/src/ipcpd/unicast/pff/pol.h
index 245b03c4..e31c2794 100644
--- a/src/ipcpd/unicast/pff/pol.h
+++ b/src/ipcpd/unicast/pff/pol.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* PDU Forwarding Function policies
*
diff --git a/src/ipcpd/unicast/pff/simple.c b/src/ipcpd/unicast/pff/simple.c
index 5f95e3ce..be542bdb 100644
--- a/src/ipcpd/unicast/pff/simple.c
+++ b/src/ipcpd/unicast/pff/simple.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Simple PDU Forwarding Function
*
diff --git a/src/ipcpd/unicast/pff/simple.h b/src/ipcpd/unicast/pff/simple.h
index 0966a186..1046e4c4 100644
--- a/src/ipcpd/unicast/pff/simple.h
+++ b/src/ipcpd/unicast/pff/simple.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Simple policy for PFF
*
diff --git a/src/ipcpd/unicast/pff/tests/CMakeLists.txt b/src/ipcpd/unicast/pff/tests/CMakeLists.txt
index 99c32e7a..8c0e3d51 100644
--- a/src/ipcpd/unicast/pff/tests/CMakeLists.txt
+++ b/src/ipcpd/unicast/pff/tests/CMakeLists.txt
@@ -3,36 +3,32 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR
get_filename_component(CURRENT_BINARY_PARENT_DIR
${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
+compute_test_prefix()
+
create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
# Add new tests here
pft_test.c
)
add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests})
-target_link_libraries(${PARENT_DIR}_test ouroboros-common)
-add_dependencies(check ${PARENT_DIR}_test)
+target_include_directories(${PARENT_DIR}_test PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CURRENT_SOURCE_PARENT_DIR}
+ ${CURRENT_BINARY_PARENT_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+ ${CMAKE_SOURCE_DIR}/src/ipcpd
+ ${CMAKE_BINARY_DIR}/src/ipcpd
+)
+
+disable_test_logging_for_target(${PARENT_DIR}_test)
+target_link_libraries(${PARENT_DIR}_test PRIVATE ouroboros-common)
-set(tests_to_run ${${PARENT_DIR}_tests})
-if(CMAKE_VERSION VERSION_LESS "3.29.0")
- remove(tests_to_run test_suite.c)
-else ()
- list(POP_FRONT tests_to_run)
-endif()
+add_dependencies(build_tests ${PARENT_DIR}_test)
-foreach (test ${tests_to_run})
- get_filename_component(test_name ${test} NAME_WE)
- add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
-endforeach (test)
+ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests})
diff --git a/src/ipcpd/unicast/pff/tests/pft_test.c b/src/ipcpd/unicast/pff/tests/pft_test.c
index 18287fb8..4962c241 100644
--- a/src/ipcpd/unicast/pff/tests/pft_test.c
+++ b/src/ipcpd/unicast/pff/tests/pft_test.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Test of the hash table
*
diff --git a/src/ipcpd/unicast/psched.c b/src/ipcpd/unicast/psched.c
index 7e12148b..21e23617 100644
--- a/src/ipcpd/unicast/psched.c
+++ b/src/ipcpd/unicast/psched.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Packet scheduler component
*
@@ -41,11 +41,13 @@
#include <stdlib.h>
#include <string.h>
+#ifndef BUILD_CONTAINER
static int qos_prio [] = {
QOS_PRIO_BE,
QOS_PRIO_VIDEO,
QOS_PRIO_VOICE,
};
+#endif
struct psched {
fset_t * set[QOS_CUBE_MAX];
@@ -67,7 +69,7 @@ static void cleanup_reader(void * o)
static void * packet_reader(void * o)
{
struct psched * sched;
- struct shm_du_buff * sdb;
+ struct ssm_pk_buff * spb;
int fd;
fqueue_t * fq;
qoscube_t qc;
@@ -102,10 +104,10 @@ static void * packet_reader(void * o)
notifier_event(NOTIFY_DT_FLOW_UP, &fd);
break;
case FLOW_PKT:
- if (sched->read(fd, &sdb) < 0)
+ if (sched->read(fd, &spb) < 0)
continue;
- sched->callback(fd, qc, sdb);
+ sched->callback(fd, qc, spb);
break;
default:
break;
@@ -168,6 +170,7 @@ struct psched * psched_create(next_packet_fn_t callback,
}
}
+#ifndef BUILD_CONTAINER
for (i = 0; i < QOS_CUBE_MAX * IPCP_SCHED_THR_MUL; ++i) {
struct sched_param par;
int pol = SCHED_RR;
@@ -185,14 +188,17 @@ struct psched * psched_create(next_packet_fn_t callback,
if (pthread_setschedparam(psched->readers[i], pol, &par))
goto fail_sched;
}
+#endif
return psched;
+#ifndef BUILD_CONTAINER
fail_sched:
for (j = 0; j < QOS_CUBE_MAX * IPCP_SCHED_THR_MUL; ++j)
pthread_cancel(psched->readers[j]);
for (j = 0; j < QOS_CUBE_MAX * IPCP_SCHED_THR_MUL; ++j)
pthread_join(psched->readers[j], NULL);
+#endif
fail_infos:
for (j = 0; j < QOS_CUBE_MAX; ++j)
fset_destroy(psched->set[j]);
diff --git a/src/ipcpd/unicast/psched.h b/src/ipcpd/unicast/psched.h
index 831f8084..d83bb793 100644
--- a/src/ipcpd/unicast/psched.h
+++ b/src/ipcpd/unicast/psched.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Packet scheduler component
*
@@ -28,10 +28,10 @@
typedef void (* next_packet_fn_t)(int fd,
qoscube_t qc,
- struct shm_du_buff * sdb);
+ struct ssm_pk_buff * spb);
typedef int (* read_fn_t)(int fd,
- struct shm_du_buff ** sdb);
+ struct ssm_pk_buff ** spb);
struct psched * psched_create(next_packet_fn_t callback,
read_fn_t read);
diff --git a/src/ipcpd/unicast/routing.c b/src/ipcpd/unicast/routing.c
index 2ad7b234..1a4e4372 100644
--- a/src/ipcpd/unicast/routing.c
+++ b/src/ipcpd/unicast/routing.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Routing component of the IPCP
*
diff --git a/src/ipcpd/unicast/routing.h b/src/ipcpd/unicast/routing.h
index e14960b5..8d721095 100644
--- a/src/ipcpd/unicast/routing.h
+++ b/src/ipcpd/unicast/routing.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Routing component of the IPCP
*
diff --git a/src/ipcpd/unicast/routing/graph.c b/src/ipcpd/unicast/routing/graph.c
index 32442dad..0226c762 100644
--- a/src/ipcpd/unicast/routing/graph.c
+++ b/src/ipcpd/unicast/routing/graph.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Undirected graph structure
*
@@ -57,10 +57,7 @@ struct edge {
};
struct graph {
- struct {
- struct list_head list;
- size_t len;
- } vertices;
+ struct llist vertices;
pthread_mutex_t lock;
};
@@ -88,7 +85,7 @@ static struct vertex * find_vertex_by_addr(struct graph * graph,
assert(graph);
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
struct vertex * e = list_entry(p, struct vertex, next);
if (e->addr == addr)
return e;
@@ -142,7 +139,7 @@ static struct vertex * add_vertex(struct graph * graph,
vertex->addr = addr;
/* Keep them ordered on address. */
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
struct vertex * v = list_entry(p, struct vertex, next);
if (v->addr > addr)
break;
@@ -151,7 +148,7 @@ static struct vertex * add_vertex(struct graph * graph,
vertex->index = i;
- list_add_tail(&vertex->next, p);
+ llist_add_tail_at(&vertex->next, p, &graph->vertices);
/* Increase the index of the vertices to the right. */
list_for_each(p, &vertex->next) {
@@ -160,37 +157,41 @@ static struct vertex * add_vertex(struct graph * graph,
v->index++;
}
- ++graph->vertices.len;
-
return vertex;
}
+static void free_edges(struct list_head * edges)
+{
+ struct list_head * p;
+ struct list_head * h;
+
+ list_for_each_safe(p, h, edges) {
+ struct edge * e = list_entry(p, struct edge, next);
+ list_del(&e->next);
+ free(e);
+ }
+}
+
static void del_vertex(struct graph * graph,
struct vertex * vertex)
{
struct list_head * p;
- struct list_head * h;
assert(graph != NULL);
assert(vertex != NULL);
- list_del(&vertex->next);
+ llist_del(&vertex->next, &graph->vertices);
/* Decrease the index of the vertices to the right. */
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
struct vertex * v = list_entry(p, struct vertex, next);
if (v->addr > vertex->addr)
v->index--;
}
- list_for_each_safe(p, h, &vertex->edges) {
- struct edge * e = list_entry(p, struct edge, next);
- del_edge(e);
- }
+ free_edges(&vertex->edges);
free(vertex);
-
- --graph->vertices.len;
}
struct graph * graph_create(void)
@@ -206,8 +207,7 @@ struct graph * graph_create(void)
return NULL;
}
- graph->vertices.len = 0;
- list_head_init(&graph->vertices.list);
+ llist_init(&graph->vertices);
return graph;
}
@@ -221,7 +221,7 @@ void graph_destroy(struct graph * graph)
pthread_mutex_lock(&graph->lock);
- list_for_each_safe(p, n, &graph->vertices.list) {
+ llist_for_each_safe(p, n, &graph->vertices) {
struct vertex * e = list_entry(p, struct vertex, next);
del_vertex(graph, e);
}
@@ -230,7 +230,7 @@ void graph_destroy(struct graph * graph)
pthread_mutex_destroy(&graph->lock);
- assert(graph->vertices.len == 0);
+ assert(llist_is_empty(&graph->vertices));
free(graph);
}
@@ -371,7 +371,7 @@ static int get_min_vertex(struct graph * graph,
*v = NULL;
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
if (!used[i] && dist[i] < min) {
min = dist[i];
index = i;
@@ -420,7 +420,7 @@ static int dijkstra(struct graph * graph,
memset(*nhops, 0, sizeof(**nhops) * graph->vertices.len);
memset(*dist, 0, sizeof(**dist) * graph->vertices.len);
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
v = list_entry(p, struct vertex, next);
(*dist)[i++] = (v->addr == src) ? 0 : INT_MAX;
}
@@ -526,7 +526,7 @@ static int graph_routing_table_simple(struct graph * graph,
list_head_init(table);
/* Now construct the routing table from the nhops. */
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
v = list_entry(p, struct vertex, next);
/* This is the src */
@@ -624,7 +624,7 @@ static int graph_routing_table_lfa(struct graph * graph,
addrs[j] = -1;
}
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
v = list_entry(p, struct vertex, next);
if (v->addr != s_addr)
@@ -650,7 +650,7 @@ static int graph_routing_table_lfa(struct graph * graph,
}
/* Loop though all nodes to see if we have a LFA for them. */
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
v = list_entry(p, struct vertex, next);
if (v->addr == s_addr)
@@ -695,7 +695,6 @@ static int graph_routing_table_ecmp(struct graph * graph,
{
struct vertex ** nhops;
struct list_head * p;
- struct list_head * h;
size_t i;
struct vertex * v;
struct vertex * src_v;
@@ -735,16 +734,15 @@ static int graph_routing_table_ecmp(struct graph * graph,
free(nhops);
- list_for_each(h, &graph->vertices.list) {
- v = list_entry(h, struct vertex, next);
- if (tmp_dist[v->index] + 1 == (*dist)[v->index]) {
+ for (i = 0; i < graph->vertices.len; ++i) {
+ if (tmp_dist[i] + 1 == (*dist)[i]) {
n = malloc(sizeof(*n));
if (n == NULL) {
free(tmp_dist);
goto fail_src_v;
}
n->nhop = e->nb->addr;
- list_add_tail(&n->next, &forwarding[v->index]);
+ list_add_tail(&n->next, &forwarding[i]);
}
}
@@ -753,38 +751,34 @@ static int graph_routing_table_ecmp(struct graph * graph,
list_head_init(table);
i = 0;
- list_for_each(p, &graph->vertices.list) {
+ llist_for_each(p, &graph->vertices) {
v = list_entry(p, struct vertex, next);
- if (v->addr == s_addr) {
+ if (v->addr == s_addr || list_is_empty(&forwarding[i])) {
++i;
continue;
}
t = malloc(sizeof(*t));
if (t == NULL)
- goto fail_t;
+ goto fail_malloc;
t->dst = v->addr;
list_head_init(&t->nhops);
- if (&forwarding[i] != forwarding[i].nxt) {
- t->nhops.nxt = forwarding[i].nxt;
- t->nhops.prv = forwarding[i].prv;
- forwarding[i].prv->nxt = &t->nhops;
- forwarding[i].nxt->prv = &t->nhops;
- }
+ t->nhops.nxt = forwarding[i].nxt;
+ t->nhops.prv = forwarding[i].prv;
+ forwarding[i].prv->nxt = &t->nhops;
+ forwarding[i].nxt->prv = &t->nhops;
list_add(&t->next, table);
++i;
}
- free(*dist);
- *dist = NULL;
free(forwarding);
return 0;
- fail_t:
+ fail_malloc:
free_routing_table(table);
fail_src_v:
free(*dist);
diff --git a/src/ipcpd/unicast/routing/graph.h b/src/ipcpd/unicast/routing/graph.h
index 8190cc6c..f3766771 100644
--- a/src/ipcpd/unicast/routing/graph.h
+++ b/src/ipcpd/unicast/routing/graph.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Undirected graph structure
*
diff --git a/src/ipcpd/unicast/routing/link-state.c b/src/ipcpd/unicast/routing/link-state.c
index e5edf539..051dd98d 100644
--- a/src/ipcpd/unicast/routing/link-state.c
+++ b/src/ipcpd/unicast/routing/link-state.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Link state routing policy
*
@@ -56,7 +56,7 @@
#include <string.h>
#define LS_ENTRY_SIZE 104
-#define LSDB "lsdb"
+#define lsdb "lsdb"
#ifndef CLOCK_REALTIME_COARSE
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
@@ -121,16 +121,8 @@ struct {
struct graph * graph;
struct {
- struct {
- struct list_head list;
- size_t len;
- } nbs;
-
- struct {
- struct list_head list;
- size_t len;
- } db;
-
+ struct llist nbs;
+ struct llist db;
pthread_rwlock_t lock;
};
@@ -189,7 +181,7 @@ static struct adjacency * get_adj(const char * path)
assert(path);
- list_for_each(p, &ls.db.list) {
+ llist_for_each(p, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst));
if (strcmp(entry, path) == 0)
@@ -245,7 +237,7 @@ static int lsdb_rib_read(const char * path,
pthread_rwlock_rdlock(&ls.lock);
- if (ls.db.len + ls.nbs.len == 0)
+ if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs))
goto fail;
a = get_adj(entry);
@@ -274,7 +266,7 @@ static int lsdb_rib_readdir(char *** buf)
pthread_rwlock_rdlock(&ls.lock);
- if (ls.db.len + ls.nbs.len == 0) {
+ if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) {
*buf = NULL;
goto no_entries;
}
@@ -284,7 +276,7 @@ static int lsdb_rib_readdir(char *** buf)
if (*buf == NULL)
goto fail_entries;
- list_for_each(p, &ls.nbs.list) {
+ llist_for_each(p, &ls.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
char * str = (nb->type == NB_DT ? ".dt " : ".mgmt ");
sprintf(entry, "%s" ADDR_FMT32 , str, ADDR_VAL32(&nb->addr));
@@ -295,7 +287,7 @@ static int lsdb_rib_readdir(char *** buf)
strcpy((*buf)[idx++], entry);
}
- list_for_each(p, &ls.db.list) {
+ llist_for_each(p, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst));
(*buf)[idx] = malloc(strlen(entry) + 1);
@@ -333,7 +325,7 @@ static int lsdb_add_nb(uint64_t addr,
pthread_rwlock_wrlock(&ls.lock);
- list_for_each(p, &ls.nbs.list) {
+ llist_for_each(p, &ls.nbs) {
struct nb * el = list_entry(p, struct nb, next);
if (addr > el->addr)
break;
@@ -360,9 +352,7 @@ static int lsdb_add_nb(uint64_t addr,
nb->fd = fd;
nb->type = type;
- list_add_tail(&nb->next, p);
-
- ++ls.nbs.len;
+ llist_add_tail_at(&nb->next, p, &ls.nbs);
log_dbg("Type %s neighbor " ADDR_FMT32 " added.",
nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr));
@@ -380,13 +370,12 @@ static int lsdb_del_nb(uint64_t addr,
pthread_rwlock_wrlock(&ls.lock);
- list_for_each_safe(p, h, &ls.nbs.list) {
+ llist_for_each_safe(p, h, &ls.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->addr != addr || nb->fd != fd)
continue;
- list_del(&nb->next);
- --ls.nbs.len;
+ llist_del(&nb->next, &ls.nbs);
pthread_rwlock_unlock(&ls.lock);
log_dbg("Type %s neighbor " ADDR_FMT32 " deleted.",
nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr));
@@ -406,7 +395,7 @@ static int nbr_to_fd(uint64_t addr)
pthread_rwlock_rdlock(&ls.lock);
- list_for_each(p, &ls.nbs.list) {
+ llist_for_each(p, &ls.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->addr == addr && nb->type == NB_DT) {
fd = nb->fd;
@@ -494,7 +483,7 @@ static int lsdb_add_link(uint64_t src,
pthread_rwlock_wrlock(&ls.lock);
- list_for_each(p, &ls.db.list) {
+ llist_for_each(p, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
if (a->dst == dst && a->src == src) {
if (a->seqno < seqno) {
@@ -521,9 +510,7 @@ static int lsdb_add_link(uint64_t src,
adj->seqno = seqno;
adj->stamp = now.tv_sec;
- list_add_tail(&adj->next, p);
-
- ls.db.len++;
+ llist_add_tail_at(&adj->next, p, &ls.db);
if (graph_update_edge(ls.graph, src, dst, *qs))
log_warn("Failed to add edge to graph.");
@@ -543,15 +530,13 @@ static int lsdb_del_link(uint64_t src,
pthread_rwlock_wrlock(&ls.lock);
- list_for_each_safe(p, h, &ls.db.list) {
+ llist_for_each_safe(p, h, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
if (a->dst == dst && a->src == src) {
- list_del(&a->next);
+ llist_del(&a->next, &ls.db);
if (graph_del_edge(ls.graph, src, dst))
log_warn("Failed to delete edge from graph.");
- ls.db.len--;
-
pthread_rwlock_unlock(&ls.lock);
set_pff_modified(false);
free(a);
@@ -599,7 +584,7 @@ static void send_lsm(uint64_t src,
lsm.s_addr = hton64(src);
lsm.seqno = hton64(seqno);
- list_for_each(p, &ls.nbs.list) {
+ llist_for_each(p, &ls.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->type != NB_MGMT)
continue;
@@ -628,7 +613,7 @@ static void lsdb_replicate(int fd)
/* Lock the lsdb, copy the lsms and send outside of lock. */
pthread_rwlock_rdlock(&ls.lock);
- list_for_each(p, &ls.db.list) {
+ llist_for_each(p, &ls.db) {
struct adjacency * adj;
struct adjacency * cpy;
adj = list_entry(p, struct adjacency, next);
@@ -675,11 +660,11 @@ static void * lsupdate(void * o)
pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock);
- list_for_each_safe(p, h, &ls.db.list) {
+ llist_for_each_safe(p, h, &ls.db) {
struct adjacency * adj;
adj = list_entry(p, struct adjacency, next);
if (now.tv_sec > adj->stamp + ls.conf.t_timeo) {
- list_del(&adj->next);
+ llist_del(&adj->next, &ls.db);
log_dbg(LINK_FMT " timed out.",
LINK_VAL(adj->src, adj->dst));
if (graph_del_edge(ls.graph, adj->src,
@@ -746,7 +731,7 @@ static void forward_lsm(uint8_t * buf,
pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock);
- list_for_each(p, &ls.nbs.list) {
+ llist_for_each(p, &ls.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->type != NB_MGMT || nb->fd == in_fd)
continue;
@@ -874,19 +859,19 @@ static void handle_event(void * self,
pthread_cleanup_pop(true);
if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_DT))
- log_dbg("Failed to add neighbor to LSDB.");
+ log_dbg("Failed to add neighbor to lsdb.");
if (lsdb_add_link(ls.addr, c->conn_info.addr, 0, &qs))
- log_dbg("Failed to add new adjacency to LSDB.");
+ log_dbg("Failed to add new adjacency to lsdb.");
break;
case NOTIFY_DT_CONN_DEL:
flow_event(c->flow_info.fd, false);
if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd))
- log_dbg("Failed to delete neighbor from LSDB.");
+ log_dbg("Failed to delete neighbor from lsdb.");
if (lsdb_del_link(ls.addr, c->conn_info.addr))
- log_dbg("Local link was not in LSDB.");
+ log_dbg("Local link was not in lsdb.");
break;
case NOTIFY_DT_CONN_QOS:
log_dbg("QoS changes currently unsupported.");
@@ -902,14 +887,14 @@ static void handle_event(void * self,
fccntl(c->flow_info.fd, FLOWSFLAGS, flags | FLOWFRNOPART);
fset_add(ls.mgmt_set, c->flow_info.fd);
if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_MGMT))
- log_warn("Failed to add mgmt neighbor to LSDB.");
+ log_warn("Failed to add mgmt neighbor to lsdb.");
/* replicate the entire lsdb */
lsdb_replicate(c->flow_info.fd);
break;
case NOTIFY_MGMT_CONN_DEL:
fset_del(ls.mgmt_set, c->flow_info.fd);
if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd))
- log_warn("Failed to delete mgmt neighbor from LSDB.");
+ log_warn("Failed to delete mgmt neighbor from lsdb.");
break;
default:
break;
@@ -1090,16 +1075,13 @@ int link_state_init(struct ls_config * conf,
goto fail_fset_create;
}
- list_head_init(&ls.db.list);
- list_head_init(&ls.nbs.list);
+ llist_init(&ls.db);
+ llist_init(&ls.nbs);
list_head_init(&ls.instances.list);
- if (rib_reg(LSDB, &r_ops))
+ if (rib_reg(lsdb, &r_ops))
goto fail_rib_reg;
- ls.db.len = 0;
- ls.nbs.len = 0;
-
return 0;
fail_rib_reg:
@@ -1121,7 +1103,7 @@ void link_state_fini(void)
struct list_head * p;
struct list_head * h;
- rib_unreg(LSDB);
+ rib_unreg(lsdb);
fset_destroy(ls.mgmt_set);
@@ -1131,9 +1113,9 @@ void link_state_fini(void)
pthread_rwlock_wrlock(&ls.lock);
- list_for_each_safe(p, h, &ls.db.list) {
+ llist_for_each_safe(p, h, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
- list_del(&a->next);
+ llist_del(&a->next, &ls.db);
free(a);
}
diff --git a/src/ipcpd/unicast/routing/link-state.h b/src/ipcpd/unicast/routing/link-state.h
index 69eb6781..38e19065 100644
--- a/src/ipcpd/unicast/routing/link-state.h
+++ b/src/ipcpd/unicast/routing/link-state.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Link state routing policy
*
diff --git a/src/ipcpd/unicast/routing/ops.h b/src/ipcpd/unicast/routing/ops.h
index 4bf75c80..b19c5176 100644
--- a/src/ipcpd/unicast/routing/ops.h
+++ b/src/ipcpd/unicast/routing/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Routing policy ops
*
diff --git a/src/ipcpd/unicast/routing/pol.h b/src/ipcpd/unicast/routing/pol.h
index b6a6f150..545f5df2 100644
--- a/src/ipcpd/unicast/routing/pol.h
+++ b/src/ipcpd/unicast/routing/pol.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Routing policies
*
diff --git a/src/ipcpd/unicast/routing/tests/CMakeLists.txt b/src/ipcpd/unicast/routing/tests/CMakeLists.txt
index b5011474..be2de72c 100644
--- a/src/ipcpd/unicast/routing/tests/CMakeLists.txt
+++ b/src/ipcpd/unicast/routing/tests/CMakeLists.txt
@@ -3,36 +3,32 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR
get_filename_component(CURRENT_BINARY_PARENT_DIR
${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-include_directories(${CURRENT_SOURCE_PARENT_DIR})
-include_directories(${CURRENT_BINARY_PARENT_DIR})
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${CMAKE_BINARY_DIR}/include)
-
get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
+compute_test_prefix()
+
create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
# Add new tests here
graph_test.c
)
add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests})
-target_link_libraries(${PARENT_DIR}_test ouroboros-common)
-add_dependencies(check ${PARENT_DIR}_test)
+target_include_directories(${PARENT_DIR}_test PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CURRENT_SOURCE_PARENT_DIR}
+ ${CURRENT_BINARY_PARENT_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+ ${CMAKE_SOURCE_DIR}/src/ipcpd
+ ${CMAKE_BINARY_DIR}/src/ipcpd
+)
+
+disable_test_logging_for_target(${PARENT_DIR}_test)
+target_link_libraries(${PARENT_DIR}_test PRIVATE ouroboros-common)
-set(tests_to_run ${${PARENT_DIR}_tests})
-if(CMAKE_VERSION VERSION_LESS "3.29.0")
- remove(tests_to_run test_suite.c)
-else ()
- list(POP_FRONT tests_to_run)
-endif()
+add_dependencies(build_tests ${PARENT_DIR}_test)
-foreach (test ${tests_to_run})
- get_filename_component(test_name ${test} NAME_WE)
- add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
-endforeach (test)
+ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests})
diff --git a/src/ipcpd/unicast/routing/tests/graph_test.c b/src/ipcpd/unicast/routing/tests/graph_test.c
index d805640c..40a744ff 100644
--- a/src/ipcpd/unicast/routing/tests/graph_test.c
+++ b/src/ipcpd/unicast/routing/tests/graph_test.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2024
+ * Ouroboros - Copyright (C) 2016 - 2026
*
* Test of the graph structure
*