summary refs log tree commit diff
path: root/nixos/modules/tasks/network-interfaces.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/tasks/network-interfaces.nix')
-rw-r--r--nixos/modules/tasks/network-interfaces.nix50
1 files changed, 44 insertions, 6 deletions
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 22b52f77b145..9579eaa77d06 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -189,6 +189,10 @@ let
 
   };
 
+  hexChars = stringToCharacters "0123456789abcdef";
+
+  isHexString = s: all (c: elem c hexChars) (stringToCharacters (toLower s));
+
 in
 
 {
@@ -205,6 +209,20 @@ in
       '';
     };
 
+    networking.hostId = mkOption {
+      default = null;
+      example = "4e98920d";
+      type = types.nullOr types.str;
+      description = ''
+        The 32-bit host ID of the machine, formatted as 8 hexadecimal characters.
+
+        You should try to make this ID unique among your machines. You can
+        generate a random 32-bit ID using the following command:
+
+        <literal>head -c4 /dev/urandom | od -A none -t x4</literal>
+      '';
+    };
+
     networking.enableIPv6 = mkOption {
       default = true;
       description = ''
@@ -513,10 +531,15 @@ in
   config = {
 
     assertions =
-      flip map interfaces (i: {
+      (flip map interfaces (i: {
         assertion = i.subnetMask == null;
         message = "The networking.interfaces.${i.name}.subnetMask option is defunct. Use prefixLength instead.";
-      });
+      })) ++ [
+        {
+          assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId);
+          message = "Invalid value given to the networking.hostId option.";
+        }
+      ];
 
     boot.kernelModules = [ ]
       ++ optional cfg.enableIPv6 "ipv6"
@@ -872,14 +895,29 @@ in
     # clear it if it's not configured in the NixOS configuration,
     # since it may have been set by dhcpcd in the meantime.
     system.activationScripts.hostname =
-      optionalString (config.networking.hostName != "") ''
-        hostname "${config.networking.hostName}"
+      optionalString (cfg.hostName != "") ''
+        hostname "${cfg.hostName}"
       '';
     system.activationScripts.domain =
-      optionalString (config.networking.domain != "") ''
-        domainname "${config.networking.domain}"
+      optionalString (cfg.domain != "") ''
+        domainname "${cfg.domain}"
       '';
 
+    environment.etc = mkIf (cfg.hostId != null)
+      [
+        {
+          target = "hostid";
+          source = pkgs.runCommand "gen-hostid" {} ''
+            hi="${cfg.hostId}"
+            ${if pkgs.stdenv.isBigEndian then ''
+              echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out
+            '' else ''
+              echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out
+            ''}
+          '';
+        }
+      ];
+
     services.udev.extraRules =
       ''
         KERNEL=="tun", TAG+="systemd"