lib: mgmt: use SOMAXCONN for mgmtd socket listen backlog - #21514
Conversation
Greptile SummaryThis PR replaces the hard-coded Confidence Score: 5/5Safe to merge β single-line change with no logic risk, correct include chain, and consistent with existing FRR conventions. No P0 or P1 findings. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["msg_server_init()"] --> B["socket(AF_UNIX)"]
B --> C["bind(sopath)"]
C --> D["listen(sock, MGMTD_MAX_CONN)"]
D -->|"before: 32"| E["accept queue capped at 32\nconnect() β EAGAIN under load"]
D -->|"after: SOMAXCONN"| F["accept queue defers to\nnet.core.somaxconn (e.g. 4096)"]
F --> G["Client connects successfully\nunder high fan-in"]
Reviews (1): Last reviewed commit: "lib: mgmt: use SOMAXCONN for mgmtd socke..." | Re-trigger Greptile |
|
ci:rerun |
|
this PR looks like it got caught up with the build breakage from yesterday. I've initiated a rerun but in the meantime a rebase + force push would work wonders too |
742d603 to
128460d
Compare
128460d to
af7fd59
Compare
|
Rebased onto upstream/master |
|
Friendly ping β @donaldsharp this PR is approved by @ton31337 and the rebase has all CI green. Ready for merge whenever you have a moment. Thanks! |
|
I asked @choppsv1 to look at this on tuesday. Waiting for him to take a gander at it. Frankly I'm not sure I agree with the need to have this at a value greater than 32, on the other hand why would we even care? I wanted someone who's more familiar with mgmtd design to look at this in any event. |
|
32 is almost surely a valid value for any normal use of mgmtd -- probably much smaller actually. However, this larger value lets us pass some stress test and look better, and is a standard value ... ok. We aren't using a TCP socket and we don't do authentication so this is file permission protected socket. If the kernel lets you initiate a connect() and get into the accept queue, then you're a-ok -- so sure, Cry 'Havoc!' ... :) That said, |
af7fd59 to
fe1ec4a
Compare
|
yeah the named constant was mostly noise once it just equals SOMAXCONN. dropped the define, listen() takes SOMAXCONN directly, and the "this is the listen backlog, not a session cap" note moved down next to the call where someone might actually read it. pushed as |
Id remove the comment, we'd just be re-documenting the listen call. We should expect people to know what the args to the function do. It made more sense on the misnamed symbol defined away from use. |
The mgmtd frontend and backend UNIX sockets pass a compile-time constant of 32 to listen(2) as the accept-queue backlog. Under fan-in from multiple concurrent clients (vtysh sessions, test harnesses, external controllers) the kernel accept queue saturates and new connect(2) attempts fail with EAGAIN before the msg_server handler runs. This is observable as a hard ceiling: at roughly 1000 concurrent writers against mgmtd_fe.sock, ~75% of dial attempts fail even with multi-step client-side retry, because the failure is a transport-layer overflow the msg framing never sees. Pass SOMAXCONN directly to listen() instead, matching the convention already used by bgpd, bfdd, and pimd. The kernel remains the final arbiter of the effective queue length (on Linux via net.core.somaxconn, typically 4096). Operators who need a lower cap can still set net.core.somaxconn. Signed-off-by: Reinaldo Saraiva <reinaldo.saraiva@gmail.com> Signed-off-by: Christian Hopps <chopps@labn.net>
fe1ec4a to
a67d09f
Compare
|
Thanks @choppsv1 β comment removed, force-pushed as |
Mirrors .coderabbit.yaml as a second AI reviewer layer. Copilot code review reads .github/copilot-instructions.md from the base branch of each PR, so placing it on staging-review keeps the file fork-local and never reaches FRRouting/frr. Same 5 architectural NACK categories encoded as natural-language rules (Copilot's instruction format, as opposed to CodeRabbit's YAML path filters): - External-client ABI not supported (ref FRRouting#21538) - Wire values must be libc-portable (ref FRRouting#21557) - No header-only PRs without in-tree consumers (ref FRRouting#21557 Jafaral) - No inline re-documentation of libc (ref FRRouting#21514 choppsv1) - YANG list key NBC changes (ref FRRouting#21296) - Single output path JSON/non-JSON (ref FRRouting#21232) Plus style & hygiene rules (banned libc funcs, DOC block size, whitespace-mixed diffs, commit-msg format, no AI-attribution phrases). Stacked with CodeRabbit on the same staging PR: two independent reviewers, different lenses, negligible additional workflow cost. Signed-off-by: Reinaldo Saraiva <reinaldo.saraiva@gmail.com>
Summary
The mgmtd frontend and backend UNIX sockets pass a compile-time constant of
32tolisten(2)as the accept-queue backlog (MGMTD_MAX_CONNinlib/mgmt_msg.h). Under fan-in from multiple concurrent clients (vtysh sessions, test harnesses, external controllers) the kernel accept queue saturates and newconnect(2)attempts fail withEAGAINbefore themsg_serverhandler ever runs.This PR aligns mgmtd with the convention already used elsewhere in FRR β
bgpd/bgp_network.c,bfdd/dplane.c, andpimd/pim_msdp_socket.call passSOMAXCONNtolisten()β so the backlog defers to the platform default (on Linux,net.core.somaxconn, typically 4096 on modern kernels). The kernel remains the final arbiter of the effective queue length; operators who need a lower cap can still setnet.core.somaxconn.No API change:
MGMTD_MAX_CONNkeeps its name. An accompanying comment clarifies that it is alisten(2)backlog, not a cap on concurrent sessions (which can confuse readers given the name).Reproduction
Stress test with ~1000 concurrent writer goroutines each opening its own
msg_clientconnection to/var/run/frr/mgmtd_fe.sockand sending a smallEDITvia the native frontend protocol. On an unpatched build:SOMAXCONN(after)Kernel: Linux 5.15,
net.core.somaxconn=4096. Observable viass -xlpon the socket path (LISTEN 0 32βLISTEN 0 4096).Related Issue
None filed; happy to open one if preferred.
Components
mgmtd, lib