From b3dd8e8118cbae6fa5172256dea0a56ccae308a0 Mon Sep 17 00:00:00 2001 From: James Coleman Date: Wed, 12 Aug 2026 14:01:26 -0500 Subject: [PATCH] Apply the resolvers instead of only writing them to the profile Setting DNS rewrote the connection profile and stopped there, so the running device kept resolving through whatever it had before. Nothing noticed while something else always activated the device afterwards: the profile was written first and NetworkManager picked the resolvers up when it got round to the interface on its own. Turning a DHCP client off now applies the profile when the device is not activated, which moved that activation ahead of the DNS write. A caller that sets an address, disables DHCP, and then sets resolvers -- the order a static configuration is naturally applied in -- ends with the device activated on a profile that had no DNS in it yet, and the write that follows never reaches the system. The profile carries the resolvers, resolv.conf carries none, and ipv4.ignore-auto-dns has by then ruled out the lease's resolvers as well: an interface holding an address, a route, and no way to resolve a name. Reapply the device after the change. Unlike turning a client off, this risks nothing for a caller connected over the interface -- reapply changes the device in place and does not tear the link down -- so it is not conditioned on the device being unactivated, which is exactly the case that needs it. --- networkManager.go | 13 +++++++++++++ tests/networkManager/results/1/test | 1 + tests/networkManager/results/2/test | 1 + 3 files changed, 15 insertions(+) diff --git a/networkManager.go b/networkManager.go index 05a0443..5622393 100644 --- a/networkManager.go +++ b/networkManager.go @@ -869,5 +869,18 @@ func (nm *networkManager) SetIfaceDNS(ctx context.Context, iface string, servers } } + // Put the resolvers into effect. Writing them to the profile alone leaves + // the running device on whatever it resolved through before, and the + // ignore-auto-dns above means that is now nothing at all where the old + // resolvers came from a lease -- a device holding an address, a route, and + // no way to resolve a name. Unlike turning a DHCP client off, this carries + // no risk for a caller connected over the interface: reapply changes the + // device in place and does not tear the link down. + if len(targets) != 0 { + if rerr := reapplyDevice(ctx, iface); rerr != nil { + logger.Printf("error applying the connection profile to %s: %v", iface, rerr) + } + } + return errors.Join(errs...) } diff --git a/tests/networkManager/results/1/test b/tests/networkManager/results/1/test index ebc2f46..6d7a0c1 100644 --- a/tests/networkManager/results/1/test +++ b/tests/networkManager/results/1/test @@ -4,3 +4,4 @@ connection modify test ipv4.routes 10.253.2.0/24 203.0.113.22 100 connection modify test ipv6.routes abcd:ef12:3455:10::/64 abcd:ef12:3456:10::1 100 connection modify test_eth0 ipv4.dns 8.8.8.8,1.1.1.1 ipv4.dns-search example.com ipv4.ignore-auto-dns yes connection modify test_eth0 ipv6.dns 2001:4860:4860::8888 ipv6.dns-search example.com ipv6.ignore-auto-dns yes +device reapply test_eth0 diff --git a/tests/networkManager/results/2/test b/tests/networkManager/results/2/test index 06ead3b..dda5457 100644 --- a/tests/networkManager/results/2/test +++ b/tests/networkManager/results/2/test @@ -4,6 +4,7 @@ connection modify test ipv4.routes 10.253.2.0/24 203.0.113.22 100 connection modify test ipv6.routes abcd:ef12:3455:10::/64 abcd:ef12:3456:10::1 100 connection modify test_eth0 ipv4.dns 8.8.8.8,1.1.1.1 ipv4.dns-search example.com ipv4.ignore-auto-dns yes connection modify test_eth0 ipv6.dns 2001:4860:4860::8888 ipv6.dns-search example.com ipv6.ignore-auto-dns yes +device reapply test_eth0 connection modify test_eth0 ipv4.method auto ipv4.addresses 1.2.10.4/24 ipv4.gateway 1.2.10.254 connection modify test_eth0 ipv6.method auto ipv6.addresses ipv6.gateway connection modify main ipv4.routes