You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
netkit: dae0 veth + /run/netns/daens left behind after clean SIGTERM stop (fast exit skips netns teardown) #1084
In netkit mode, systemctl stop dae (clean SIGTERM) leaves the dae0 interface and the named netns /run/netns/daens behind. dae exits cleanly, but does not tear down its own netkit interface / netns. This leaks kernel state after every stop, and can break a subsequent systemctl restart dae in edge cases (peer interface stuck in a half-dead netns).
Environment
dae: current main (identical code path on the kdae fork)
OS: Debian (LXC container on Proxmox VE), kernel 7.0.14-12-pve
Mode: netkit (auto-selected on kernel >= 6.7)
Reproduction
Start dae in netkit mode.
systemctl stop dae (SIGTERM).
Inspect leftover state:
# ip link show dae0
18: dae0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> ... link-netns daens # still UP
# ls /run/netns/daens
/run/netns/daens # still present
journal confirms a clean exit (not SIGKILL, no timeout):
Aug 21 01:09:45 debian systemd[1]: dae.service: Deactivated successfully.
Aug 21 01:09:45 debian systemd[1]: Stopped dae.service - dae Service.
dae received SIGTERM and exited normally, yet dae0 and /run/netns/daens were not torn down.
Root cause
cmd/run.goshutdownAfterSignalWithHandoff():
iffastExit {
log.Infoln("[Shutdown] Fast exit enabled; skipping in-process netns and control-plane teardown. Residual kernel state will be purged on next startup.")
returnnil// returns BEFORE netns.Close()
}
ifnetns!=nil {
ife:=netns.Close(); e!=nil { // would delete dae0 + /run/netns/daenslog.Warnf("close dae netns: %v", e)
}
}
fastExit is set to true in the SIGTERM/SIGINT/SIGQUIT handler, so every normal systemctl stop skips netns.Close(). That Close() (in control/netns_utils.go) is the only place calling DeleteLink(HostVethName) + DeleteNamedNetns(NsName) (i.e. dae0 + /run/netns/daens).
The residue is normally purged on the next startup (tryCreateNetkit deletes an existing dae0, setupNetns deletes an existing /run/netns/daens), which is why restart often still works. But a stop should not leave a live netkit interface + named netns behind.
Proposed fix
Tear down the netns unconditionally, before the fastExit early return. netns teardown is cheap (delete a link, delete a named netns, close two fds); only the expensive control-plane teardown (aborting connections, closing dialers) should be skipped on fast exit:
// Always tear down the netns first — it is cheap and leaves kernel// state (dae0 + /run/netns/daens) behind if skipped.ifnetns!=nil {
ife:=netns.Close(); e!=nil {
log.Warnf("close dae netns: %v", e)
}
}
iffastExit {
log.Infoln("[Shutdown] Fast exit enabled; skipping in-process control-plane teardown.")
returnnil
}
Activity
fix(cmd): tear down dae netns on fast exit to avoid leftover dae0/netns