m/n/c/network: refetch link attributes from kernel

Fetch all link attributes from the kernel once an interface is
created/configured to ensure all attributes are present and any
defaults set by the kernel are taken into account.

Only affects the static configuration path, dynamic configuration path
already gets the interface data directly from the kernel.

This is an alternative to CL 3112 which had to be reverted.

Change-Id: I1076fa318cac5f0ecdb47c5b0aac4dfe7ea2cac9
Reviewed-on: https://review.monogon.dev/c/monogon/+/3139
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 abe9aca..3d695cc 100644
--- a/metropolis/node/core/network/static.go
+++ b/metropolis/node/core/network/static.go
@@ -118,15 +118,21 @@
 			}()
 		}
 		nameLinkMap[i.Name] = newLink
+		// Get the link from the kernel again to get all defaulted and
+		// hardware-derived attributes.
+		newLinkWithAttrs, err := netlink.LinkByIndex(newLink.Attrs().Index)
+		if err != nil {
+			return fmt.Errorf("while getting just-configured link: %w", err)
+		}
 		if i.Ipv4Autoconfig != nil {
-			if err := s.runDHCPv4(ctx, newLink); err != nil {
+			if err := s.runDHCPv4(ctx, newLinkWithAttrs); err != nil {
 				return fmt.Errorf("error enabling DHCPv4 on %q: %w", newLink.Attrs().Name, err)
 			}
 			hasIPv4Autoconfig = true
 		}
 		if i.Ipv6Autoconfig != nil {
 			opts := sysctl.Options{
-				"net.ipv6.conf." + newLink.Attrs().Name + ".accept_ra": "1",
+				"net.ipv6.conf." + newLinkWithAttrs.Attrs().Name + ".accept_ra": "1",
 			}
 			if err := opts.Apply(); err != nil {
 				return fmt.Errorf("failed enabling accept_ra for interface %q: %w", newLink.Attrs().Name, err)