1{ config, lib, pkgs, ... }:
2
3with pkgs;
4with lib;
5
6let
7 cfg = config.services.connman;
8 configFile = pkgs.writeText "connman.conf" ''
9 [General]
10 NetworkInterfaceBlacklist=${concatStringsSep "," cfg.networkInterfaceBlacklist}
11
12 ${cfg.extraConfig}
13 '';
14 enableIwd = cfg.wifi.backend == "iwd";
15in {
16
17 imports = [
18 (mkRenamedOptionModule [ "networking" "connman" ] [ "services" "connman" ])
19 ];
20
21 ###### interface
22
23 options = {
24
25 services.connman = {
26
27 enable = mkOption {
28 type = types.bool;
29 default = false;
30 description = ''
31 Whether to use ConnMan for managing your network connections.
32 '';
33 };
34
35 enableVPN = mkOption {
36 type = types.bool;
37 default = true;
38 description = ''
39 Whether to enable ConnMan VPN service.
40 '';
41 };
42
43 extraConfig = mkOption {
44 type = types.lines;
45 default = "";
46 description = ''
47 Configuration lines appended to the generated connman configuration file.
48 '';
49 };
50
51 networkInterfaceBlacklist = mkOption {
52 type = with types; listOf str;
53 default = [ "vmnet" "vboxnet" "virbr" "ifb" "ve" ];
54 description = ''
55 Default blacklisted interfaces, this includes NixOS containers interfaces (ve).
56 '';
57 };
58
59 wifi = {
60 backend = mkOption {
61 type = types.enum [ "wpa_supplicant" "iwd" ];
62 default = "wpa_supplicant";
63 description = ''
64 Specify the Wi-Fi backend used.
65 Currently supported are <option>wpa_supplicant</option> or <option>iwd</option>.
66 '';
67 };
68 };
69
70 extraFlags = mkOption {
71 type = with types; listOf str;
72 default = [ ];
73 example = [ "--nodnsproxy" ];
74 description = ''
75 Extra flags to pass to connmand
76 '';
77 };
78
79 package = mkOption {
80 type = types.path;
81 description = "The connman package / build flavor";
82 default = connman;
83 example = literalExample "pkgs.connmanFull";
84 };
85
86 };
87
88 };
89
90 ###### implementation
91
92 config = mkIf cfg.enable {
93
94 assertions = [{
95 assertion = !config.networking.useDHCP;
96 message = "You can not use services.connman with networking.useDHCP";
97 }{
98 # TODO: connman seemingly can be used along network manager and
99 # connmanFull supports this - so this should be worked out somehow
100 assertion = !config.networking.networkmanager.enable;
101 message = "You can not use services.connman with networking.networkmanager";
102 }];
103
104 environment.systemPackages = [ cfg.package ];
105
106 systemd.services.connman = {
107 description = "Connection service";
108 wantedBy = [ "multi-user.target" ];
109 after = [ "syslog.target" ] ++ optional enableIwd "iwd.service";
110 requires = optional enableIwd "iwd.service";
111 serviceConfig = {
112 Type = "dbus";
113 BusName = "net.connman";
114 Restart = "on-failure";
115 ExecStart = toString ([
116 "${cfg.package}/sbin/connmand"
117 "--config=${configFile}"
118 "--nodaemon"
119 ] ++ optional enableIwd "--wifi=iwd_agent"
120 ++ cfg.extraFlags);
121 StandardOutput = "null";
122 };
123 };
124
125 systemd.services.connman-vpn = mkIf cfg.enableVPN {
126 description = "ConnMan VPN service";
127 wantedBy = [ "multi-user.target" ];
128 after = [ "syslog.target" ];
129 before = [ "connman" ];
130 serviceConfig = {
131 Type = "dbus";
132 BusName = "net.connman.vpn";
133 ExecStart = "${cfg.package}/sbin/connman-vpnd -n";
134 StandardOutput = "null";
135 };
136 };
137
138 systemd.services.net-connman-vpn = mkIf cfg.enableVPN {
139 description = "D-BUS Service";
140 serviceConfig = {
141 Name = "net.connman.vpn";
142 before = [ "connman" ];
143 ExecStart = "${cfg.package}/sbin/connman-vpnd -n";
144 User = "root";
145 SystemdService = "connman-vpn.service";
146 };
147 };
148
149 networking = {
150 useDHCP = false;
151 wireless = {
152 enable = mkIf (!enableIwd) true;
153 iwd = mkIf enableIwd {
154 enable = true;
155 };
156 };
157 networkmanager.enable = false;
158 };
159 };
160}