summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-07-05 18:32:03 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-07-08 11:02:24 +0200
commit11d3d58a8f60a16485e89582c1c12a224e11152b (patch)
tree70d74ed8a1f8e4666c5ea6d9dd4fc1f99185c254
parentfd7404d927277a623b7c24e62bd564aa6853f9d8 (diff)
downloadouroboros-11d3d58a8f60a16485e89582c1c12a224e11152b.tar.gz
ouroboros-11d3d58a8f60a16485e89582c1c12a224e11152b.zip
ipcpd: Minimize ipcpd-eth send buffer
The eth send buffer needs to block quickly so we can mark congestion correctly in the upper layer buffers. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
-rw-r--r--cmake/config/ipcp/eth.cmake4
-rw-r--r--src/ipcpd/eth/eth.c19
2 files changed, 15 insertions, 8 deletions
diff --git a/cmake/config/ipcp/eth.cmake b/cmake/config/ipcp/eth.cmake
index d336d647..6a044d4b 100644
--- a/cmake/config/ipcp/eth.cmake
+++ b/cmake/config/ipcp/eth.cmake
@@ -10,8 +10,8 @@ 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_SNDBUF 0 CACHE STRING
- "Raw socket SO_SNDBUF in bytes; 0 = leave kernel default (wmem_default)")
+set(IPCP_ETH_SNDBUF 4096 CACHE STRING
+ "Raw socket SO_SNDBUF in bytes (floored to one frame); 0 = kernel default")
set(IPCP_ETH_RCVBUF 0 CACHE STRING
"Raw socket SO_RCVBUF in bytes; 0 = leave kernel default (rmem_default)")
set(IPCP_ETH_LO_MTU 9000 CACHE STRING
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 7e038a03..efb1b61e 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -1942,15 +1942,22 @@ static int eth_init_raw_socket(struct ifreq * ifr)
#endif
sndbuf = IPCP_ETH_SNDBUF;
- if (sndbuf > 0 && setsockopt(eth_data.s_fd, SOL_SOCKET, SO_SNDBUF,
- &sndbuf, sizeof(sndbuf))) {
- log_info("Failed to set SO_SNDBUF to %d.", sndbuf);
+ if (sndbuf > 0) {
+ /* Never below one frame or sendto() cannot fit an SDU. */
+ sndbuf = MAX(sndbuf, (int) (ETH_HEADER_TOT_SIZE + ETH_MTU));
+ if (setsockopt(eth_data.s_fd, SOL_SOCKET, SO_SNDBUF,
+ &sndbuf, sizeof(sndbuf)))
+ log_info("Failed to set SO_SNDBUF to %d.", sndbuf);
}
rcvbuf = IPCP_ETH_RCVBUF;
- if (rcvbuf > 0 && setsockopt(eth_data.s_fd, SOL_SOCKET, SO_RCVBUF,
- &rcvbuf, sizeof(rcvbuf))) {
- log_info("Failed to set SO_RCVBUF to %d.", rcvbuf);
+ if (rcvbuf > 0) {
+ /* SO_RCVBUFFORCE bypasses rmem_max; SO_RCVBUF is fallback. */
+ if (setsockopt(eth_data.s_fd, SOL_SOCKET, SO_RCVBUFFORCE,
+ &rcvbuf, sizeof(rcvbuf))
+ && setsockopt(eth_data.s_fd, SOL_SOCKET, SO_RCVBUF,
+ &rcvbuf, sizeof(rcvbuf)))
+ log_info("Failed to set SO_RCVBUF to %d.", rcvbuf);
}
if (bind(eth_data.s_fd, (struct sockaddr *) &eth_data.device,