From 889ef361eb478ecfe69e9012b07a98641ca2f408 Mon Sep 17 00:00:00 2001 From: Ben Duncan <5178243+benduncan@users.noreply.github.com> Date: Wed, 22 Apr 2026 16:30:38 +1000 Subject: [PATCH] fix: interim -T retrofit for dhcpcd EIP allocation Stop ObtainDHCPLease from erroring on hosts where dhcpcd is already running as a daemon managing br-wan (e.g. server 2). Add -T (test-only mode) so the invocation does not collide with the host daemon's control socket on the interface. Softens ProtectKernelTunables and MemoryDenyWriteExecute in the daemon unit to accommodate dhcpcd's runtime requirements; both revert when the in-process Go DHCP client rewrite lands (mulga-989 / mulga-990 / mulga-991, see docs/development/bugs/dhcp-allocate-error.md). Interim: leaves the phantom-lease and release-socket-clobber risks active until the rewrite replaces this path entirely. --- build/systemd/spinifex-daemon.service | 5 +++-- spinifex/handlers/ec2/vpc/external_ipam_dhcp.go | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build/systemd/spinifex-daemon.service b/build/systemd/spinifex-daemon.service index c37d28224..84307522e 100644 --- a/build/systemd/spinifex-daemon.service +++ b/build/systemd/spinifex-daemon.service @@ -34,13 +34,14 @@ LockPersonality=yes RestrictRealtime=yes RestrictNamespaces=yes ProtectClock=yes -ProtectKernelTunables=yes +# Required for dhcpcd (issue dhcpcd[867]: br-wan: if_init: Read-only file system) +ProtectKernelTunables=no ProtectKernelModules=yes ProtectKernelLogs=yes ProtectControlGroups=yes ProtectProc=invisible SystemCallArchitectures=native -MemoryDenyWriteExecute=yes +MemoryDenyWriteExecute=no # AF_PACKET is required by dhcpcd (raw L2 BOOTP before the iface has an IP). RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK AF_PACKET ProtectHostname=yes diff --git a/spinifex/handlers/ec2/vpc/external_ipam_dhcp.go b/spinifex/handlers/ec2/vpc/external_ipam_dhcp.go index b46846a18..7cda46c71 100644 --- a/spinifex/handlers/ec2/vpc/external_ipam_dhcp.go +++ b/spinifex/handlers/ec2/vpc/external_ipam_dhcp.go @@ -51,12 +51,17 @@ func ObtainDHCPLease(bridge, clientID string) (string, error) { // --noconfigure = don't add IP to interface (OVN handles traffic) // -1 = exit after obtaining a lease (don't daemonize) // -4 = IPv4 only - // -I clientID = unique client identifier per ENI + // -T = TEST MODE + // -I clientID = unique client identifier per ENI (Required to generate different IP from the DHCP server) // -t 15 = 15 second timeout cmd := exec.Command("sudo", dhcpcdBin, "--noconfigure", "-1", "-4", + + // Previous bug, if dhcpcd already running (e.g dhcp mode set on an interface, will send cmd to daemon, not STDOUT) + "-T", + "-I", clientID, "-t", "15", bridge,