From 11d3d58a8f60a16485e89582c1c12a224e11152b Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sun, 5 Jul 2026 18:32:03 +0200 Subject: 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 Signed-off-by: Sander Vrijders --- cmake/config/ipcp/eth.cmake | 4 ++-- src/ipcpd/eth/eth.c | 19 +++++++++++++------ 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 *) ð_data.device, -- cgit v1.2.3