diff --git a/nixos/modules/hardware/facter/default.nix b/nixos/modules/hardware/facter/default.nix index 324471b16e70..f2719b55b8ce 100644 --- a/nixos/modules/hardware/facter/default.nix +++ b/nixos/modules/hardware/facter/default.nix @@ -7,6 +7,7 @@ imports = [ ./disk.nix ./keyboard.nix + ./networking ./system.nix ]; diff --git a/nixos/modules/hardware/facter/networking/default.nix b/nixos/modules/hardware/facter/networking/default.nix new file mode 100644 index 000000000000..dfbc54c8396d --- /dev/null +++ b/nixos/modules/hardware/facter/networking/default.nix @@ -0,0 +1,69 @@ +{ config, lib, ... }: +let + # Filter network interfaces from facter report to only those suitable for DHCP + physicalInterfaces = lib.filter ( + iface: + # Only include network interfaces suitable for DHCP: + # - Ethernet (most common) + # - WLAN (WiFi) + # - USB-Link (USB network adapters, tethering) + # - Network Interface (generic/unknown type) + # This implicitly excludes: Loopback, mainframe-specific interfaces (CTC, IUCV, HSI, ESCON) + # See: https://github.com/numtide/hwinfo/blob/ea251a74b88dcd53aebdd381194ab43d10fbbd79/src/ids/src/class#L817-L874 + let + validTypes = [ + "Ethernet" + "WLAN" + "USB-Link" + "Network Interface" + ]; + in + lib.elem (iface.sub_class.name or "") validTypes + ) (config.hardware.facter.report.hardware.network_interface or [ ]); + + # Extract interface names from unix_device_names + detectedInterfaceNames = lib.concatMap (iface: iface.unix_device_names or [ ]) physicalInterfaces; + + # Get the interface names from the configuration (which defaults to detectedInterfaceNames) + interfaceNames = config.hardware.facter.detected.dhcp.interfaces; + + # Generate per-interface DHCP config + perInterfaceConfig = lib.listToAttrs ( + lib.map (name: { + inherit name; + value = { + useDHCP = lib.mkDefault true; + }; + }) interfaceNames + ); +in +{ + imports = [ + ./initrd.nix + ./intel.nix + ]; + + options.hardware.facter.detected.dhcp = { + enable = lib.mkEnableOption "Facter dhcp module" // { + default = builtins.length config.hardware.facter.report.hardware.network_interface or [ ] > 0; + defaultText = "hardware dependent"; + }; + + interfaces = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = detectedInterfaceNames; + defaultText = lib.literalExpression "automatically detected from facter report"; + description = "List of network interface names to configure with DHCP. Defaults to auto-detected physical interfaces."; + example = [ + "eth0" + "wlan0" + ]; + }; + }; + config = lib.mkIf config.hardware.facter.detected.dhcp.enable { + networking.useDHCP = lib.mkDefault true; + + # Per-interface DHCP configuration + networking.interfaces = perInterfaceConfig; + }; +} diff --git a/nixos/modules/hardware/facter/networking/initrd.nix b/nixos/modules/hardware/facter/networking/initrd.nix new file mode 100644 index 000000000000..56be802b7cd9 --- /dev/null +++ b/nixos/modules/hardware/facter/networking/initrd.nix @@ -0,0 +1,20 @@ +{ lib, config, ... }: +let + facterLib = import ../lib.nix lib; + + inherit (config.hardware.facter) report; +in +{ + options.hardware.facter.detected.boot.initrd.networking.kernelModules = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = lib.uniqueStrings (facterLib.collectDrivers (report.hardware.network_controller or [ ])); + defaultText = "hardware dependent"; + description = '' + List of kernel modules to include in the initrd to support networking. + ''; + }; + + config = lib.mkIf config.boot.initrd.network.enable { + boot.initrd.kernelModules = config.hardware.facter.detected.boot.initrd.networking.kernelModules; + }; +} diff --git a/nixos/modules/hardware/facter/networking/intel.nix b/nixos/modules/hardware/facter/networking/intel.nix new file mode 100644 index 000000000000..4ae693a3c636 --- /dev/null +++ b/nixos/modules/hardware/facter/networking/intel.nix @@ -0,0 +1,57 @@ +{ lib, config, ... }: +let + inherit (config.hardware.facter) report; + cfg = config.hardware.facter.detected.networking.intel; +in +{ + options.hardware.facter.detected.networking.intel = with lib; { + _2200BG.enable = mkEnableOption "the Facter Intel 2200BG module" // { + + default = lib.any ( + { + vendor ? { }, + device ? { }, + ... + }: + # vendor (0x8086) Intel Corp. + (vendor.value or 0) == 32902 + && (lib.elem (device.value or 0) [ + 4163 # 0x1043 + 4175 # 0x104f + 16928 # 0x4220 + 16929 # 0x4221 + 16931 # 0x4223 + 16932 # 0x4224 + ]) + ) (report.hardware.network_controller or [ ]); + + defaultText = "hardware dependent"; + }; + _3945ABG.enable = mkEnableOption "the Facter Intel 3945ABG module" // { + + default = lib.any ( + { + vendor ? { }, + device ? { }, + ... + }: + # vendor (0x8086) Intel Corp. + (vendor.value or 0) == 32902 + && (lib.elem (device.value or 0) [ + 16937 # 0x4229 + 16938 # 0x4230 + 16930 # 0x4222 + 16935 # 0x4227 + ]) + ) (report.hardware.network_controller or [ ]); + + defaultText = "hardware dependent"; + }; + }; + + config = { + networking.enableIntel2200BGFirmware = lib.mkIf cfg._2200BG.enable (lib.mkDefault true); + hardware.enableRedistributableFirmware = lib.mkIf cfg._3945ABG.enable (lib.mkDefault true); + }; + +}