m/n/c/mgmt: disable interfaces before kexec

This is done to prevent network interface DMA transactions from
interfering with an in-progress kexec. [1]

[1] https://lists.infradead.org/pipermail/kexec/2011-January/004795.html

Change-Id: I12ab22c095fcff56873d980d524c461b1b2d57ee
Reviewed-on: https://review.monogon.dev/c/monogon/+/2783
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/metropolis/node/core/mgmt/BUILD.bazel b/metropolis/node/core/mgmt/BUILD.bazel
index e683eee..a274013 100644
--- a/metropolis/node/core/mgmt/BUILD.bazel
+++ b/metropolis/node/core/mgmt/BUILD.bazel
@@ -18,6 +18,7 @@
         "//metropolis/pkg/supervisor",
         "//metropolis/proto/api",
         "//metropolis/proto/common",
+        "@com_github_vishvananda_netlink//:netlink",
         "@org_golang_google_grpc//:go_default_library",
         "@org_golang_google_grpc//codes",
         "@org_golang_google_grpc//status",
diff --git a/metropolis/node/core/mgmt/update.go b/metropolis/node/core/mgmt/update.go
index 69b8744..ab31682 100644
--- a/metropolis/node/core/mgmt/update.go
+++ b/metropolis/node/core/mgmt/update.go
@@ -4,6 +4,7 @@
 	"context"
 	"time"
 
+	"github.com/vishvananda/netlink"
 	"golang.org/x/sys/unix"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
@@ -40,9 +41,29 @@
 			s.LogTree.MustLeveledFor("update").Info("activating now...")
 			unix.Unmount(s.UpdateService.ESPPath, 0)
 			unix.Sync()
+			disableNetworkInterfaces()
 			unix.Reboot(method)
 		}()
 	}
 
 	return &apb.UpdateNodeResponse{}, nil
 }
+
+// For kexec it's recommended to disable all physical network interfaces
+// before doing it. This function doesn't return any errors as it's best-
+// effort anyways as we cannot reliably log the error anymore.
+func disableNetworkInterfaces() {
+	links, err := netlink.LinkList()
+	if err != nil {
+		return
+	}
+	for _, link := range links {
+		d, ok := link.(*netlink.Device)
+		if !ok {
+			continue
+		}
+		if err := netlink.LinkSetDown(d); err != nil {
+			continue
+		}
+	}
+}