confd: skip neighbor/address flush for interfaces in container netns

When an interface has been handed off to a container it lives in
another netns, so `ip neigh/addr flush dev FOO` fails on the host.
The failure aborts dagger, and since interfaces_change() runs before
containers_change() in change_cb(), the container delete path is
never reached -- the stale container keeps the interface trapped in
its netns, breaking the next reconfiguration.

Guard both the neighbor and address flush exit scripts with
`if_nametoindex(ifname)` -- true exactly when the interface is in
the host netns, false for both "in a container" and "already gone".
This replaces the pre-existing `!cni_find(ifname) && if_nametoindex(
ifname)` guard at the addr site: cni_find() added no information
for this check and would popen(container find) for nothing when the
interface had been deleted entirely.

Also harden wrap() in /usr/sbin/container so a stale setup pidfile
doesn't short-circuit Finit's stop attempt -- kill the setup PID and
still ask podman to stop the container.

Fixes #1493

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2026-05-12 13:38:47 +02:00
parent 23da086976
commit d393a10994
2 changed files with 22 additions and 11 deletions
+4 -3
View File
@@ -652,7 +652,9 @@ wrap()
if [ "$cmd" = "stop" ]; then
# The setup phase may run forever in the background trying to fetch
# the image. It saves its PID in /run/containers/${name}.pid
# the image. It saves its PID in /run/containers/${name}.pid. Kill
# any in-flight setup, then fall through to podman stop -- a stale
# pidfile is not proof the container isn't running.
if [ -f "$pidfile" ]; then
pid=$(cat "$pidfile")
@@ -663,10 +665,9 @@ wrap()
fi
rm -f "$pidfile"
return 0
fi
# Only the 'podman stop' command takes -i and --timeout
# Only the 'podman stop' command takes -i (ignore missing) and --timeout
args="-i --timeout $timeout"
fi
+18 -8
View File
@@ -295,11 +295,18 @@ int netdag_gen_ip_neighs(struct dagger *net, FILE *ip, const char *proto,
int err = 0;
if (!ipconf || !lydx_is_enabled(ipconf, "enabled")) {
FILE *fp = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "flush-neigh.sh");
FILE *fp;
/* Skip if interface is currently in another netns (container) see #1493 */
if (!if_nametoindex(ifname))
return 0;
fp = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "flush-neigh.sh");
if (fp) {
fprintf(fp, "ip -%c neigh flush dev %s nud permanent\n", proto[3], ifname);
fclose(fp);
}
return 0;
}
@@ -323,15 +330,18 @@ int netdag_gen_ip_addrs(struct dagger *net, FILE *ip, const char *proto,
const char *ifname = lydx_get_cattr(dif, "name");
if (!ipconf || !lydx_is_enabled(ipconf, "enabled")) {
if (!cni_find(ifname) && if_nametoindex(ifname)) {
FILE *fp;
FILE *fp;
fp = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "flush.sh");
if (fp) {
fprintf(fp, "ip -%c addr flush dev %s\n", proto[3], ifname);
fclose(fp);
}
/* Skip if interface is currently in another netns (container) see #1493 */
if (!if_nametoindex(ifname))
return 0;
fp = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "flush.sh");
if (fp) {
fprintf(fp, "ip -%c addr flush dev %s\n", proto[3], ifname);
fclose(fp);
}
return 0;
}