diff --git a/metropolis/node/core/network/BUILD.bazel b/metropolis/node/core/network/BUILD.bazel
index bec2f19..23fdd5d 100644
--- a/metropolis/node/core/network/BUILD.bazel
+++ b/metropolis/node/core/network/BUILD.bazel
@@ -16,13 +16,13 @@
         "//go/algorithm/toposort",
         "//go/logging",
         "//metropolis/node",
-        "//metropolis/node/core/network/dhcp4c",
-        "//metropolis/node/core/network/dhcp4c/callback",
         "//metropolis/node/core/network/ipam",
         "//metropolis/node/core/network/workloads",
         "//metropolis/node/core/productinfo",
         "//osbase/event",
         "//osbase/event/memory",
+        "//osbase/net/dhcp4c",
+        "//osbase/net/dhcp4c/callback",
         "//osbase/net/dns",
         "//osbase/net/dns/forward",
         "//osbase/net/proto",
diff --git a/metropolis/node/core/network/dhcp4c/BUILD.bazel b/metropolis/node/core/network/dhcp4c/BUILD.bazel
deleted file mode 100644
index 34f2a23..0000000
--- a/metropolis/node/core/network/dhcp4c/BUILD.bazel
+++ /dev/null
@@ -1,38 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "dhcp4c",
-    srcs = [
-        "dhcpc.go",
-        "doc.go",
-        "lease.go",
-    ],
-    importpath = "source.monogon.dev/metropolis/node/core/network/dhcp4c",
-    visibility = [
-        "//metropolis/node:__subpackages__",
-        # Exception for this package: the DHCP client is also used by nanoswitch.
-        "//metropolis/test/nanoswitch:__subpackages__",
-    ],
-    deps = [
-        "//metropolis/node/core/network/dhcp4c/transport",
-        "//osbase/supervisor",
-        "@com_github_cenkalti_backoff_v4//:backoff",
-        "@com_github_insomniacslk_dhcp//dhcpv4",
-        "@com_github_insomniacslk_dhcp//iana",
-    ],
-)
-
-go_test(
-    name = "dhcp4c_test",
-    srcs = [
-        "dhcpc_test.go",
-        "lease_test.go",
-    ],
-    embed = [":dhcp4c"],
-    deps = [
-        "//metropolis/node/core/network/dhcp4c/transport",
-        "@com_github_cenkalti_backoff_v4//:backoff",
-        "@com_github_insomniacslk_dhcp//dhcpv4",
-        "@com_github_stretchr_testify//assert",
-    ],
-)
diff --git a/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel b/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
deleted file mode 100644
index 7e9827d..0000000
--- a/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
+++ /dev/null
@@ -1,37 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "k_test")
-
-go_library(
-    name = "callback",
-    srcs = ["callback.go"],
-    importpath = "source.monogon.dev/metropolis/node/core/network/dhcp4c/callback",
-    visibility = [
-        "//metropolis/node:__subpackages__",
-        # Exception for this package: the DHCP client is also used by nanoswitch.
-        "//metropolis/test/nanoswitch:__subpackages__",
-    ],
-    deps = [
-        "//metropolis/node/core/network/dhcp4c",
-        "@com_github_insomniacslk_dhcp//dhcpv4",
-        "@com_github_vishvananda_netlink//:netlink",
-        "@org_golang_x_sys//unix",
-    ],
-)
-
-go_test(
-    name = "callback_test",
-    srcs = ["callback_test.go"],
-    embed = [":callback"],
-    deps = [
-        "//metropolis/node/core/network/dhcp4c",
-        "@com_github_google_go_cmp//cmp",
-        "@com_github_insomniacslk_dhcp//dhcpv4",
-        "@com_github_vishvananda_netlink//:netlink",
-        "@org_golang_x_sys//unix",
-    ],
-)
-
-k_test(
-    name = "ktest",
-    tester = ":callback_test",
-)
diff --git a/metropolis/node/core/network/dhcp4c/callback/callback.go b/metropolis/node/core/network/dhcp4c/callback/callback.go
deleted file mode 100644
index 39c8ef1..0000000
--- a/metropolis/node/core/network/dhcp4c/callback/callback.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-// Package callback contains minimal callbacks for configuring the kernel with
-// options received over DHCP.
-//
-// These directly configure the relevant kernel subsytems and need to own
-// certain parts of them as documented on a per- callback basis to make sure
-// that they can recover from restarts and crashes of the DHCP client.
-// The callbacks in here are not suitable for use in advanced network scenarios
-// like running multiple DHCP clients per interface via ClientIdentifier or
-// when running an external FIB manager. In these cases it's advised to extract
-// the necessary information from the lease in your own callback and
-// communicate it directly to the responsible entity.
-package callback
-
-import (
-	"fmt"
-	"math"
-	"net"
-	"os"
-	"time"
-
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"github.com/vishvananda/netlink"
-	"golang.org/x/sys/unix"
-
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
-)
-
-// Compose can be used to chain multiple callbacks
-func Compose(callbacks ...dhcp4c.LeaseCallback) dhcp4c.LeaseCallback {
-	return func(lease *dhcp4c.Lease) error {
-		for _, cb := range callbacks {
-			if err := cb(lease); err != nil {
-				return err
-			}
-		}
-		return nil
-	}
-}
-
-func isIPNetEqual(a, b *net.IPNet) bool {
-	if a == b {
-		return true
-	}
-	if a == nil || b == nil {
-		return false
-	}
-	aOnes, aBits := a.Mask.Size()
-	bOnes, bBits := b.Mask.Size()
-	return a.IP.Equal(b.IP) && aOnes == bOnes && aBits == bBits
-}
-
-// ManageIP sets up and tears down the assigned IP address. It takes exclusive
-// ownership of all IPv4 addresses on the given interface which do not have
-// IFA_F_PERMANENT set, so it's not possible to run multiple dynamic addressing
-// clients on a single interface.
-func ManageIP(iface netlink.Link) dhcp4c.LeaseCallback {
-	return func(lease *dhcp4c.Lease) error {
-		newNet := lease.IPNet()
-
-		addrs, err := netlink.AddrList(iface, netlink.FAMILY_V4)
-		if err != nil {
-			return fmt.Errorf("netlink failed to list addresses: %w", err)
-		}
-
-		for _, addr := range addrs {
-			if addr.Flags&unix.IFA_F_PERMANENT == 0 {
-				// Linux identifies addreses by IP, mask and peer (see
-				// net/ipv4/devinet.find_matching_ifa in Linux 5.10).
-				// So don't touch addresses which match on these properties as
-				// AddrReplace will atomically reconfigure them anyways without
-				// interrupting things.
-				if isIPNetEqual(addr.IPNet, newNet) && addr.Peer == nil && lease != nil {
-					continue
-				}
-
-				if err := netlink.AddrDel(iface, &addr); !os.IsNotExist(err) && err != nil {
-					return fmt.Errorf("failed to delete address: %w", err)
-				}
-			}
-		}
-
-		if lease != nil {
-			remainingLifetimeSecs := int(math.Ceil(time.Until(lease.ExpiresAt).Seconds()))
-			newBroadcastIP := dhcpv4.GetIP(dhcpv4.OptionBroadcastAddress, lease.Options)
-			if err := netlink.AddrReplace(iface, &netlink.Addr{
-				IPNet:       newNet,
-				ValidLft:    remainingLifetimeSecs,
-				PreferedLft: remainingLifetimeSecs,
-				Broadcast:   newBroadcastIP,
-			}); err != nil {
-				return fmt.Errorf("failed to update address: %w", err)
-			}
-		}
-		return nil
-	}
-}
-
-// ManageRoutes installs and removes routes according to the current DHCP lease,
-// including the default route (if any).
-// It takes ownership of all RTPROTO_DHCP routes on the given interface, so it's
-// not possible to run multiple DHCP clients on the given interface.
-func ManageRoutes(iface netlink.Link) dhcp4c.LeaseCallback {
-	return func(lease *dhcp4c.Lease) error {
-		newRoutes := lease.Routes()
-
-		dhcpRoutes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{
-			Protocol:  unix.RTPROT_DHCP,
-			LinkIndex: iface.Attrs().Index,
-		}, netlink.RT_FILTER_OIF|netlink.RT_FILTER_PROTOCOL)
-		if err != nil {
-			return fmt.Errorf("netlink failed to list routes: %w", err)
-		}
-		for _, route := range dhcpRoutes {
-			// Don't remove routes which can be atomically replaced by
-			// RouteReplace to prevent potential traffic disruptions.
-			//
-			// This is O(n^2) but the number of routes is bounded by the size
-			// of a DHCP packet (around 100 routes). Sorting both would be
-			// be marginally faster for large amounts of routes only and in 99%
-			// of cases it's going to be <5 routes.
-			var found bool
-			for _, newRoute := range newRoutes {
-				if isIPNetEqual(newRoute.Dest, route.Dst) {
-					found = true
-					break
-				}
-			}
-			if !found {
-				err := netlink.RouteDel(&route)
-				if !os.IsNotExist(err) && err != nil {
-					return fmt.Errorf("failed to delete DHCP route: %w", err)
-				}
-			}
-		}
-
-		for _, route := range newRoutes {
-			newRoute := netlink.Route{
-				Protocol:  unix.RTPROT_DHCP,
-				Dst:       route.Dest,
-				Gw:        route.Router,
-				Src:       lease.AssignedIP,
-				LinkIndex: iface.Attrs().Index,
-				Scope:     netlink.SCOPE_UNIVERSE,
-			}
-			// Routes with a non-L3 gateway are link-scoped
-			if route.Router.IsUnspecified() {
-				newRoute.Scope = netlink.SCOPE_LINK
-			}
-			err := netlink.RouteReplace(&newRoute)
-			if err != nil {
-				return fmt.Errorf("failed to add %s: %w", route, err)
-			}
-		}
-		return nil
-	}
-}
diff --git a/metropolis/node/core/network/dhcp4c/callback/callback_test.go b/metropolis/node/core/network/dhcp4c/callback/callback_test.go
deleted file mode 100644
index d9735df..0000000
--- a/metropolis/node/core/network/dhcp4c/callback/callback_test.go
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-package callback
-
-import (
-	"fmt"
-	"math"
-	"net"
-	"os"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"github.com/vishvananda/netlink"
-	"golang.org/x/sys/unix"
-
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
-)
-
-func trivialLeaseFromNet(ipnet net.IPNet) *dhcp4c.Lease {
-	opts := make(dhcpv4.Options)
-	opts.Update(dhcpv4.OptSubnetMask(ipnet.Mask))
-	return &dhcp4c.Lease{
-		AssignedIP: ipnet.IP,
-		ExpiresAt:  time.Now().Add(1 * time.Second),
-		Options:    opts,
-	}
-}
-
-var (
-	testNet1          = net.IPNet{IP: net.IP{10, 0, 1, 2}, Mask: net.CIDRMask(24, 32)}
-	testNet1Broadcast = net.IP{10, 0, 1, 255}
-	testNet1Router    = net.IP{10, 0, 1, 1}
-	testNet2          = net.IPNet{IP: net.IP{10, 0, 2, 2}, Mask: net.CIDRMask(24, 32)}
-	testNet2Broadcast = net.IP{10, 0, 2, 255}
-	testNet2Router    = net.IP{10, 0, 2, 1}
-	mainRoutingTable  = 254 // Linux automatically puts all routes into this table unless specified
-)
-
-func TestAssignedIPCallback(t *testing.T) {
-	if os.Getenv("IN_KTEST") != "true" {
-		t.Skip("Not in ktest")
-	}
-
-	var tests = []struct {
-		name          string
-		initialAddrs  []netlink.Addr
-		newLease      *dhcp4c.Lease
-		expectedAddrs []netlink.Addr
-	}{
-		// Lifetimes are necessary, otherwise the Kernel sets the
-		// IFA_F_PERMANENT flag behind our back.
-		{
-			name:          "RemoveOldIPs",
-			initialAddrs:  []netlink.Addr{{IPNet: &testNet1, ValidLft: 60}, {IPNet: &testNet2, ValidLft: 60}},
-			newLease:      nil,
-			expectedAddrs: nil,
-		},
-		{
-			name:         "IgnoresPermanentIPs",
-			initialAddrs: []netlink.Addr{{IPNet: &testNet1, Flags: unix.IFA_F_PERMANENT}, {IPNet: &testNet2, ValidLft: 60}},
-			newLease:     trivialLeaseFromNet(testNet2),
-			expectedAddrs: []netlink.Addr{
-				{IPNet: &testNet1, Flags: unix.IFA_F_PERMANENT, ValidLft: math.MaxUint32, PreferedLft: math.MaxUint32, Broadcast: testNet1Broadcast},
-				{IPNet: &testNet2, ValidLft: 1, PreferedLft: 1, Broadcast: testNet2Broadcast},
-			},
-		},
-		{
-			name:         "AssignsNewIP",
-			initialAddrs: []netlink.Addr{},
-			newLease:     trivialLeaseFromNet(testNet2),
-			expectedAddrs: []netlink.Addr{
-				{IPNet: &testNet2, ValidLft: 1, PreferedLft: 1, Broadcast: testNet2Broadcast},
-			},
-		},
-		{
-			name:         "UpdatesIP",
-			initialAddrs: []netlink.Addr{},
-			newLease:     trivialLeaseFromNet(testNet1),
-			expectedAddrs: []netlink.Addr{
-				{IPNet: &testNet1, ValidLft: 1, PreferedLft: 1, Broadcast: testNet1Broadcast},
-			},
-		},
-		{
-			name:          "RemovesIPOnRelease",
-			initialAddrs:  []netlink.Addr{{IPNet: &testNet1, ValidLft: 60, PreferedLft: 60}},
-			newLease:      nil,
-			expectedAddrs: nil,
-		},
-	}
-	for i, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			testLink := &netlink.Dummy{
-				LinkAttrs: netlink.LinkAttrs{
-					Name:  fmt.Sprintf("aipcb-test-%d", i),
-					Flags: unix.IFF_UP,
-				},
-			}
-			if err := netlink.LinkAdd(testLink); err != nil {
-				t.Fatalf("test cannot set up network interface: %v", err)
-			}
-			defer netlink.LinkDel(testLink)
-			for _, addr := range test.initialAddrs {
-				if err := netlink.AddrAdd(testLink, &addr); err != nil {
-					t.Fatalf("test cannot set up initial addrs: %v", err)
-				}
-			}
-			// Associate dynamically-generated interface name for later comparison
-			for i := range test.expectedAddrs {
-				test.expectedAddrs[i].Label = testLink.Name
-				test.expectedAddrs[i].LinkIndex = testLink.Index
-			}
-			cb := ManageIP(testLink)
-			if err := cb(test.newLease); err != nil {
-				t.Fatalf("callback returned an error: %v", err)
-			}
-			addrs, err := netlink.AddrList(testLink, netlink.FAMILY_V4)
-			if err != nil {
-				t.Fatalf("test cannot read back addrs from interface: %v", err)
-			}
-			if diff := cmp.Diff(test.expectedAddrs, addrs); diff != "" {
-				t.Errorf("Wrong IPs on interface (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
-
-func leaseAddRouter(lease *dhcp4c.Lease, router net.IP) *dhcp4c.Lease {
-	lease.Options.Update(dhcpv4.OptRouter(router))
-	return lease
-}
-
-func leaseAddClasslessRoutes(lease *dhcp4c.Lease, routes ...*dhcpv4.Route) *dhcp4c.Lease {
-	lease.Options.Update(dhcpv4.OptClasslessStaticRoute(routes...))
-	return lease
-}
-
-func mustParseCIDR(cidr string) *net.IPNet {
-	_, n, err := net.ParseCIDR(cidr)
-	if err != nil {
-		panic(err)
-	}
-	// Equality checks don't know about net.IP's canonicalization rules.
-	if n.IP.To4() != nil {
-		n.IP = n.IP.To4()
-	}
-	return n
-}
-
-func TestDefaultRouteCallback(t *testing.T) {
-	if os.Getenv("IN_KTEST") != "true" {
-		t.Skip("Not in ktest")
-	}
-	// testRoute is only used as a route destination and not configured on any
-	// interface.
-	testRoute := net.IPNet{IP: net.IP{10, 0, 3, 0}, Mask: net.CIDRMask(24, 32)}
-
-	// A test interface is set up for each test and assigned testNet1 and
-	// testNet2 so that testNet1Router and testNet2Router are valid gateways
-	// for routes in this environment. A LinkIndex of -1 is replaced by the
-	// correct link index for this test interface at runtime for both
-	// initialRoutes and expectedRoutes.
-	var tests = []struct {
-		name           string
-		initialRoutes  []netlink.Route
-		newLease       *dhcp4c.Lease
-		expectedRoutes []netlink.Route
-	}{
-		{
-			name:          "AddsDefaultRoute",
-			initialRoutes: []netlink.Route{},
-			newLease:      leaseAddRouter(trivialLeaseFromNet(testNet1), testNet1Router),
-			expectedRoutes: []netlink.Route{{
-				Protocol:  unix.RTPROT_DHCP,
-				Dst:       mustParseCIDR("0.0.0.0/0"),
-				Family:    unix.AF_INET,
-				Gw:        testNet1Router,
-				Src:       testNet1.IP,
-				Table:     mainRoutingTable,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Type:      unix.RTN_UNICAST,
-			}},
-		},
-		{
-			name:           "IgnoresLeasesWithoutRouter",
-			initialRoutes:  []netlink.Route{},
-			newLease:       trivialLeaseFromNet(testNet1),
-			expectedRoutes: nil,
-		},
-		{
-			name: "RemovesUnrelatedOldRoutes",
-			initialRoutes: []netlink.Route{{
-				Dst:       &testRoute,
-				Family:    unix.AF_INET,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Protocol:  unix.RTPROT_DHCP,
-				Gw:        testNet2Router,
-				Scope:     netlink.SCOPE_UNIVERSE,
-			}},
-			newLease:       nil,
-			expectedRoutes: nil,
-		},
-		{
-			name: "IgnoresNonDHCPRoutes",
-			initialRoutes: []netlink.Route{{
-				Dst:       &testRoute,
-				Family:    unix.AF_INET,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Protocol:  unix.RTPROT_BIRD,
-				Gw:        testNet2Router,
-			}},
-			newLease: nil,
-			expectedRoutes: []netlink.Route{{
-				Protocol:  unix.RTPROT_BIRD,
-				Dst:       &testRoute,
-				Family:    unix.AF_INET,
-				Gw:        testNet2Router,
-				Table:     mainRoutingTable,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Type:      unix.RTN_UNICAST,
-			}},
-		},
-		{
-			name: "RemovesRoute",
-			initialRoutes: []netlink.Route{{
-				Dst:       nil,
-				Family:    unix.AF_INET,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Protocol:  unix.RTPROT_DHCP,
-				Gw:        testNet2Router,
-			}},
-			newLease:       nil,
-			expectedRoutes: nil,
-		},
-		{
-			name: "UpdatesRoute",
-			initialRoutes: []netlink.Route{{
-				Dst:       nil,
-				Family:    unix.AF_INET,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Protocol:  unix.RTPROT_DHCP,
-				Src:       testNet1.IP,
-				Gw:        testNet1Router,
-			}},
-			newLease: leaseAddRouter(trivialLeaseFromNet(testNet2), testNet2Router),
-			expectedRoutes: []netlink.Route{{
-				Protocol:  unix.RTPROT_DHCP,
-				Dst:       mustParseCIDR("0.0.0.0/0"),
-				Family:    unix.AF_INET,
-				Gw:        testNet2Router,
-				Src:       testNet2.IP,
-				Table:     mainRoutingTable,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Type:      unix.RTN_UNICAST,
-			}},
-		},
-		{
-			name:          "AddsClasslessStaticRoutes",
-			initialRoutes: []netlink.Route{},
-			newLease: leaseAddClasslessRoutes(
-				// Router should be ignored
-				leaseAddRouter(trivialLeaseFromNet(testNet1), testNet1Router),
-				// P2P/foreign gateway route
-				&dhcpv4.Route{Dest: mustParseCIDR("192.168.42.1/32"), Router: net.IPv4zero},
-				// Standard route over foreign gateway set up by previous route
-				&dhcpv4.Route{Dest: mustParseCIDR("0.0.0.0/0"), Router: net.IPv4(192, 168, 42, 1)},
-			),
-			expectedRoutes: []netlink.Route{{
-				Protocol:  unix.RTPROT_DHCP,
-				Dst:       mustParseCIDR("0.0.0.0/0"),
-				Family:    unix.AF_INET,
-				Gw:        net.IPv4(192, 168, 42, 1).To4(), // Equal() doesn't know about canonicalization
-				Src:       testNet1.IP,
-				Table:     mainRoutingTable,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Type:      unix.RTN_UNICAST,
-			}, {
-				Protocol:  unix.RTPROT_DHCP,
-				Dst:       mustParseCIDR("192.168.42.1/32"),
-				Family:    unix.AF_INET,
-				Gw:        nil,
-				Src:       testNet1.IP,
-				Table:     mainRoutingTable,
-				LinkIndex: -1, // Filled in dynamically with test interface
-				Type:      unix.RTN_UNICAST,
-				Scope:     unix.RT_SCOPE_LINK,
-			}},
-		},
-	}
-	for i, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			testLink := &netlink.Dummy{
-				LinkAttrs: netlink.LinkAttrs{
-					Name:  fmt.Sprintf("drcb-test-%d", i),
-					Flags: unix.IFF_UP,
-				},
-			}
-			if err := netlink.LinkAdd(testLink); err != nil {
-				t.Fatalf("test cannot set up network interface: %v", err)
-			}
-			defer func() { // Clean up after each test
-				routes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{}, 0)
-				if err == nil {
-					for _, route := range routes {
-						netlink.RouteDel(&route)
-					}
-				}
-			}()
-			defer netlink.LinkDel(testLink)
-			if err := netlink.AddrAdd(testLink, &netlink.Addr{
-				IPNet: &testNet1,
-			}); err != nil {
-				t.Fatalf("test cannot set up test addrs: %v", err)
-			}
-			if err := netlink.AddrAdd(testLink, &netlink.Addr{
-				IPNet: &testNet2,
-			}); err != nil {
-				t.Fatalf("test cannot set up test addrs: %v", err)
-			}
-			for _, route := range test.initialRoutes {
-				if route.LinkIndex == -1 {
-					route.LinkIndex = testLink.Index
-				}
-				if err := netlink.RouteAdd(&route); err != nil {
-					t.Fatalf("test cannot set up initial routes: %v", err)
-				}
-			}
-			for i := range test.expectedRoutes {
-				if test.expectedRoutes[i].LinkIndex == -1 {
-					test.expectedRoutes[i].LinkIndex = testLink.Index
-				}
-			}
-
-			cb := ManageRoutes(testLink)
-			if err := cb(test.newLease); err != nil {
-				t.Fatalf("callback returned an error: %v", err)
-			}
-			routes, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{}, 0)
-			if err != nil {
-				t.Fatalf("test cannot read back routes: %v", err)
-			}
-			var notKernelRoutes []netlink.Route
-			for _, route := range routes {
-				if route.Protocol != unix.RTPROT_KERNEL { // Filter kernel-managed routes
-					notKernelRoutes = append(notKernelRoutes, route)
-				}
-			}
-			if diff := cmp.Diff(test.expectedRoutes, notKernelRoutes); diff != "" {
-				t.Errorf("Expected route mismatch (-want +got):\n%s", diff)
-			}
-		})
-	}
-}
diff --git a/metropolis/node/core/network/dhcp4c/dhcpc.go b/metropolis/node/core/network/dhcp4c/dhcpc.go
deleted file mode 100644
index dff272b..0000000
--- a/metropolis/node/core/network/dhcp4c/dhcpc.go
+++ /dev/null
@@ -1,709 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-// Package dhcp4c implements a DHCPv4 Client as specified in RFC2131 (with some
-// notable deviations).  It implements only the DHCP state machine itself, any
-// configuration other than the interface IP address (which is always assigned
-// in DHCP and necessary for the protocol to work) is exposed as
-// [informers/observables/watchable variables/???] to consumers who then deal
-// with it.
-package dhcp4c
-
-import (
-	"context"
-	"crypto/rand"
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"net"
-	"time"
-
-	"github.com/cenkalti/backoff/v4"
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"github.com/insomniacslk/dhcp/iana"
-
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c/transport"
-	"source.monogon.dev/osbase/supervisor"
-)
-
-type state int
-
-const (
-	// stateDiscovering sends broadcast DHCPDISCOVER messages to the network
-	// and waits for either a DHCPOFFER or (in case of Rapid Commit) DHCPACK.
-	stateDiscovering state = iota
-	// stateRequesting sends broadcast DHCPREQUEST messages containing the
-	// server identifier for the selected lease and waits for a DHCPACK or a
-	// DHCPNAK. If it doesn't get either it transitions back into discovering.
-	stateRequesting
-	// stateBound just waits until RenewDeadline (derived from RenewTimeValue,
-	// half the lifetime by default) expires.
-	stateBound
-	// stateRenewing sends unicast DHCPREQUEST messages to the
-	// currently-selected server and waits for either a DHCPACK or DHCPNAK
-	// message. On DHCPACK it transitions to bound, otherwise to discovering.
-	stateRenewing
-	// stateRebinding sends broadcast DHCPREQUEST messages to the network and
-	// waits for either a DHCPACK or DHCPNAK from any server. Response
-	// processing is identical to stateRenewing.
-	stateRebinding
-)
-
-func (s state) String() string {
-	switch s {
-	case stateDiscovering:
-		return "DISCOVERING"
-	case stateRequesting:
-		return "REQUESTING"
-	case stateBound:
-		return "BOUND"
-	case stateRenewing:
-		return "RENEWING"
-	case stateRebinding:
-		return "REBINDING"
-	default:
-		return "INVALID"
-	}
-}
-
-// This only requests SubnetMask and IPAddressLeaseTime as renewal and
-// rebinding times are fine if they are just defaulted. They are respected (if
-// valid, otherwise they are clamped to the nearest valid value) if sent by the
-// server.
-var internalOptions = dhcpv4.OptionCodeList{dhcpv4.OptionSubnetMask, dhcpv4.OptionIPAddressLeaseTime}
-
-// Transport represents a mechanism over which DHCP messages can be exchanged
-// with a server.
-type Transport interface {
-	// Send attempts to send the given DHCP payload message to the transport
-	// target once. An empty return value does not indicate that the message
-	// was successfully received.
-	Send(payload *dhcpv4.DHCPv4) error
-	// SetReceiveDeadline sets a deadline for Receive() calls after which they
-	// return with ErrDeadlineExceeded
-	SetReceiveDeadline(time.Time) error
-	// Receive waits for a DHCP message to arrive and returns it. If the
-	// deadline expires without a message arriving it will return
-	// ErrDeadlineExceeded. If the message is completely malformed it will an
-	// instance of InvalidMessageError.
-	Receive() (*dhcpv4.DHCPv4, error)
-	// Close closes the given transport. Calls to any of the above methods will
-	// fail if the transport is closed.  Specific transports can be reopened
-	// after being closed.
-	Close() error
-}
-
-// UnicastTransport represents a mechanism over which DHCP messages can be
-// exchanged with a single server over an arbitrary IPv4-based network.
-// Implementers need to support servers running outside the local network via a
-// router.
-type UnicastTransport interface {
-	Transport
-	// Open connects the transport to a new unicast target. Can only be called
-	// after calling Close() or after creating a new transport.
-	Open(serverIP, bindIP net.IP) error
-}
-
-// BroadcastTransport represents a mechanism over which DHCP messages can be
-// exchanged with all servers on a Layer 2 broadcast domain. Implementers need
-// to support sending and receiving messages without any IP being configured on
-// the interface.
-type BroadcastTransport interface {
-	Transport
-	// Open connects the transport. Can only be called after calling Close() or
-	// after creating a new transport.
-	Open() error
-}
-
-type LeaseCallback func(*Lease) error
-
-// Client implements a DHCPv4 client.
-//
-// Note that the size of all data sent to the server (RequestedOptions,
-// ClientIdentifier, VendorClassIdentifier and ExtraRequestOptions) should be
-// kept reasonably small (<500 bytes) in order to maximize the chance that
-// requests can be properly transmitted.
-type Client struct {
-	// RequestedOptions contains a list of extra options this client is
-	// interested in
-	RequestedOptions dhcpv4.OptionCodeList
-
-	// ClientIdentifier is used by the DHCP server to identify this client.
-	// If empty, on Ethernet the MAC address is used instead.
-	ClientIdentifier []byte
-
-	// VendorClassIdentifier is used by the DHCP server to identify options
-	// specific to this type of clients and to populate the vendor-specific
-	// option (43).
-	VendorClassIdentifier string
-
-	// ExtraRequestOptions are extra options sent to the server.
-	ExtraRequestOptions dhcpv4.Options
-
-	// Backoff strategies for each state. These all have sane defaults,
-	// override them only if necessary.
-	DiscoverBackoff    backoff.BackOff
-	AcceptOfferBackoff backoff.BackOff
-	RenewBackoff       backoff.BackOff
-	RebindBackoff      backoff.BackOff
-
-	state state
-
-	iface *net.Interface
-
-	// now can be used to override time for testing
-	now func() time.Time
-
-	// LeaseCallback is called every time a lease is aquired, renewed or lost
-	LeaseCallback LeaseCallback
-
-	// Valid in states Discovering, Requesting, Rebinding
-	broadcastConn BroadcastTransport
-
-	// Valid in states Requesting
-	offer *dhcpv4.DHCPv4
-
-	// Valid in states Bound, Renewing
-	unicastConn UnicastTransport
-
-	// Valid in states Bound, Renewing, Rebinding
-	lease              *dhcpv4.DHCPv4
-	leaseDeadline      time.Time
-	leaseBoundDeadline time.Time
-	leaseRenewDeadline time.Time
-}
-
-// defaultBackoffOpts can be passed to NewExponentialBackOff and configures it
-// to retry infinitely and use a DHCP-appropriate InitialInterval.
-func defaultBackoffOpts(b *backoff.ExponentialBackOff) {
-	b.MaxElapsedTime = 0 // No Timeout
-	// Lots of servers wait 1s for existing users of an IP. Wait at least for
-	// that and keep some slack for randomization, communication and processing
-	// overhead.
-	b.InitialInterval = 1400 * time.Millisecond
-	b.MaxInterval = 30 * time.Second
-	b.RandomizationFactor = 0.2
-}
-
-// NewClient instantiates (but doesn't start) a new DHCPv4 client.
-// To have a working client it's required to set LeaseCallback to something
-// that is capable of configuring the IP address on the given interface. Unless
-// managed through external means like a routing protocol, setting the default
-// route is also required. A simple example with the callback package thus
-// looks like this:
-//
-//	c := dhcp4c.NewClient(yourInterface)
-//	c.LeaseCallback = callback.Compose(callback.ManageIP(yourInterface), callback.ManageDefaultRoute(yourInterface))
-//	c.Run(ctx)
-func NewClient(iface *net.Interface) (*Client, error) {
-	broadcastConn := transport.NewBroadcastTransport(iface)
-
-	// broadcastConn needs to be open in stateDiscovering
-	if err := broadcastConn.Open(); err != nil {
-		return nil, fmt.Errorf("failed to create DHCP broadcast transport: %w", err)
-	}
-
-	discoverBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts)
-
-	acceptOfferBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts,
-		// Abort after 30s and go back to discovering
-		backoff.WithMaxElapsedTime(30*time.Second))
-
-	renewBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts,
-		// Increase maximum interval to reduce chatter when the server is down
-		backoff.WithMaxInterval(5*time.Minute))
-
-	rebindBackoff := backoff.NewExponentialBackOff(defaultBackoffOpts,
-		// Increase maximum interval to reduce chatter when the server is down
-		backoff.WithMaxInterval(5*time.Minute))
-
-	// Check if the hardware address contains at least one non-zero value.
-	// This exists to catch undefined/non-supplied hardware address values,
-	// it does not check for L2 protocol-specific hardware address constraints.
-	hasValidHWAddr := false
-	for _, b := range iface.HardwareAddr {
-		if b != 0x00 {
-			hasValidHWAddr = true
-			break
-		}
-	}
-	if !hasValidHWAddr {
-		return nil, fmt.Errorf("iface HardwareAddr is invalid (only zeroes or invalid length): %x", iface.HardwareAddr)
-	}
-
-	return &Client{
-		state:              stateDiscovering,
-		broadcastConn:      broadcastConn,
-		unicastConn:        transport.NewUnicastTransport(iface),
-		iface:              iface,
-		RequestedOptions:   dhcpv4.OptionCodeList{},
-		now:                time.Now,
-		DiscoverBackoff:    discoverBackoff,
-		AcceptOfferBackoff: acceptOfferBackoff,
-		RenewBackoff:       renewBackoff,
-		RebindBackoff:      rebindBackoff,
-	}, nil
-}
-
-// acceptableLease checks if the given lease is valid enough to even be
-// processed. This is intentionally not exposed to users because under certain
-// cirumstances it can end up acquiring all available IP addresses from a
-// server.
-func (c *Client) acceptableLease(offer *dhcpv4.DHCPv4) bool {
-	// RFC2131 Section 4.3.1 Table 3
-	if offer.ServerIdentifier() == nil || offer.ServerIdentifier().To4() == nil {
-		return false
-	}
-	// RFC2131 Section 4.3.1 Table 3
-	// Minimum representable lease time is 1s (Section 1.1)
-	if offer.IPAddressLeaseTime(0) < 1*time.Second {
-		return false
-	}
-
-	// Ignore IPs that are in no way valid for an interface (multicast,
-	// loopback, ...)
-	if offer.YourIPAddr.To4() == nil || (!offer.YourIPAddr.IsGlobalUnicast() && !offer.YourIPAddr.IsLinkLocalUnicast()) {
-		return false
-	}
-
-	// Technically the options Requested IP address, Parameter request list,
-	// Client identifier and Maximum message size should be refused (MUST NOT),
-	// but in the interest of interopatibilty let's simply remove them if they
-	// are present.
-	delete(offer.Options, dhcpv4.OptionRequestedIPAddress.Code())
-	delete(offer.Options, dhcpv4.OptionParameterRequestList.Code())
-	delete(offer.Options, dhcpv4.OptionClientIdentifier.Code())
-	delete(offer.Options, dhcpv4.OptionMaximumDHCPMessageSize.Code())
-
-	// Clamp rebindinding times longer than the lease time. Otherwise the state
-	// machine might misbehave.
-	if offer.IPAddressRebindingTime(0) > offer.IPAddressLeaseTime(0) {
-		offer.UpdateOption(dhcpv4.OptGeneric(dhcpv4.OptionRebindingTimeValue, dhcpv4.Duration(offer.IPAddressLeaseTime(0)).ToBytes()))
-	}
-	// Clamp renewal times longer than the rebinding time. Otherwise the state
-	// machine might misbehave.
-	if offer.IPAddressRenewalTime(0) > offer.IPAddressRebindingTime(0) {
-		offer.UpdateOption(dhcpv4.OptGeneric(dhcpv4.OptionRenewTimeValue, dhcpv4.Duration(offer.IPAddressRebindingTime(0)).ToBytes()))
-	}
-
-	// Normalize two options that can be represented either inline or as
-	// options.
-	if len(offer.ServerHostName) > 0 {
-		offer.Options[uint8(dhcpv4.OptionTFTPServerName)] = []byte(offer.ServerHostName)
-	}
-	if len(offer.BootFileName) > 0 {
-		offer.Options[uint8(dhcpv4.OptionBootfileName)] = []byte(offer.BootFileName)
-	}
-
-	// Normalize siaddr to option 150 (see RFC5859)
-	if len(offer.GetOneOption(dhcpv4.OptionTFTPServerAddress)) == 0 {
-		if offer.ServerIPAddr.To4() != nil && (offer.ServerIPAddr.IsGlobalUnicast() || offer.ServerIPAddr.IsLinkLocalUnicast()) {
-			offer.Options[uint8(dhcpv4.OptionTFTPServerAddress)] = offer.ServerIPAddr.To4()
-		}
-	}
-
-	return true
-}
-
-func earliestDeadline(dl1, dl2 time.Time) time.Time {
-	if dl1.Before(dl2) {
-		return dl1
-	} else {
-		return dl2
-	}
-}
-
-// newXID generates a new transaction ID
-func (c *Client) newXID() (dhcpv4.TransactionID, error) {
-	var xid dhcpv4.TransactionID
-	if _, err := io.ReadFull(rand.Reader, xid[:]); err != nil {
-		return xid, fmt.Errorf("cannot read randomness for transaction ID: %w", err)
-	}
-	return xid, nil
-}
-
-// As most servers out there cannot do reassembly, let's just hope for the best
-// and provide the local interface MTU. If the packet is too big it won't work
-// anyways.  Also clamp to the biggest representable MTU in DHCPv4 (2 bytes
-// unsigned int).
-func (c *Client) maxMsgSize() uint16 {
-	if c.iface.MTU < math.MaxUint16 {
-		return uint16(c.iface.MTU)
-	} else {
-		return math.MaxUint16
-	}
-}
-
-// newMsg creates a new DHCP message of a given type and adds common options.
-func (c *Client) newMsg(t dhcpv4.MessageType) (*dhcpv4.DHCPv4, error) {
-	xid, err := c.newXID()
-	if err != nil {
-		return nil, err
-	}
-	opts := make(dhcpv4.Options)
-	opts.Update(dhcpv4.OptMessageType(t))
-	if len(c.ClientIdentifier) > 0 {
-		opts.Update(dhcpv4.OptClientIdentifier(c.ClientIdentifier))
-	}
-	if t == dhcpv4.MessageTypeDiscover || t == dhcpv4.MessageTypeRequest || t == dhcpv4.MessageTypeInform {
-		opts.Update(dhcpv4.OptParameterRequestList(append(append(dhcpv4.OptionCodeList(nil), c.RequestedOptions...), internalOptions...)...))
-		opts.Update(dhcpv4.OptMaxMessageSize(c.maxMsgSize()))
-		if c.VendorClassIdentifier != "" {
-			opts.Update(dhcpv4.OptClassIdentifier(c.VendorClassIdentifier))
-		}
-		for opt, val := range c.ExtraRequestOptions {
-			opts[opt] = val
-		}
-	}
-	return &dhcpv4.DHCPv4{
-		OpCode:        dhcpv4.OpcodeBootRequest,
-		HWType:        iana.HWTypeEthernet,
-		ClientHWAddr:  c.iface.HardwareAddr,
-		HopCount:      0,
-		TransactionID: xid,
-		NumSeconds:    0,
-		Flags:         0,
-		ClientIPAddr:  net.IPv4zero,
-		YourIPAddr:    net.IPv4zero,
-		ServerIPAddr:  net.IPv4zero,
-		GatewayIPAddr: net.IPv4zero,
-		Options:       opts,
-	}, nil
-}
-
-// transactionStateSpec describes a state which is driven by a DHCP message
-// transaction (sending a specific message and then transitioning into a
-// different state depending on the received messages)
-type transactionStateSpec struct {
-	// ctx is a context for canceling the process
-	ctx context.Context
-
-	// transport is used to send and receive messages in this state
-	transport Transport
-
-	// stateDeadline is a fixed external deadline for how long the FSM can
-	// remain in this state.
-	// If it's exceeded the stateDeadlineExceeded callback is called and
-	// responsible for transitioning out of this state. It can be left empty to
-	// signal that there's no external deadline for the state.
-	stateDeadline time.Time
-
-	// backoff controls how long to wait for answers until handing control back
-	// to the FSM.
-	// Since the FSM hasn't advanced until then this means we just get called
-	// again and retransmit.
-	backoff backoff.BackOff
-
-	// requestType is the type of DHCP request sent out in this state. This is
-	// used to populate the default options for the message.
-	requestType dhcpv4.MessageType
-
-	// setExtraOptions can modify the request and set extra options before
-	// transmitting. Returning an error here aborts the FSM an can be used to
-	// terminate when no valid request can be constructed.
-	setExtraOptions func(msg *dhcpv4.DHCPv4) error
-
-	// handleMessage gets called for every parseable (not necessarily valid)
-	// DHCP message received by the transport. It should return an error for
-	// every message that doesn't advance the state machine and no error for
-	// every one that does. It is responsible for advancing the FSM if the
-	// required information is present.
-	handleMessage func(msg *dhcpv4.DHCPv4, sentTime time.Time) error
-
-	// stateDeadlineExceeded gets called if either the backoff returns
-	// backoff.Stop or the stateDeadline runs out. It is responsible for
-	// advancing the FSM into the next state.
-	stateDeadlineExceeded func() error
-}
-
-func (c *Client) runTransactionState(s transactionStateSpec) error {
-	sentTime := c.now()
-	msg, err := c.newMsg(s.requestType)
-	if err != nil {
-		return fmt.Errorf("failed to get new DHCP message: %w", err)
-	}
-	if err := s.setExtraOptions(msg); err != nil {
-		return fmt.Errorf("failed to create DHCP message: %w", err)
-	}
-
-	wait := s.backoff.NextBackOff()
-	if wait == backoff.Stop {
-		return s.stateDeadlineExceeded()
-	}
-
-	receiveDeadline := sentTime.Add(wait)
-	if !s.stateDeadline.IsZero() {
-		receiveDeadline = earliestDeadline(s.stateDeadline, receiveDeadline)
-
-		// Jump out if deadline expires in less than 10ms. Minimum lease time is 1s
-		// and if we have less than 10ms to wait for an answer before switching
-		// state it makes no sense to send out another request. This nearly
-		// eliminates the problem of sending two different requests back-to-back.
-		if s.stateDeadline.Add(-10 * time.Millisecond).Before(sentTime) {
-			return s.stateDeadlineExceeded()
-		}
-	}
-
-	if err := s.transport.Send(msg); err != nil {
-		return fmt.Errorf("failed to send message: %w", err)
-	}
-
-	if err := s.transport.SetReceiveDeadline(receiveDeadline); err != nil {
-		return fmt.Errorf("failed to set deadline: %w", err)
-	}
-
-	for {
-		offer, err := s.transport.Receive()
-		select {
-		case <-s.ctx.Done():
-			c.cleanup()
-			return s.ctx.Err()
-		default:
-		}
-		if errors.Is(err, transport.ErrDeadlineExceeded) {
-			return nil
-		}
-		var e transport.InvalidMessageError
-		if errors.As(err, &e) {
-			// Packet couldn't be read. Maybe log at some point in the future.
-			continue
-		}
-		if err != nil {
-			return fmt.Errorf("failed to receive packet: %w", err)
-		}
-		if offer.TransactionID != msg.TransactionID { // Not our transaction
-			continue
-		}
-		err = s.handleMessage(offer, sentTime)
-		if err == nil {
-			return nil
-		} else if !errors.Is(err, ErrInvalidMsg) {
-			return err
-		}
-	}
-}
-
-var ErrInvalidMsg = errors.New("invalid message")
-
-func (c *Client) runState(ctx context.Context) error {
-	switch c.state {
-	case stateDiscovering:
-		return c.runTransactionState(transactionStateSpec{
-			ctx:         ctx,
-			transport:   c.broadcastConn,
-			backoff:     c.DiscoverBackoff,
-			requestType: dhcpv4.MessageTypeDiscover,
-			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
-				msg.UpdateOption(dhcpv4.OptGeneric(dhcpv4.OptionRapidCommit, []byte{}))
-				return nil
-			},
-			handleMessage: func(offer *dhcpv4.DHCPv4, sentTime time.Time) error {
-				switch offer.MessageType() {
-				case dhcpv4.MessageTypeOffer:
-					if c.acceptableLease(offer) {
-						c.offer = offer
-						c.AcceptOfferBackoff.Reset()
-						c.state = stateRequesting
-						return nil
-					}
-				case dhcpv4.MessageTypeAck:
-					if c.acceptableLease(offer) {
-						return c.transitionToBound(offer, sentTime)
-					}
-				}
-				return ErrInvalidMsg
-			},
-		})
-	case stateRequesting:
-		return c.runTransactionState(transactionStateSpec{
-			ctx:         ctx,
-			transport:   c.broadcastConn,
-			backoff:     c.AcceptOfferBackoff,
-			requestType: dhcpv4.MessageTypeRequest,
-			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
-				msg.UpdateOption(dhcpv4.OptServerIdentifier(c.offer.ServerIdentifier()))
-				msg.TransactionID = c.offer.TransactionID
-				msg.UpdateOption(dhcpv4.OptRequestedIPAddress(c.offer.YourIPAddr))
-				return nil
-			},
-			handleMessage: func(msg *dhcpv4.DHCPv4, sentTime time.Time) error {
-				switch msg.MessageType() {
-				case dhcpv4.MessageTypeAck:
-					if c.acceptableLease(msg) {
-						return c.transitionToBound(msg, sentTime)
-					}
-				case dhcpv4.MessageTypeNak:
-					c.requestingToDiscovering()
-					return nil
-				}
-				return ErrInvalidMsg
-			},
-			stateDeadlineExceeded: func() error {
-				c.requestingToDiscovering()
-				return nil
-			},
-		})
-	case stateBound:
-		select {
-		case <-time.After(c.leaseBoundDeadline.Sub(c.now())):
-			c.state = stateRenewing
-			c.RenewBackoff.Reset()
-			return nil
-		case <-ctx.Done():
-			c.cleanup()
-			return ctx.Err()
-		}
-	case stateRenewing:
-		return c.runTransactionState(transactionStateSpec{
-			ctx:           ctx,
-			transport:     c.unicastConn,
-			backoff:       c.RenewBackoff,
-			requestType:   dhcpv4.MessageTypeRequest,
-			stateDeadline: c.leaseRenewDeadline,
-			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
-				msg.ClientIPAddr = c.lease.YourIPAddr
-				return nil
-			},
-			handleMessage: func(ack *dhcpv4.DHCPv4, sentTime time.Time) error {
-				switch ack.MessageType() {
-				case dhcpv4.MessageTypeAck:
-					if c.acceptableLease(ack) {
-						return c.transitionToBound(ack, sentTime)
-					}
-				case dhcpv4.MessageTypeNak:
-					return c.leaseToDiscovering()
-				}
-				return ErrInvalidMsg
-			},
-			stateDeadlineExceeded: func() error {
-				c.state = stateRebinding
-				if err := c.switchToBroadcast(); err != nil {
-					return fmt.Errorf("failed to switch to broadcast: %w", err)
-				}
-				c.RebindBackoff.Reset()
-				return nil
-			},
-		})
-	case stateRebinding:
-		return c.runTransactionState(transactionStateSpec{
-			ctx:           ctx,
-			transport:     c.broadcastConn,
-			backoff:       c.RebindBackoff,
-			stateDeadline: c.leaseDeadline,
-			requestType:   dhcpv4.MessageTypeRequest,
-			setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
-				msg.ClientIPAddr = c.lease.YourIPAddr
-				return nil
-			},
-			handleMessage: func(ack *dhcpv4.DHCPv4, sentTime time.Time) error {
-				switch ack.MessageType() {
-				case dhcpv4.MessageTypeAck:
-					if c.acceptableLease(ack) {
-						return c.transitionToBound(ack, sentTime)
-					}
-				case dhcpv4.MessageTypeNak:
-					return c.leaseToDiscovering()
-				}
-				return ErrInvalidMsg
-			},
-			stateDeadlineExceeded: func() error {
-				return c.leaseToDiscovering()
-			},
-		})
-	}
-	return errors.New("state machine in invalid state")
-}
-
-func (c *Client) Run(ctx context.Context) error {
-	if c.LeaseCallback == nil {
-		panic("LeaseCallback must be set before calling Run")
-	}
-	logger := supervisor.Logger(ctx)
-	for {
-		oldState := c.state
-		if err := c.runState(ctx); err != nil {
-			return err
-		}
-		if c.state != oldState {
-			logger.Infof("%s => %s", oldState, c.state)
-		}
-	}
-}
-
-func (c *Client) cleanup() {
-	c.unicastConn.Close()
-	if c.lease != nil {
-		c.LeaseCallback(nil)
-	}
-	c.broadcastConn.Close()
-}
-
-func (c *Client) requestingToDiscovering() {
-	c.offer = nil
-	c.DiscoverBackoff.Reset()
-	c.state = stateDiscovering
-}
-
-func (c *Client) leaseToDiscovering() error {
-	if c.state == stateRenewing {
-		if err := c.switchToBroadcast(); err != nil {
-			return err
-		}
-	}
-	c.state = stateDiscovering
-	c.lease = nil
-	c.DiscoverBackoff.Reset()
-	if err := c.LeaseCallback(nil); err != nil {
-		return fmt.Errorf("lease callback failed: %w", err)
-	}
-	return nil
-}
-
-func leaseFromAck(ack *dhcpv4.DHCPv4, expiresAt time.Time) *Lease {
-	if ack == nil {
-		return nil
-	}
-	return &Lease{Options: ack.Options, AssignedIP: ack.YourIPAddr, ExpiresAt: expiresAt}
-}
-
-func (c *Client) transitionToBound(ack *dhcpv4.DHCPv4, sentTime time.Time) error {
-	// Guaranteed to exist, leases without a lease time are filtered
-	leaseTime := ack.IPAddressLeaseTime(0)
-	c.leaseDeadline = sentTime.Add(leaseTime)
-	c.leaseBoundDeadline = sentTime.Add(ack.IPAddressRenewalTime(time.Duration(float64(leaseTime) * 0.5)))
-	c.leaseRenewDeadline = sentTime.Add(ack.IPAddressRebindingTime(time.Duration(float64(leaseTime) * 0.85)))
-
-	if err := c.LeaseCallback(leaseFromAck(ack, c.leaseDeadline)); err != nil {
-		return fmt.Errorf("lease callback failed: %w", err)
-	}
-
-	if c.state != stateRenewing {
-		if err := c.switchToUnicast(ack.ServerIdentifier(), ack.YourIPAddr); err != nil {
-			return fmt.Errorf("failed to switch transports: %w", err)
-		}
-	}
-	c.state = stateBound
-	c.lease = ack
-	return nil
-}
-
-func (c *Client) switchToUnicast(serverIP, bindIP net.IP) error {
-	if err := c.broadcastConn.Close(); err != nil {
-		return fmt.Errorf("failed to close broadcast transport: %w", err)
-	}
-	if err := c.unicastConn.Open(serverIP, bindIP); err != nil {
-		return fmt.Errorf("failed to open unicast transport: %w", err)
-	}
-	return nil
-}
-
-func (c *Client) switchToBroadcast() error {
-	if err := c.unicastConn.Close(); err != nil {
-		return fmt.Errorf("failed to close unicast transport: %w", err)
-	}
-	if err := c.broadcastConn.Open(); err != nil {
-		return fmt.Errorf("failed to open broadcast transport: %w", err)
-	}
-	return nil
-}
diff --git a/metropolis/node/core/network/dhcp4c/dhcpc_test.go b/metropolis/node/core/network/dhcp4c/dhcpc_test.go
deleted file mode 100644
index 57361fe..0000000
--- a/metropolis/node/core/network/dhcp4c/dhcpc_test.go
+++ /dev/null
@@ -1,501 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-package dhcp4c
-
-import (
-	"context"
-	"fmt"
-	"net"
-	"testing"
-	"time"
-
-	"github.com/cenkalti/backoff/v4"
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"github.com/stretchr/testify/assert"
-
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c/transport"
-)
-
-type fakeTime struct {
-	time time.Time
-}
-
-func newFakeTime(t time.Time) *fakeTime {
-	return &fakeTime{
-		time: t,
-	}
-}
-
-func (ft *fakeTime) Now() time.Time {
-	return ft.time
-}
-
-func (ft *fakeTime) Advance(d time.Duration) {
-	ft.time = ft.time.Add(d)
-}
-
-type mockTransport struct {
-	sentPacket     *dhcpv4.DHCPv4
-	sendError      error
-	setDeadline    time.Time
-	receivePackets []*dhcpv4.DHCPv4
-	receiveError   error
-	receiveIdx     int
-	closed         bool
-}
-
-func (mt *mockTransport) sendPackets(pkts ...*dhcpv4.DHCPv4) {
-	mt.receiveIdx = 0
-	mt.receivePackets = pkts
-}
-
-func (mt *mockTransport) Open() error {
-	mt.closed = false
-	return nil
-}
-
-func (mt *mockTransport) Send(payload *dhcpv4.DHCPv4) error {
-	mt.sentPacket = payload
-	return mt.sendError
-}
-
-func (mt *mockTransport) Receive() (*dhcpv4.DHCPv4, error) {
-	if mt.receiveError != nil {
-		return nil, mt.receiveError
-	}
-	if len(mt.receivePackets) > mt.receiveIdx {
-		packet := mt.receivePackets[mt.receiveIdx]
-		packet, err := dhcpv4.FromBytes(packet.ToBytes()) // Clone packet
-		if err != nil {
-			panic("ToBytes => FromBytes failed")
-		}
-		packet.TransactionID = mt.sentPacket.TransactionID
-		mt.receiveIdx++
-		return packet, nil
-	}
-	return nil, transport.ErrDeadlineExceeded
-}
-
-func (mt *mockTransport) SetReceiveDeadline(t time.Time) error {
-	mt.setDeadline = t
-	return nil
-}
-
-func (mt *mockTransport) Close() error {
-	mt.closed = true
-	return nil
-}
-
-type unicastMockTransport struct {
-	mockTransport
-	serverIP net.IP
-	bindIP   net.IP
-}
-
-func (umt *unicastMockTransport) Open(serverIP, bindIP net.IP) error {
-	if umt.serverIP != nil {
-		panic("double-open of unicast transport")
-	}
-	umt.serverIP = serverIP
-	umt.bindIP = bindIP
-	return nil
-}
-
-func (umt *unicastMockTransport) Close() error {
-	umt.serverIP = nil
-	umt.bindIP = nil
-	return umt.mockTransport.Close()
-}
-
-type mockBackoff struct {
-	indefinite bool
-	values     []time.Duration
-	idx        int
-}
-
-func newMockBackoff(vals []time.Duration, indefinite bool) *mockBackoff {
-	return &mockBackoff{values: vals, indefinite: indefinite}
-}
-
-func (mb *mockBackoff) NextBackOff() time.Duration {
-	if mb.idx < len(mb.values) || mb.indefinite {
-		val := mb.values[mb.idx%len(mb.values)]
-		mb.idx++
-		return val
-	}
-	return backoff.Stop
-}
-
-func (mb *mockBackoff) Reset() {
-	mb.idx = 0
-}
-
-func TestClient_runTransactionState(t *testing.T) {
-	ft := newFakeTime(time.Date(2020, 10, 28, 15, 02, 32, 352, time.UTC))
-	c := Client{
-		now:   ft.Now,
-		iface: &net.Interface{MTU: 9324, HardwareAddr: net.HardwareAddr{0x12, 0x23, 0x34, 0x45, 0x56, 0x67}},
-	}
-	mt := &mockTransport{}
-	err := c.runTransactionState(transactionStateSpec{
-		ctx:         context.Background(),
-		transport:   mt,
-		backoff:     newMockBackoff([]time.Duration{1 * time.Second}, true),
-		requestType: dhcpv4.MessageTypeDiscover,
-		setExtraOptions: func(msg *dhcpv4.DHCPv4) error {
-			msg.UpdateOption(dhcpv4.OptDomainName("just.testing.invalid"))
-			return nil
-		},
-		handleMessage: func(msg *dhcpv4.DHCPv4, sentTime time.Time) error {
-			return nil
-		},
-		stateDeadlineExceeded: func() error {
-			panic("shouldn't be called")
-		},
-	})
-	assert.NoError(t, err)
-	assert.Equal(t, "just.testing.invalid", mt.sentPacket.DomainName())
-	assert.Equal(t, dhcpv4.MessageTypeDiscover, mt.sentPacket.MessageType())
-}
-
-// TestAcceptableLease tests if a minimal valid lease is accepted by
-// acceptableLease
-func TestAcceptableLease(t *testing.T) {
-	var c Client
-	offer := &dhcpv4.DHCPv4{
-		OpCode: dhcpv4.OpcodeBootReply,
-	}
-	offer.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeOffer))
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
-	offer.YourIPAddr = net.IP{192, 0, 2, 2}
-	assert.True(t, c.acceptableLease(offer), "Valid lease is not acceptable")
-}
-
-type dhcpClientPuppet struct {
-	ft  *fakeTime
-	bmt *mockTransport
-	umt *unicastMockTransport
-	c   *Client
-}
-
-func newPuppetClient(initState state) *dhcpClientPuppet {
-	ft := newFakeTime(time.Date(2020, 10, 28, 15, 02, 32, 352, time.UTC))
-	bmt := &mockTransport{}
-	umt := &unicastMockTransport{}
-	c := &Client{
-		state:              initState,
-		now:                ft.Now,
-		iface:              &net.Interface{MTU: 9324, HardwareAddr: net.HardwareAddr{0x12, 0x23, 0x34, 0x45, 0x56, 0x67}},
-		broadcastConn:      bmt,
-		unicastConn:        umt,
-		DiscoverBackoff:    newMockBackoff([]time.Duration{1 * time.Second}, true),
-		AcceptOfferBackoff: newMockBackoff([]time.Duration{1 * time.Second, 2 * time.Second}, false),
-		RenewBackoff:       newMockBackoff([]time.Duration{1 * time.Second}, true),
-		RebindBackoff:      newMockBackoff([]time.Duration{1 * time.Second}, true),
-	}
-	return &dhcpClientPuppet{
-		ft:  ft,
-		bmt: bmt,
-		umt: umt,
-		c:   c,
-	}
-}
-
-func newResponse(m dhcpv4.MessageType) *dhcpv4.DHCPv4 {
-	o := &dhcpv4.DHCPv4{
-		OpCode: dhcpv4.OpcodeBootReply,
-	}
-	o.UpdateOption(dhcpv4.OptMessageType(m))
-	return o
-}
-
-// TestDiscoverOffer tests if the DHCP state machine in discovering state
-// properly selects the first valid lease and transitions to requesting state
-func TestDiscoverRequesting(t *testing.T) {
-	p := newPuppetClient(stateDiscovering)
-
-	// A minimal valid lease
-	offer := newResponse(dhcpv4.MessageTypeOffer)
-	testIP := net.IP{192, 0, 2, 2}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
-	offer.YourIPAddr = testIP
-
-	// Intentionally bad offer with no lease time.
-	terribleOffer := newResponse(dhcpv4.MessageTypeOffer)
-	terribleOffer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 2}))
-	terribleOffer.YourIPAddr = net.IPv4(192, 0, 2, 2)
-
-	// Send the bad offer first, then the valid offer
-	p.bmt.sendPackets(terribleOffer, offer)
-
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, stateRequesting, p.c.state, "DHCP client didn't process offer")
-	assert.Equal(t, testIP, p.c.offer.YourIPAddr, "DHCP client requested invalid offer")
-}
-
-// TestOfferBound tests if the DHCP state machine in requesting state processes
-// a valid DHCPACK and transitions to bound state.
-func TestRequestingBound(t *testing.T) {
-	p := newPuppetClient(stateRequesting)
-
-	offer := newResponse(dhcpv4.MessageTypeAck)
-	testIP := net.IP{192, 0, 2, 2}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
-	offer.YourIPAddr = testIP
-
-	p.bmt.sendPackets(offer)
-	p.c.offer = offer
-	p.c.LeaseCallback = func(lease *Lease) error {
-		assert.Equal(t, testIP, lease.AssignedIP, "new lease has wrong IP")
-		return nil
-	}
-
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't process offer")
-	assert.Equal(t, testIP, p.c.lease.YourIPAddr, "DHCP client requested invalid offer")
-}
-
-// TestRequestingDiscover tests if the DHCP state machine in requesting state
-// transitions back to discovering if it takes too long to get a valid DHCPACK.
-func TestRequestingDiscover(t *testing.T) {
-	p := newPuppetClient(stateRequesting)
-
-	offer := newResponse(dhcpv4.MessageTypeOffer)
-	testIP := net.IP{192, 0, 2, 2}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(10 * time.Second))
-	offer.YourIPAddr = testIP
-	p.c.offer = offer
-
-	for i := 0; i < 10; i++ {
-		p.bmt.sendPackets()
-		if err := p.c.runState(context.Background()); err != nil {
-			t.Fatal(err)
-		}
-		assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType(), "Invalid message type for requesting")
-		if p.c.state == stateDiscovering {
-			break
-		}
-		p.ft.time = p.bmt.setDeadline
-
-		if i == 9 {
-			t.Fatal("Too many tries while requesting, backoff likely wrong")
-		}
-	}
-	assert.Equal(t, stateDiscovering, p.c.state, "DHCP client didn't switch back to offer after requesting expired")
-}
-
-// TestDiscoverRapidCommit tests if the DHCP state machine in discovering state
-// transitions directly to bound if a rapid commit response (DHCPACK) is
-// received.
-func TestDiscoverRapidCommit(t *testing.T) {
-	testIP := net.IP{192, 0, 2, 2}
-	offer := newResponse(dhcpv4.MessageTypeAck)
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 0, 2, 1}))
-	leaseTime := 10 * time.Second
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
-	offer.YourIPAddr = testIP
-
-	p := newPuppetClient(stateDiscovering)
-	p.c.LeaseCallback = func(lease *Lease) error {
-		assert.Equal(t, testIP, lease.AssignedIP, "callback called with wrong IP")
-		assert.Equal(t, p.ft.Now().Add(leaseTime), lease.ExpiresAt, "invalid ExpiresAt")
-		return nil
-	}
-	p.bmt.sendPackets(offer)
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't process offer")
-	assert.Equal(t, testIP, p.c.lease.YourIPAddr, "DHCP client requested invalid offer")
-	assert.Equal(t, 5*time.Second, p.c.leaseBoundDeadline.Sub(p.ft.Now()), "Renewal time was incorrectly defaulted")
-}
-
-type TestOption uint8
-
-func (o TestOption) Code() uint8 {
-	return uint8(o) + 224 // Private options
-}
-func (o TestOption) String() string {
-	return fmt.Sprintf("Test Option %d", uint8(o))
-}
-
-// TestBoundRenewingBound tests if the DHCP state machine in bound correctly
-// transitions to renewing after leaseBoundDeadline expires, sends a
-// DHCPREQUEST and after it gets a DHCPACK response calls LeaseCallback and
-// transitions back to bound with correct new deadlines.
-func TestBoundRenewingBound(t *testing.T) {
-	offer := newResponse(dhcpv4.MessageTypeAck)
-	testIP := net.IP{192, 0, 2, 2}
-	serverIP := net.IP{192, 0, 2, 1}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
-	leaseTime := 10 * time.Second
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
-	offer.YourIPAddr = testIP
-
-	p := newPuppetClient(stateBound)
-	p.umt.Open(serverIP, testIP)
-	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
-	// Other deadlines are intentionally empty to make sure they aren't used
-	p.c.leaseRenewDeadline = p.ft.Now().Add(8500 * time.Millisecond)
-	p.c.leaseBoundDeadline = p.ft.Now().Add(5000 * time.Millisecond)
-
-	p.ft.Advance(5*time.Second - 5*time.Millisecond)
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	// We cannot intercept time.After so we just advance the clock by the time slept
-	p.ft.Advance(5 * time.Millisecond)
-	assert.Equal(t, stateRenewing, p.c.state, "DHCP client not renewing")
-	offer.UpdateOption(dhcpv4.OptGeneric(TestOption(1), []byte{0x12}))
-	p.umt.sendPackets(offer)
-	p.c.LeaseCallback = func(lease *Lease) error {
-		assert.Equal(t, testIP, lease.AssignedIP, "callback called with wrong IP")
-		assert.Equal(t, p.ft.Now().Add(leaseTime), lease.ExpiresAt, "invalid ExpiresAt")
-		assert.Equal(t, []byte{0x12}, lease.Options.Get(TestOption(1)), "renewal didn't add new option")
-		return nil
-	}
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't renew")
-	assert.Equal(t, p.ft.Now().Add(leaseTime), p.c.leaseDeadline, "lease deadline not updated")
-	assert.Equal(t, dhcpv4.MessageTypeRequest, p.umt.sentPacket.MessageType(), "Invalid message type for renewal")
-}
-
-// TestRenewingRebinding tests if the DHCP state machine in renewing state
-// correctly sends DHCPREQUESTs and transitions to the rebinding state when it
-// hasn't received a valid response until the deadline expires.
-func TestRenewingRebinding(t *testing.T) {
-	offer := newResponse(dhcpv4.MessageTypeAck)
-	testIP := net.IP{192, 0, 2, 2}
-	serverIP := net.IP{192, 0, 2, 1}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
-	leaseTime := 10 * time.Second
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
-	offer.YourIPAddr = testIP
-
-	p := newPuppetClient(stateRenewing)
-	p.umt.Open(serverIP, testIP)
-	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
-	// Other deadlines are intentionally empty to make sure they aren't used
-	p.c.leaseRenewDeadline = p.ft.Now().Add(8500 * time.Millisecond)
-	p.c.leaseDeadline = p.ft.Now().Add(10000 * time.Millisecond)
-
-	startTime := p.ft.Now()
-	p.ft.Advance(5 * time.Second)
-
-	p.c.LeaseCallback = func(*Lease) error {
-		t.Fatal("Lease callback called without valid offer")
-		return nil
-	}
-
-	for i := 0; i < 10; i++ {
-		p.umt.sendPackets()
-		if err := p.c.runState(context.Background()); err != nil {
-			t.Fatal(err)
-		}
-		assert.Equal(t, dhcpv4.MessageTypeRequest, p.umt.sentPacket.MessageType(), "Invalid message type for renewal")
-		p.ft.time = p.umt.setDeadline
-
-		if p.c.state == stateRebinding {
-			break
-		}
-		if i == 9 {
-			t.Fatal("Too many tries while renewing, backoff likely wrong")
-		}
-	}
-	assert.Equal(t, startTime.Add(8500*time.Millisecond), p.umt.setDeadline, "wrong listen deadline when renewing")
-	assert.Equal(t, stateRebinding, p.c.state, "DHCP client not renewing")
-	assert.False(t, p.bmt.closed)
-	assert.True(t, p.umt.closed)
-}
-
-// TestRebindingBound tests if the DHCP state machine in rebinding state sends
-// DHCPREQUESTs to the network and if it receives a valid DHCPACK correctly
-// transitions back to bound state.
-func TestRebindingBound(t *testing.T) {
-	offer := newResponse(dhcpv4.MessageTypeAck)
-	testIP := net.IP{192, 0, 2, 2}
-	serverIP := net.IP{192, 0, 2, 1}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
-	leaseTime := 10 * time.Second
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
-	offer.YourIPAddr = testIP
-
-	p := newPuppetClient(stateRebinding)
-	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
-	// Other deadlines are intentionally empty to make sure they aren't used
-	p.c.leaseDeadline = p.ft.Now().Add(10000 * time.Millisecond)
-
-	p.ft.Advance(9 * time.Second)
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType(), "DHCP rebind sent invalid message type")
-	assert.Equal(t, stateRebinding, p.c.state, "DHCP client transferred out of rebinding state without trigger")
-	offer.UpdateOption(dhcpv4.OptGeneric(TestOption(1), []byte{0x12})) // Mark answer
-	p.bmt.sendPackets(offer)
-	p.bmt.sentPacket = nil
-	p.c.LeaseCallback = func(lease *Lease) error {
-		assert.Equal(t, testIP, lease.AssignedIP, "callback called with wrong IP")
-		assert.Equal(t, p.ft.Now().Add(leaseTime), lease.ExpiresAt, "invalid ExpiresAt")
-		assert.Equal(t, []byte{0x12}, lease.Options.Get(TestOption(1)), "renewal didn't add new option")
-		return nil
-	}
-	if err := p.c.runState(context.Background()); err != nil {
-		t.Fatal(err)
-	}
-	assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType())
-	assert.Equal(t, stateBound, p.c.state, "DHCP client didn't go back to bound")
-}
-
-// TestRebindingBound tests if the DHCP state machine in rebinding state
-// transitions to discovering state if leaseDeadline expires and calls
-// LeaseCallback with an empty new lease.
-func TestRebindingDiscovering(t *testing.T) {
-	offer := newResponse(dhcpv4.MessageTypeAck)
-	testIP := net.IP{192, 0, 2, 2}
-	serverIP := net.IP{192, 0, 2, 1}
-	offer.UpdateOption(dhcpv4.OptServerIdentifier(serverIP))
-	leaseTime := 10 * time.Second
-	offer.UpdateOption(dhcpv4.OptIPAddressLeaseTime(leaseTime))
-	offer.YourIPAddr = testIP
-
-	p := newPuppetClient(stateRebinding)
-	p.c.lease, _ = dhcpv4.FromBytes(offer.ToBytes())
-	// Other deadlines are intentionally empty to make sure they aren't used
-	p.c.leaseDeadline = p.ft.Now().Add(10000 * time.Millisecond)
-
-	p.ft.Advance(9 * time.Second)
-	p.c.LeaseCallback = func(lease *Lease) error {
-		assert.Nil(t, lease, "transition to discovering didn't clear new lease on callback")
-		return nil
-	}
-	for i := 0; i < 10; i++ {
-		p.bmt.sendPackets()
-		p.bmt.sentPacket = nil
-		if err := p.c.runState(context.Background()); err != nil {
-			t.Fatal(err)
-		}
-		if p.c.state == stateDiscovering {
-			assert.Nil(t, p.bmt.sentPacket)
-			break
-		}
-		assert.Equal(t, dhcpv4.MessageTypeRequest, p.bmt.sentPacket.MessageType(), "Invalid message type for rebind")
-		p.ft.time = p.bmt.setDeadline
-		if i == 9 {
-			t.Fatal("Too many tries while rebinding, backoff likely wrong")
-		}
-	}
-	assert.Nil(t, p.c.lease, "Lease not zeroed on transition to discovering")
-	assert.Equal(t, stateDiscovering, p.c.state, "DHCP client didn't transition to discovering after loosing lease")
-}
diff --git a/metropolis/node/core/network/dhcp4c/doc.go b/metropolis/node/core/network/dhcp4c/doc.go
deleted file mode 100644
index 622452b..0000000
--- a/metropolis/node/core/network/dhcp4c/doc.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-// Package dhcp4c provides a client implementation of the DHCPv4 protocol
-// (RFC2131) and a few extensions for Linux-based systems.
-// The code is split into three main parts:
-//   - The core DHCP state machine, which lives in dhcpc.go
-//   - Mechanisms to send and receive DHCP messages, which live in transport/
-//   - Standard callbacks which implement necessary kernel configuration steps in
-//     a simple and standalone way living in callback/
-//
-// Since the DHCP protocol is ugly and underspecified (see
-// https://tools.ietf.org/html/draft-ietf-dhc-implementation-02 for a subset of
-// known issues), this client slightly bends the specification in the following
-// cases:
-//   - IP fragmentation for DHCP messages is not supported for both sending and
-//     receiving messages This is because the major servers (ISC, dnsmasq, ...)
-//     do not implement it and just drop fragmented packets, so it would be
-//     counterproductive to try to send them. The client just attempts to send
-//     the full message and hopes it passes through to the server.
-//   - The suggested timeouts and wait periods have been tightened significantly.
-//     When the standard was written 10Mbps Ethernet with hubs was a common
-//     interconnect. Using these would make the client extremely slow on today's
-//     1Gbps+ networks.
-//   - Wrong data in DHCP responses is fixed up if possible. This fixing includes
-//     dropping prohibited options, clamping semantically invalid data and
-//     defaulting not set options as far as it's possible. Non-recoverable
-//     responses (for example because a non-Unicast IP is handed out or lease
-//     time is not set or zero) are still ignored.  All data which can be stored
-//     in both DHCP fields and options is also normalized to the corresponding
-//     option.
-//   - Duplicate Address Detection is not implemented by default. It's slow, hard
-//     to implement correctly and generally not necessary on modern networks as
-//     the servers already waste time checking for duplicate addresses. It's
-//     possible to hook it in via a LeaseCallback if necessary in a given
-//     application.
-//
-// Operationally, there's one known caveat to using this client: If the lease
-// offered during the select phase (in a DHCPOFFER) is not the same as the one
-// sent in the following DHCPACK the first one might be acceptable, but the
-// second one might not be. This can cause pathological behavior where the
-// client constantly switches between discovering and requesting states.
-// Depending on the reuse policies on the DHCP server this can cause the client
-// to consume all available IP addresses. Sadly there's no good way of fixing
-// this within the boundaries of the protocol. A DHCPRELEASE for the adresse
-// would need to be unicasted so the unaccepable address would need to be
-// configured which can be either impossible if it's not valid or not
-// acceptable from a security standpoint (for example because it overlaps with
-// a prefix used internally) and a DHCPDECLINE would cause the server to
-// blacklist the IP thus also depleting the IP pool.
-// This could be potentially avoided by originating DHCPRELEASE packages from a
-// userspace transport, but said transport would need to be routing- and
-// PMTU-aware which would make it even more complicated than the existing
-// BroadcastTransport.
-package dhcp4c
diff --git a/metropolis/node/core/network/dhcp4c/lease.go b/metropolis/node/core/network/dhcp4c/lease.go
deleted file mode 100644
index fefe092..0000000
--- a/metropolis/node/core/network/dhcp4c/lease.go
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-package dhcp4c
-
-import (
-	"encoding/binary"
-	"net"
-	"time"
-
-	"github.com/insomniacslk/dhcp/dhcpv4"
-)
-
-// Lease represents a DHCPv4 lease. It only consists of an IP, an expiration
-// timestamp and options as all other relevant parts of the message have been
-// normalized into their respective options. It also contains some smart
-// getters for commonly-used options which extract only valid information from
-// options.
-type Lease struct {
-	AssignedIP net.IP
-	ExpiresAt  time.Time
-	Options    dhcpv4.Options
-}
-
-// SubnetMask returns the SubnetMask option or the default mask if not set or
-// invalid.
-// It returns nil if the lease is nil.
-func (l *Lease) SubnetMask() net.IPMask {
-	if l == nil {
-		return nil
-	}
-	mask := net.IPMask(dhcpv4.GetIP(dhcpv4.OptionSubnetMask, l.Options))
-	// If given mask is not valid, use the default mask.
-	if _, bits := mask.Size(); bits != 32 {
-		mask = l.AssignedIP.DefaultMask()
-	}
-	return mask
-}
-
-// IPNet returns an IPNet from the assigned IP and subnet mask.
-// It returns nil if the lease is nil.
-func (l *Lease) IPNet() *net.IPNet {
-	if l == nil {
-		return nil
-	}
-	return &net.IPNet{
-		IP:   l.AssignedIP,
-		Mask: l.SubnetMask(),
-	}
-}
-
-// Routes returns all routes assigned by a DHCP answer. It combines and
-// normalizes data from the Router, StaticRoutingTable and ClasslessStaticRoute
-// options.
-func (l *Lease) Routes() []*dhcpv4.Route {
-	if l == nil {
-		return nil
-	}
-
-	// Note that this is different from l.IPNet() because we care about the
-	// network base address of the network instead of the assigned IP.
-	assignedNet := &net.IPNet{IP: l.AssignedIP.Mask(l.SubnetMask()), Mask: l.SubnetMask()}
-
-	// RFC 3442 Section DHCP Client Behavior:
-	// If the DHCP server returns both a Classless Static Routes option and
-	// a Router option, the DHCP client MUST ignore the Router option.
-	// Similarly, if the DHCP server returns both a Classless Static Routes
-	// option and a Static Routes option, the DHCP client MUST ignore the
-	// Static Routes option.
-	var routes dhcpv4.Routes
-	rawCIDRRoutes := l.Options.Get(dhcpv4.OptionClasslessStaticRoute)
-	if rawCIDRRoutes != nil {
-		// TODO(#96): This needs a logging story
-		// Ignore errors intentionally and just return what has been parsed
-		_ = routes.FromBytes(rawCIDRRoutes)
-		return sanitizeRoutes(routes, assignedNet)
-	}
-	// The Static Routes option contains legacy classful routes (i.e. routes
-	// whose mask is determined by the IP of the network).
-	// Each static route is expressed as a pair of IPs, the first one being
-	// the destination network and the second one being the router IP.
-	// See RFC 2132 Section 5.8 for further details.
-	legacyRouteIPs := dhcpv4.GetIPs(dhcpv4.OptionStaticRoutingTable, l.Options)
-	// Routes are only valid in pairs, cut the last one off if necessary
-	if len(legacyRouteIPs)%2 != 0 {
-		legacyRouteIPs = legacyRouteIPs[:len(legacyRouteIPs)-1]
-	}
-	for i := 0; i < len(legacyRouteIPs)/2; i++ {
-		dest := legacyRouteIPs[i*2]
-		if dest.IsUnspecified() {
-			// RFC 2132 Section 5.8:
-			// The default route (0.0.0.0) is an illegal destination for a
-			// static route.
-			continue
-		}
-		via := legacyRouteIPs[i*2+1]
-		destNet := net.IPNet{
-			// Apply the default mask just to make sure this is a valid route
-			IP:   dest.Mask(dest.DefaultMask()),
-			Mask: dest.DefaultMask(),
-		}
-		routes = append(routes, &dhcpv4.Route{Dest: &destNet, Router: via})
-	}
-	for _, r := range dhcpv4.GetIPs(dhcpv4.OptionRouter, l.Options) {
-		if r.IsGlobalUnicast() || r.IsLinkLocalUnicast() {
-			routes = append(routes, &dhcpv4.Route{
-				Dest:   &net.IPNet{IP: net.IPv4zero, Mask: net.IPv4Mask(0, 0, 0, 0)},
-				Router: r,
-			})
-			// Only one default router can exist, exit after the first one
-			break
-		}
-	}
-	return sanitizeRoutes(routes, assignedNet)
-}
-
-// sanitizeRoutes filters the list of routes by removing routes that are
-// obviously invalid. It filters out routes according to the following criteria:
-//  1. The route is not an interface route and its router is not a unicast or
-//     link-local address.
-//  2. Each route's router must be reachable according to the routes listed
-//     before it and the assigned network.
-//  3. The network mask must consist of all-ones followed by all-zeros. Non-
-//     contiguous routes are not allowed.
-//  4. If multiple routes match the same destination, only the first one is kept.
-//  5. Routes covering the loopback IP space (127.0.0.0/8) will be ignored if
-//     they are smaller than a /9 to prevent them from interfering with loopback
-//     IPs.
-func sanitizeRoutes(routes []*dhcpv4.Route, assignedNet *net.IPNet) []*dhcpv4.Route {
-	var saneRoutes []*dhcpv4.Route
-	for _, route := range routes {
-		if route.Router != nil && !route.Router.IsUnspecified() {
-			if !route.Router.IsGlobalUnicast() && !route.Router.IsLinkLocalUnicast() {
-				// Ignore non-unicast routers
-				continue
-			}
-			reachable := false
-			for _, r := range saneRoutes {
-				if r.Dest.Contains(route.Router) {
-					reachable = true
-					break
-				}
-			}
-			if assignedNet.Contains(route.Router) {
-				reachable = true
-			}
-			if !reachable {
-				continue
-			}
-		}
-		ones, bits := route.Dest.Mask.Size()
-		if bits == 0 && len(route.Dest.Mask) > 0 {
-			// Bitmask is not ones followed by zeros, i.e. invalid
-			continue
-		}
-		// Ignore routes that would be able to redirect loopback IPs
-		if route.Dest.IP.IsLoopback() && ones >= 8 {
-			continue
-		}
-		// Ignore routes that would shadow the implicit interface route
-		assignedOnes, _ := assignedNet.Mask.Size()
-		if assignedNet.IP.Equal(route.Dest.IP) && assignedOnes == ones {
-			continue
-		}
-		validDest := true
-		for _, r := range saneRoutes {
-			rOnes, _ := r.Dest.Mask.Size()
-			if r.Dest.IP.Equal(route.Dest.IP) && ones == rOnes {
-				// Exact duplicate, ignore
-				validDest = false
-				break
-			}
-		}
-		if validDest {
-			saneRoutes = append(saneRoutes, route)
-		}
-	}
-	return saneRoutes
-}
-
-// DNSServers represents an ordered collection of DNS servers
-type DNSServers []net.IP
-
-func (a DNSServers) Equal(b DNSServers) bool {
-	if len(a) == len(b) {
-		if len(a) == 0 {
-			return true // both are empty or nil
-		}
-		for i, aVal := range a {
-			if !aVal.Equal(b[i]) {
-				return false
-			}
-		}
-		return true
-	}
-	return false
-
-}
-
-func ip4toInt(ip net.IP) uint32 {
-	ip4 := ip.To4()
-	if ip4 == nil {
-		return 0
-	}
-	return binary.BigEndian.Uint32(ip4)
-}
-
-// DNSServers returns all unique valid DNS servers from the DHCP
-// DomainNameServers options.
-// It returns nil if the lease is nil.
-func (l *Lease) DNSServers() DNSServers {
-	if l == nil {
-		return nil
-	}
-	rawServers := dhcpv4.GetIPs(dhcpv4.OptionDomainNameServer, l.Options)
-	var servers DNSServers
-	serversSeenMap := make(map[uint32]bool)
-	for _, s := range rawServers {
-		ip4Num := ip4toInt(s)
-		if s.IsGlobalUnicast() || s.IsLinkLocalUnicast() {
-			if serversSeenMap[ip4Num] {
-				continue
-			}
-			serversSeenMap[ip4Num] = true
-			servers = append(servers, s)
-		}
-	}
-	return servers
-}
diff --git a/metropolis/node/core/network/dhcp4c/lease_test.go b/metropolis/node/core/network/dhcp4c/lease_test.go
deleted file mode 100644
index 5d233df..0000000
--- a/metropolis/node/core/network/dhcp4c/lease_test.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-package dhcp4c
-
-import (
-	"bytes"
-	"net"
-	"testing"
-
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestLeaseDHCPServers(t *testing.T) {
-	var tests = []struct {
-		name     string
-		lease    *Lease
-		expected DNSServers
-	}{{
-		name:     "ReturnsNilWithNoLease",
-		lease:    nil,
-		expected: nil,
-	}, {
-		name: "DiscardsInvalidIPs",
-		lease: &Lease{
-			Options: dhcpv4.OptionsFromList(dhcpv4.OptDNS(net.IP{0, 0, 0, 0})),
-		},
-		expected: nil,
-	}, {
-		name: "DeduplicatesIPs",
-		lease: &Lease{
-			Options: dhcpv4.OptionsFromList(dhcpv4.OptDNS(net.IP{192, 0, 2, 1}, net.IP{192, 0, 2, 2}, net.IP{192, 0, 2, 1})),
-		},
-		expected: DNSServers{net.IP{192, 0, 2, 1}, net.IP{192, 0, 2, 2}},
-	}}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			res := test.lease.DNSServers()
-			assert.Equal(t, test.expected, res)
-		})
-	}
-}
-
-func makeIPNet(cidr string) *net.IPNet {
-	_, n, err := net.ParseCIDR(cidr)
-	if err != nil {
-		panic(err)
-	}
-	return n
-}
-
-type testRoute struct {
-	dest     string
-	via      string
-	expected bool
-}
-
-func (t testRoute) toRealRoute() *dhcpv4.Route {
-	ip, n, err := net.ParseCIDR(t.dest)
-	if err != nil {
-		panic(err)
-	}
-	if !ip.Equal(n.IP) {
-		panic("testRoute is not aligned to route boundary")
-	}
-	routerIP := net.ParseIP(t.via)
-	if routerIP == nil && t.via != "" {
-		panic("routerIP is not valid")
-	}
-	return &dhcpv4.Route{
-		Dest:   n,
-		Router: routerIP,
-	}
-}
-
-func TestSanitizeRoutes(t *testing.T) {
-	var tests = []struct {
-		name        string
-		assignedNet *net.IPNet
-		routes      []testRoute
-	}{{
-		name:        "SimpleAdditionalRoute",
-		assignedNet: makeIPNet("10.0.5.0/24"),
-		routes: []testRoute{
-			{"10.0.7.0/24", "10.0.5.1", true},
-		},
-	}, {
-		name:        "OutOfNetworkGateway",
-		assignedNet: makeIPNet("10.5.0.2/32"),
-		routes: []testRoute{
-			{"10.0.7.1/32", "", true},
-			{"0.0.0.0/0", "10.0.7.1", true},
-		},
-	}, {
-		name:        "InvalidRouter",
-		assignedNet: makeIPNet("10.0.5.0/24"),
-		routes: []testRoute{
-			// Router is localhost
-			{"10.0.7.0/24", "127.0.0.1", false},
-			// Router is unreachable
-			{"10.0.8.0/24", "10.254.0.1", false},
-		},
-	}, {
-		name:        "SameDestinationRoutes",
-		assignedNet: makeIPNet("10.0.5.0/24"),
-		routes: []testRoute{
-			{"0.0.0.0/0", "10.0.5.1", true},
-			{"10.0.7.0/24", "10.0.5.1", true},
-			{"0.0.0.0/0", "10.0.7.1", false},
-		},
-	}, {
-		name:        "RoutesShadowingLoopback",
-		assignedNet: makeIPNet("10.0.5.0/24"),
-		routes: []testRoute{
-			// Default route, technically covers 127.0.0.0/8, but less-specific
-			{"0.0.0.0/0", "10.0.5.1", true},
-			// 127.0.0.0/8 is still more-specific
-			{"126.0.0.0/7", "10.0.5.1", true},
-			// Duplicate of 127.0.0.0/8, behavior undefined, disallowed
-			{"127.0.0.0/8", "10.0.5.1", false},
-			// Shadows localhost, disallowed
-			{"127.0.0.1/32", "10.0.5.1", false},
-		},
-	}}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			var routes []*dhcpv4.Route
-			var expectedRoutes []*dhcpv4.Route
-			for _, r := range test.routes {
-				routes = append(routes, r.toRealRoute())
-				if r.expected {
-					expectedRoutes = append(expectedRoutes, r.toRealRoute())
-				}
-			}
-			out := sanitizeRoutes(routes, test.assignedNet)
-			if len(out) != len(expectedRoutes) {
-				t.Errorf("expected %d routes, got %d", len(expectedRoutes), len(out))
-				t.Error("Expected:")
-				for _, r := range expectedRoutes {
-					t.Errorf("\t%s via %s", r.Dest, r.Router)
-				}
-				t.Error("Actual:")
-				for _, r := range out {
-					t.Errorf("\t%s via %s", r.Dest, r.Router)
-				}
-				return
-			}
-			for i, r := range expectedRoutes {
-				if !out[i].Router.Equal(r.Router) || !out[i].Dest.IP.Equal(r.Dest.IP) || !bytes.Equal(out[i].Dest.Mask, r.Dest.Mask) {
-					t.Errorf("expected %s via %s, got %s via %s", r.Dest, r.Router, out[i].Dest, out[i].Router)
-				}
-			}
-		})
-	}
-}
diff --git a/metropolis/node/core/network/dhcp4c/transport/BUILD.bazel b/metropolis/node/core/network/dhcp4c/transport/BUILD.bazel
deleted file mode 100644
index 8d5425f..0000000
--- a/metropolis/node/core/network/dhcp4c/transport/BUILD.bazel
+++ /dev/null
@@ -1,20 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "transport",
-    srcs = [
-        "transport.go",
-        "transport_broadcast.go",
-        "transport_unicast.go",
-    ],
-    importpath = "source.monogon.dev/metropolis/node/core/network/dhcp4c/transport",
-    visibility = ["//metropolis/node/core/network/dhcp4c:__subpackages__"],
-    deps = [
-        "@com_github_google_gopacket//:gopacket",
-        "@com_github_google_gopacket//layers",
-        "@com_github_insomniacslk_dhcp//dhcpv4",
-        "@com_github_mdlayher_packet//:packet",
-        "@org_golang_x_net//bpf",
-        "@org_golang_x_sys//unix",
-    ],
-)
diff --git a/metropolis/node/core/network/dhcp4c/transport/transport.go b/metropolis/node/core/network/dhcp4c/transport/transport.go
deleted file mode 100644
index 9a5ff14..0000000
--- a/metropolis/node/core/network/dhcp4c/transport/transport.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-// Package transport contains Linux-based transports for the DHCP broadcast and
-// unicast specifications.
-package transport
-
-import (
-	"errors"
-	"fmt"
-	"net"
-)
-
-var ErrDeadlineExceeded = errors.New("deadline exceeded")
-
-func NewInvalidMessageError(internalErr error) error {
-	return &InvalidMessageError{internalErr: internalErr}
-}
-
-type InvalidMessageError struct {
-	internalErr error
-}
-
-func (i InvalidMessageError) Error() string {
-	return fmt.Sprintf("received invalid packet: %v", i.internalErr.Error())
-}
-
-func (i InvalidMessageError) Unwrap() error {
-	return i.internalErr
-}
-
-func deadlineFromTimeout(err error) error {
-	var timeoutErr net.Error
-	if errors.As(err, &timeoutErr) && timeoutErr.Timeout() {
-		return ErrDeadlineExceeded
-	}
-	return err
-}
diff --git a/metropolis/node/core/network/dhcp4c/transport/transport_broadcast.go b/metropolis/node/core/network/dhcp4c/transport/transport_broadcast.go
deleted file mode 100644
index b61af80..0000000
--- a/metropolis/node/core/network/dhcp4c/transport/transport_broadcast.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-package transport
-
-import (
-	"errors"
-	"fmt"
-	"math"
-	"net"
-	"time"
-
-	"github.com/google/gopacket"
-	"github.com/google/gopacket/layers"
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"github.com/mdlayher/packet"
-	"golang.org/x/net/bpf"
-)
-
-const (
-	// RFC2474 Section 4.2.2.1 with reference to RFC791 Section 3.1 (Network
-	// Control Precedence)
-	dscpCS7 = 0x7 << 3
-
-	// IPv4 MTU
-	maxIPv4MTU = math.MaxUint16 // IPv4 "Total Length" field is an unsigned 16 bit integer
-)
-
-// mustAssemble calls bpf.Assemble and panics if it retuns an error.
-func mustAssemble(insns []bpf.Instruction) []bpf.RawInstruction {
-	rawInsns, err := bpf.Assemble(insns)
-	if err != nil {
-		panic("mustAssemble failed to assemble BPF: " + err.Error())
-	}
-	return rawInsns
-}
-
-// BPF filter for UDP in IPv4 with destination port 68 (DHCP Client)
-//
-// This is used to make the kernel drop non-DHCP traffic for us so that we
-// don't have to handle excessive unrelated traffic flowing on a given link
-// which might overwhelm the single-threaded receiver.
-var bpfFilterInstructions = []bpf.Instruction{
-	// Check IP protocol version equals 4 (first 4 bits of the first byte)
-	// With Ethernet II framing, this is more of a sanity check. We already
-	// request the kernel to only return EtherType 0x0800 (IPv4) frames.
-	bpf.LoadAbsolute{Off: 0, Size: 1},
-	bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 0xf0}, // SubnetMask second 4 bits
-	bpf.JumpIf{Cond: bpf.JumpEqual, Val: 4 << 4, SkipTrue: 1},
-	bpf.RetConstant{Val: 0}, // Discard
-
-	// Check IPv4 Protocol byte (offset 9) equals UDP
-	bpf.LoadAbsolute{Off: 9, Size: 1},
-	bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(layers.IPProtocolUDP), SkipTrue: 1},
-	bpf.RetConstant{Val: 0}, // Discard
-
-	// Check if IPv4 fragment offset is all-zero (this is not a fragment)
-	bpf.LoadAbsolute{Off: 6, Size: 2},
-	bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 0x1fff, SkipFalse: 1},
-	bpf.RetConstant{Val: 0}, // Discard
-
-	// Load IPv4 header size from offset zero and store it into X
-	bpf.LoadMemShift{Off: 0},
-
-	// Check if UDP header destination port equals 68
-	bpf.LoadIndirect{Off: 2, Size: 2}, // Offset relative to header size in register X
-	bpf.JumpIf{Cond: bpf.JumpEqual, Val: 68, SkipTrue: 1},
-	bpf.RetConstant{Val: 0}, // Discard
-
-	// Accept packet and pass through up maximum IP packet size
-	bpf.RetConstant{Val: maxIPv4MTU},
-}
-
-var bpfFilter = mustAssemble(bpfFilterInstructions)
-
-// BroadcastTransport implements a DHCP transport based on a custom IP/UDP
-// stack fulfilling the specific requirements for broadcasting DHCP packets
-// (like all-zero source address, no ARP, ...)
-type BroadcastTransport struct {
-	rawConn *packet.Conn
-	iface   *net.Interface
-}
-
-func NewBroadcastTransport(iface *net.Interface) *BroadcastTransport {
-	return &BroadcastTransport{iface: iface}
-}
-
-func (t *BroadcastTransport) Open() error {
-	if t.rawConn != nil {
-		return errors.New("broadcast transport already open")
-	}
-	rawConn, err := packet.Listen(t.iface, packet.Datagram, int(layers.EthernetTypeIPv4), &packet.Config{
-		Filter: bpfFilter,
-	})
-	if err != nil {
-		return fmt.Errorf("failed to create raw listener: %w", err)
-	}
-	t.rawConn = rawConn
-	return nil
-}
-
-func (t *BroadcastTransport) Send(payload *dhcpv4.DHCPv4) error {
-	if t.rawConn == nil {
-		return errors.New("broadcast transport closed")
-	}
-	pkt := gopacket.NewSerializeBuffer()
-	opts := gopacket.SerializeOptions{
-		ComputeChecksums: true,
-		FixLengths:       true,
-	}
-
-	ipLayer := &layers.IPv4{
-		Version: 4,
-		// Shift left of ECN field
-		TOS: dscpCS7 << 2,
-		// These packets should never be routed (their IP headers contain
-		// garbage)
-		TTL:      1,
-		Protocol: layers.IPProtocolUDP,
-		// Most DHCP servers don't support fragmented packets.
-		Flags: layers.IPv4DontFragment,
-		DstIP: net.IPv4bcast,
-		SrcIP: net.IPv4zero,
-	}
-	udpLayer := &layers.UDP{
-		DstPort: 67,
-		SrcPort: 68,
-	}
-	if err := udpLayer.SetNetworkLayerForChecksum(ipLayer); err != nil {
-		panic("Invalid layer stackup encountered")
-	}
-
-	err := gopacket.SerializeLayers(pkt, opts,
-		ipLayer,
-		udpLayer,
-		gopacket.Payload(payload.ToBytes()))
-
-	if err != nil {
-		return fmt.Errorf("failed to assemble packet: %w", err)
-	}
-
-	_, err = t.rawConn.WriteTo(pkt.Bytes(), &packet.Addr{HardwareAddr: layers.EthernetBroadcast})
-	if err != nil {
-		return fmt.Errorf("failed to transmit broadcast packet: %w", err)
-	}
-	return nil
-}
-
-func (t *BroadcastTransport) Receive() (*dhcpv4.DHCPv4, error) {
-	if t.rawConn == nil {
-		return nil, errors.New("broadcast transport closed")
-	}
-	buf := make([]byte, math.MaxUint16) // Maximum IP packet size
-	n, _, err := t.rawConn.ReadFrom(buf)
-	if err != nil {
-		return nil, deadlineFromTimeout(err)
-	}
-	respPacket := gopacket.NewPacket(buf[:n], layers.LayerTypeIPv4, gopacket.Default)
-	ipLayer := respPacket.Layer(layers.LayerTypeIPv4)
-	if ipLayer == nil {
-		return nil, NewInvalidMessageError(errors.New("got invalid IP packet"))
-	}
-	ip := ipLayer.(*layers.IPv4)
-	if ip.Flags&layers.IPv4MoreFragments != 0 {
-		return nil, NewInvalidMessageError(errors.New("got fragmented message"))
-	}
-
-	udpLayer := respPacket.Layer(layers.LayerTypeUDP)
-	if udpLayer == nil {
-		return nil, NewInvalidMessageError(errors.New("got non-UDP packet"))
-	}
-	udp := udpLayer.(*layers.UDP)
-	if udp.DstPort != 68 {
-		return nil, NewInvalidMessageError(errors.New("message not for DHCP client port"))
-	}
-	msg, err := dhcpv4.FromBytes(udp.Payload)
-	if err != nil {
-		return nil, NewInvalidMessageError(fmt.Errorf("failed to decode DHCPv4 message: %w", err))
-	}
-	return msg, nil
-}
-
-func (t *BroadcastTransport) Close() error {
-	if t.rawConn == nil {
-		return nil
-	}
-	if err := t.rawConn.Close(); err != nil {
-		return err
-	}
-	t.rawConn = nil
-	return nil
-}
-
-func (t *BroadcastTransport) SetReceiveDeadline(deadline time.Time) error {
-	if t.rawConn == nil {
-		return errors.New("broadcast transport closed")
-	}
-	return t.rawConn.SetReadDeadline(deadline)
-}
diff --git a/metropolis/node/core/network/dhcp4c/transport/transport_unicast.go b/metropolis/node/core/network/dhcp4c/transport/transport_unicast.go
deleted file mode 100644
index b76e37c..0000000
--- a/metropolis/node/core/network/dhcp4c/transport/transport_unicast.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright The Monogon Project Authors.
-// SPDX-License-Identifier: Apache-2.0
-
-package transport
-
-import (
-	"errors"
-	"fmt"
-	"math"
-	"net"
-	"os"
-	"time"
-
-	"github.com/insomniacslk/dhcp/dhcpv4"
-	"golang.org/x/sys/unix"
-)
-
-// UnicastTransport implements a DHCP transport based on a normal Linux UDP
-// socket with some custom socket options to influence DSCP and routing.
-type UnicastTransport struct {
-	udpConn  *net.UDPConn
-	targetIP net.IP
-	iface    *net.Interface
-}
-
-func NewUnicastTransport(iface *net.Interface) *UnicastTransport {
-	return &UnicastTransport{
-		iface: iface,
-	}
-}
-
-func (t *UnicastTransport) Open(serverIP, bindIP net.IP) error {
-	if t.udpConn != nil {
-		return errors.New("unicast transport already open")
-	}
-	rawFd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0)
-	if err != nil {
-		return fmt.Errorf("failed to get socket: %w", err)
-	}
-	if err := unix.BindToDevice(rawFd, t.iface.Name); err != nil {
-		return fmt.Errorf("failed to bind UDP interface to device: %w", err)
-	}
-	if err := unix.SetsockoptByte(rawFd, unix.SOL_IP, unix.IP_TOS, dscpCS7<<2); err != nil {
-		return fmt.Errorf("failed to set DSCP CS7: %w", err)
-	}
-	var addr [4]byte
-	copy(addr[:], bindIP.To4())
-	if err := unix.Bind(rawFd, &unix.SockaddrInet4{Addr: addr, Port: 68}); err != nil {
-		return fmt.Errorf("failed to bind UDP unicast interface: %w", err)
-	}
-	filePtr := os.NewFile(uintptr(rawFd), "dhcp-udp")
-	defer filePtr.Close()
-	conn, err := net.FileConn(filePtr)
-	if err != nil {
-		return fmt.Errorf("failed to initialize runtime-supported UDP connection: %w", err)
-	}
-	realConn, ok := conn.(*net.UDPConn)
-	if !ok {
-		panic("UDP socket imported into Go runtime is no longer a UDP socket")
-	}
-	t.udpConn = realConn
-	t.targetIP = serverIP
-	return nil
-}
-
-func (t *UnicastTransport) Send(payload *dhcpv4.DHCPv4) error {
-	if t.udpConn == nil {
-		return errors.New("unicast transport closed")
-	}
-	_, _, err := t.udpConn.WriteMsgUDP(payload.ToBytes(), []byte{}, &net.UDPAddr{
-		IP:   t.targetIP,
-		Port: 67,
-	})
-	return err
-}
-
-func (t *UnicastTransport) SetReceiveDeadline(deadline time.Time) error {
-	return t.udpConn.SetReadDeadline(deadline)
-}
-
-func (t *UnicastTransport) Receive() (*dhcpv4.DHCPv4, error) {
-	if t.udpConn == nil {
-		return nil, errors.New("unicast transport closed")
-	}
-	receiveBuf := make([]byte, math.MaxUint16)
-	_, _, err := t.udpConn.ReadFromUDP(receiveBuf)
-	if err != nil {
-		return nil, deadlineFromTimeout(err)
-	}
-	msg, err := dhcpv4.FromBytes(receiveBuf)
-	if err != nil {
-		return nil, NewInvalidMessageError(err)
-	}
-	return msg, nil
-}
-
-func (t *UnicastTransport) Close() error {
-	if t.udpConn == nil {
-		return nil
-	}
-	err := t.udpConn.Close()
-	t.udpConn = nil
-	if err != nil && errors.Is(err, net.ErrClosed) {
-		//nolint:returnerrcheck
-		return nil
-	}
-	return err
-}
diff --git a/metropolis/node/core/network/main.go b/metropolis/node/core/network/main.go
index 276e59e..2dcf7bb 100644
--- a/metropolis/node/core/network/main.go
+++ b/metropolis/node/core/network/main.go
@@ -17,12 +17,12 @@
 	"github.com/vishvananda/netlink"
 
 	"source.monogon.dev/metropolis/node"
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
-	dhcpcb "source.monogon.dev/metropolis/node/core/network/dhcp4c/callback"
 	"source.monogon.dev/metropolis/node/core/network/ipam"
 	"source.monogon.dev/metropolis/node/core/network/workloads"
 	"source.monogon.dev/osbase/event"
 	"source.monogon.dev/osbase/event/memory"
+	"source.monogon.dev/osbase/net/dhcp4c"
+	dhcpcb "source.monogon.dev/osbase/net/dhcp4c/callback"
 	"source.monogon.dev/osbase/net/dns"
 	"source.monogon.dev/osbase/net/dns/forward"
 	"source.monogon.dev/osbase/supervisor"
diff --git a/metropolis/node/core/network/neigh.go b/metropolis/node/core/network/neigh.go
index d86dab7..c472d54 100644
--- a/metropolis/node/core/network/neigh.go
+++ b/metropolis/node/core/network/neigh.go
@@ -15,7 +15,7 @@
 	"github.com/vishvananda/netlink"
 	"golang.org/x/sys/unix"
 
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
+	"source.monogon.dev/osbase/net/dhcp4c"
 )
 
 var ethernetNull = net.HardwareAddr{0, 0, 0, 0, 0, 0}
diff --git a/metropolis/node/core/network/static.go b/metropolis/node/core/network/static.go
index e8169d9..c7c5d6a 100644
--- a/metropolis/node/core/network/static.go
+++ b/metropolis/node/core/network/static.go
@@ -21,8 +21,8 @@
 	"source.monogon.dev/go/algorithm/toposort"
 	"source.monogon.dev/go/logging"
 	"source.monogon.dev/metropolis/node"
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
-	dhcpcb "source.monogon.dev/metropolis/node/core/network/dhcp4c/callback"
+	"source.monogon.dev/osbase/net/dhcp4c"
+	dhcpcb "source.monogon.dev/osbase/net/dhcp4c/callback"
 	"source.monogon.dev/osbase/supervisor"
 	"source.monogon.dev/osbase/sysctl"
 
diff --git a/metropolis/test/nanoswitch/BUILD.bazel b/metropolis/test/nanoswitch/BUILD.bazel
index 9aff921..ef80101 100644
--- a/metropolis/test/nanoswitch/BUILD.bazel
+++ b/metropolis/test/nanoswitch/BUILD.bazel
@@ -11,9 +11,9 @@
     visibility = ["//visibility:private"],
     deps = [
         "//metropolis/node",
-        "//metropolis/node/core/network/dhcp4c",
-        "//metropolis/node/core/network/dhcp4c/callback",
         "//osbase/bringup",
+        "//osbase/net/dhcp4c",
+        "//osbase/net/dhcp4c/callback",
         "//osbase/supervisor",
         "//osbase/test/socksproxy",
         "@com_github_google_nftables//:nftables",
diff --git a/metropolis/test/nanoswitch/nanoswitch.go b/metropolis/test/nanoswitch/nanoswitch.go
index c3fde27..78d8efe 100644
--- a/metropolis/test/nanoswitch/nanoswitch.go
+++ b/metropolis/test/nanoswitch/nanoswitch.go
@@ -29,9 +29,9 @@
 	"github.com/vishvananda/netlink"
 
 	common "source.monogon.dev/metropolis/node"
-	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
-	dhcpcb "source.monogon.dev/metropolis/node/core/network/dhcp4c/callback"
 	"source.monogon.dev/osbase/bringup"
+	"source.monogon.dev/osbase/net/dhcp4c"
+	dhcpcb "source.monogon.dev/osbase/net/dhcp4c/callback"
 	"source.monogon.dev/osbase/supervisor"
 )
 
