at v206 4.6 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.networking.wireless; 8 configFile = "/etc/wpa_supplicant.conf"; 9 10 ifaces = 11 cfg.interfaces ++ 12 optional (config.networking.WLANInterface != "") config.networking.WLANInterface; 13 14in 15 16{ 17 18 ###### interface 19 20 options = { 21 22 networking.WLANInterface = mkOption { 23 default = ""; 24 description = "Obsolete. Use <option>networking.wireless.interfaces</option> instead."; 25 }; 26 27 networking.wireless = { 28 enable = mkOption { 29 type = types.bool; 30 default = false; 31 description = '' 32 Whether to start <command>wpa_supplicant</command> to scan for 33 and associate with wireless networks. Note: NixOS currently 34 does not manage <command>wpa_supplicant</command>'s 35 configuration file, <filename>${configFile}</filename>. You 36 should edit this file yourself to define wireless networks, 37 WPA keys and so on (see 38 <citerefentry><refentrytitle>wpa_supplicant.conf</refentrytitle> 39 <manvolnum>5</manvolnum></citerefentry>), or use 40 networking.wireless.userControlled.* to allow users to add entries 41 through <command>wpa_cli</command> and <command>wpa_gui</command>. 42 ''; 43 }; 44 45 interfaces = mkOption { 46 type = types.listOf types.str; 47 default = []; 48 example = [ "wlan0" "wlan1" ]; 49 description = '' 50 The interfaces <command>wpa_supplicant</command> will use. If empty, it will 51 automatically use all wireless interfaces. 52 ''; 53 }; 54 55 driver = mkOption { 56 type = types.str; 57 default = "nl80211,wext"; 58 description = "Force a specific wpa_supplicant driver."; 59 }; 60 61 userControlled = { 62 enable = mkOption { 63 type = types.bool; 64 default = false; 65 description = '' 66 Allow normal users to control wpa_supplicant through wpa_gui or wpa_cli. 67 This is useful for laptop users that switch networks a lot and don't want 68 to depend on a large package such as NetworkManager just to pick nearby 69 access points. 70 71 When you want to use this, make sure ${configFile} doesn't exist. 72 It will be created for you. 73 74 Currently it is also necessary to explicitly specify networking.wireless.interfaces. 75 ''; 76 }; 77 78 group = mkOption { 79 type = types.str; 80 default = "wheel"; 81 example = "network"; 82 description = "Members of this group can control wpa_supplicant."; 83 }; 84 }; 85 }; 86 }; 87 88 89 ###### implementation 90 91 config = mkIf cfg.enable { 92 93 environment.systemPackages = [ pkgs.wpa_supplicant ]; 94 95 services.dbus.packages = [ pkgs.wpa_supplicant ]; 96 97 # FIXME: start a separate wpa_supplicant instance per interface. 98 jobs.wpa_supplicant = 99 { description = "WPA Supplicant"; 100 101 wantedBy = [ "network.target" ]; 102 103 path = [ pkgs.wpa_supplicant ]; 104 105 preStart = '' 106 touch -a ${configFile} 107 chmod 600 ${configFile} 108 '' + optionalString cfg.userControlled.enable '' 109 if [ ! -s ${configFile} ]; then 110 echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group}" >> ${configFile} 111 echo "update_config=1" >> ${configFile} 112 fi 113 ''; 114 115 script = 116 '' 117 ${if ifaces == [] then '' 118 for i in $(cd /sys/class/net && echo *); do 119 DEVTYPE= 120 source /sys/class/net/$i/uevent 121 if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then 122 ifaces="$ifaces''${ifaces:+ -N} -i$i" 123 fi 124 done 125 '' else '' 126 ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}" 127 ''} 128 exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces 129 ''; 130 }; 131 132 powerManagement.resumeCommands = 133 '' 134 ${config.systemd.package}/bin/systemctl try-restart wpa_supplicant 135 ''; 136 137 assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != []; 138 message = "user controlled wpa_supplicant needs explicit networking.wireless.interfaces";}]; 139 140 # Restart wpa_supplicant when a wlan device appears or disappears. 141 services.udev.extraRules = 142 '' 143 ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service" 144 ''; 145 146 }; 147 148}