diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-07-05 18:32:03 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-07-08 11:02:24 +0200 |
| commit | 11d3d58a8f60a16485e89582c1c12a224e11152b (patch) | |
| tree | 70d74ed8a1f8e4666c5ea6d9dd4fc1f99185c254 | |
| parent | fd7404d927277a623b7c24e62bd564aa6853f9d8 (diff) | |
| download | ouroboros-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.cmake | 4 | ||||
| -rw-r--r-- | 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, |
