XDP in NSD 4.14.0

Hi, @all

Running into a little oddity in NSD 4.14.0 (the Ubuntu package, apparently built with
–enable-xdp) and figured I’d flag it here.

Every time I systemctl restart nsd, the outgoing process logs this:

nsd[485157]: signal received, shutting down…
nsd[485157]: xdp: detaching xdp program 0 from (null)
nsd[485157]: xdp: failed to detach xdp program: Operation not permitted
systemd[1]: nsd.service: Killing process 490780 (nsd: server 1) with signal SIGKILL.
nsd[491669]: XDP support is enabled, but not configured. Not using XDP.

The giveaway is detaching xdp program 0 from (null) — we’ve never set xdp-interface, and NSD itself correctly says “XDP support is enabled, but not configured” on the next startup. But the shutdown path tries to detach anyway. Looks like the cleanup isn’t gated on whether an interface was ever attached.

I poked at a couple of workarounds for curiosity’s sake:

  • Granting CAP_SYS_ADMIN via a systemd drop-in — doesn’t help, since NSD drops caps itself after startup, so by shutdown time CapEff is zero regardless.
  • Adding xdp-program-load: no — parses fine, no effect on the shutdown path.

Neither is a real fix. Reproduces 100% on all 12 of our ns3-* anycast nodes (Ubuntu 24.04 LTS, stock package, nothing fancy in nsd.conf).

The actual impact is pretty mild — NSD restarts fine, DNS keeps serving, only a child process eats a SIGKILL — but it pollutes our journal with scary-looking lines and our log-watching stack counts them as crashes. And I’d rather not have an unclean shutdown path in production on principle.

Any thoughts?

Cheers, Jan Žorž

Hi,

indeed, I missed gating the cleanup on shutdown.

Here’s the patch for the time being:

diff --git a/server.c b/server.c
index ee67c035..756b51ea 100644
--- a/server.c
+++ b/server.c
@@ -3215,7 +3215,9 @@ server_main(struct nsd *nsd)
 	}
 
 #ifdef USE_XDP
-	xdp_server_cleanup(&nsd->xdp.xdp_server);
+	if (nsd->options->xdp_interface) {
+		xdp_server_cleanup(&nsd->xdp.xdp_server);
+	}
 #endif
 
 #ifdef MEMCLEAN /* OS collects memory pages */