From 0b8e24c80ad0a5e9e97b0aedd17357199b82c369 Mon Sep 17 00:00:00 2001
From: sinanmohd <sinan@sinanmohd.com>
Date: Mon, 27 Nov 2023 09:56:05 +0530
Subject: modules/iwd: fix broken dhcp dns configuration

---
 modules/iwd.nix | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 modules/iwd.nix

(limited to 'modules')

diff --git a/modules/iwd.nix b/modules/iwd.nix
new file mode 100644
index 0000000..0c1c94a
--- /dev/null
+++ b/modules/iwd.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, ... }:
+
+let
+  inherit (lib)
+    mkEnableOption mkIf mkOption types
+    recursiveUpdate;
+
+  cfg = config.networking.wireless.iwd;
+  ini = pkgs.formats.ini { };
+  defaults = {
+    # without UseDefaultInterface, sometimes wlan0 simply goes AWOL with NetworkManager
+    # https://iwd.wiki.kernel.org/interface_lifecycle#interface_management_in_iwd
+    General.UseDefaultInterface = with config.networking.networkmanager; (enable && (wifi.backend == "iwd"));
+  };
+  configFile = ini.generate "main.conf" (recursiveUpdate defaults cfg.settings);
+
+in
+{
+  options.networking.wireless.iwd = {
+    enable = mkEnableOption (lib.mdDoc "iwd");
+
+    package = mkOption {
+      type = types.package;
+      default = pkgs.iwd;
+      defaultText = lib.literalExpression "pkgs.iwd";
+      description = lib.mdDoc ''
+        The iwd package to use.
+      '';
+    };
+
+    settings = mkOption {
+      type = ini.type;
+      default = { };
+
+      example = {
+        Settings.AutoConnect = true;
+
+        Network = {
+          EnableIPv6 = true;
+          RoutePriorityOffset = 300;
+        };
+      };
+
+      description = lib.mdDoc ''
+        Options passed to iwd.
+        See [here](https://iwd.wiki.kernel.org/networkconfigurationsettings) for supported options.
+      '';
+    };
+  };
+
+  config = lib.mkMerge [
+    (mkIf cfg.enable {
+      assertions = [{
+        assertion = !config.networking.wireless.enable;
+        message = ''
+          Only one wireless daemon is allowed at the time: networking.wireless.enable and networking.wireless.iwd.enable are mutually exclusive.
+        '';
+      }];
+
+      environment.etc."iwd/${configFile.name}".source = configFile;
+
+      # for iwctl
+      environment.systemPackages = [ cfg.package ];
+      services.dbus.packages = [ cfg.package ];
+      systemd.packages = [ cfg.package ];
+
+      systemd.network.links."80-iwd" = {
+        matchConfig.Type = "wlan";
+        linkConfig.NamePolicy = "keep kernel";
+      };
+
+      systemd.services.iwd = {
+        wantedBy = [ "multi-user.target" ];
+        restartTriggers = [ configFile ];
+      };
+    })
+    (let
+      needResolv = cfg.enable
+                   && lib.hasAttrByPath [ "Network" "NameResolvingService" ] cfg.settings
+                   && cfg.settings.Network.NameResolvingService == "resolvconf";
+    in
+    mkIf needResolv {
+      environment.systemPackages = [ pkgs.openresolv ];
+
+      systemd.services.iwd = {
+        path = [ pkgs.openresolv ];
+        serviceConfig.ReadWritePaths = "/etc/resolv.conf";
+      };
+    })
+  ];
+
+  meta.maintainers = with lib.maintainers; [ dtzWill ];
+}
-- 
cgit v1.2.3