m/n/c/network: static networking fixes

This fixes three issues with static networking:

It joins interfaces to a master in down state as otherwise Linux
can return an error.

It takes up the automatically-created loopback interface as otherwise we
have no working loopback interface which causes some weird breakage.

It also patches netlink to use RTM_SETLINK instead of RTM_NEWLINK for
reconfiguring interfaces as otherwise Linux sometimes returns an error.

Change-Id: I512e38c6edc1a6d964feb552b1a3995165d74730
Reviewed-on: https://review.monogon.dev/c/monogon/+/1523
Tested-by: Jenkins CI
Reviewed-by: Serge Bazanski <serge@monogon.tech>
diff --git a/metropolis/node/core/network/static.go b/metropolis/node/core/network/static.go
index 45469df..29e3c48 100644
--- a/metropolis/node/core/network/static.go
+++ b/metropolis/node/core/network/static.go
@@ -68,13 +68,14 @@
 			return fmt.Errorf("interface %q: %w", i.Name, err)
 		}
 		newLink.Attrs().Name = i.Name
-		// Set link administratively up
-		newLink.Attrs().Flags |= unix.IFF_UP
 		if i.Mtu != 0 {
 			newLink.Attrs().MTU = int(i.Mtu)
 		}
 		if nameParentMap[i.Name] != "" {
 			newLink.Attrs().MasterIndex = nameLinkMap[nameParentMap[i.Name]].Attrs().Index
+		} else {
+			// Set link administratively up if no MasterIndex has been set.
+			newLink.Attrs().Flags |= net.FlagUp
 		}
 		if newLink.Attrs().Index == -1 {
 			if err := netlink.LinkAdd(newLink); err != nil {
@@ -192,7 +193,7 @@
 
 	for _, link := range links {
 		if link.Attrs().EncapType == "loopback" {
-			continue
+			netlink.LinkSetUp(link)
 		}
 		d, ok := link.(*netlink.Device)
 		if !ok {