at 16.09-beta 6.1 kB view raw
1{ config, lib, pkgs, utils, ... }: 2 3with utils; 4with lib; 5 6let 7 8 cfg = config.networking; 9 interfaces = attrValues cfg.interfaces; 10 11 interfaceIps = i: 12 i.ip4 ++ optionals cfg.enableIPv6 i.ip6 13 ++ optional (i.ipAddress != null) { 14 address = i.ipAddress; 15 prefixLength = i.prefixLength; 16 } ++ optional (cfg.enableIPv6 && i.ipv6Address != null) { 17 address = i.ipv6Address; 18 prefixLength = i.ipv6PrefixLength; 19 }; 20 21 dhcpStr = useDHCP: if useDHCP == true || useDHCP == null then "both" else "none"; 22 23 slaves = 24 concatLists (map (bond: bond.interfaces) (attrValues cfg.bonds)) 25 ++ concatLists (map (bridge: bridge.interfaces) (attrValues cfg.bridges)) 26 ++ map (sit: sit.dev) (attrValues cfg.sits) 27 ++ map (vlan: vlan.interface) (attrValues cfg.vlans); 28 29in 30 31{ 32 33 config = mkIf cfg.useNetworkd { 34 35 assertions = [ { 36 assertion = cfg.defaultGatewayWindowSize == null; 37 message = "networking.defaultGatewayWindowSize is not supported by networkd."; 38 } { 39 assertion = cfg.vswitches == {}; 40 message = "networking.vswichtes are not supported by networkd."; 41 } ] ++ flip mapAttrsToList cfg.bridges (n: { rstp, ... }: { 42 assertion = !rstp; 43 message = "networking.bridges.${n}.rstp is not supported by networkd."; 44 }); 45 46 systemd.services.dhcpcd.enable = mkDefault false; 47 48 systemd.services.network-local-commands = { 49 after = [ "systemd-networkd.service" ]; 50 bindsTo = [ "systemd-networkd.service" ]; 51 }; 52 53 systemd.network = 54 let 55 domains = cfg.search ++ (optional (cfg.domain != null) cfg.domain); 56 genericNetwork = override: { 57 DHCP = override (dhcpStr cfg.useDHCP); 58 } // optionalAttrs (cfg.defaultGateway != null) { 59 gateway = override [ cfg.defaultGateway ]; 60 } // optionalAttrs (cfg.defaultGateway6 != null) { 61 gateway = override [ cfg.defaultGateway6 ]; 62 } // optionalAttrs (domains != [ ]) { 63 domains = override domains; 64 }; 65 in mkMerge [ { 66 enable = true; 67 networks."99-main" = genericNetwork mkDefault; 68 } 69 (mkMerge (flip map interfaces (i: { 70 netdevs = mkIf i.virtual ( 71 let 72 devType = if i.virtualType != null then i.virtualType 73 else (if hasPrefix "tun" i.name then "tun" else "tap"); 74 in { 75 "40-${i.name}" = { 76 netdevConfig = { 77 Name = i.name; 78 Kind = devType; 79 }; 80 "${devType}Config" = optionalAttrs (i.virtualOwner != null) { 81 User = i.virtualOwner; 82 }; 83 }; 84 }); 85 networks."40-${i.name}" = mkMerge [ (genericNetwork mkDefault) { 86 name = mkDefault i.name; 87 DHCP = mkForce (dhcpStr 88 (if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ])); 89 address = flip map (interfaceIps i) 90 (ip: "${ip.address}/${toString ip.prefixLength}"); 91 } ]; 92 }))) 93 (mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: { 94 netdevs."40-${name}" = { 95 netdevConfig = { 96 Name = name; 97 Kind = "bridge"; 98 }; 99 }; 100 networks = listToAttrs (flip map bridge.interfaces (bi: 101 nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) { 102 DHCP = mkOverride 0 (dhcpStr false); 103 networkConfig.Bridge = name; 104 } ]))); 105 }))) 106 (mkMerge (flip mapAttrsToList cfg.bonds (name: bond: { 107 netdevs."40-${name}" = { 108 netdevConfig = { 109 Name = name; 110 Kind = "bond"; 111 }; 112 bondConfig = 113 (optionalAttrs (bond.lacp_rate != null) { 114 LACPTransmitRate = bond.lacp_rate; 115 }) // (optionalAttrs (bond.miimon != null) { 116 MIIMonitorSec = bond.miimon; 117 }) // (optionalAttrs (bond.mode != null) { 118 Mode = bond.mode; 119 }) // (optionalAttrs (bond.xmit_hash_policy != null) { 120 TransmitHashPolicy = bond.xmit_hash_policy; 121 }); 122 }; 123 networks = listToAttrs (flip map bond.interfaces (bi: 124 nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) { 125 DHCP = mkOverride 0 (dhcpStr false); 126 networkConfig.Bond = name; 127 } ]))); 128 }))) 129 (mkMerge (flip mapAttrsToList cfg.macvlans (name: macvlan: { 130 netdevs."40-${name}" = { 131 netdevConfig = { 132 Name = name; 133 Kind = "macvlan"; 134 }; 135 macvlanConfig = optionalAttrs (macvlan.mode != null) { Mode = macvlan.mode; }; 136 }; 137 networks."40-${macvlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) { 138 macvlan = [ name ]; 139 } ]); 140 }))) 141 (mkMerge (flip mapAttrsToList cfg.sits (name: sit: { 142 netdevs."40-${name}" = { 143 netdevConfig = { 144 Name = name; 145 Kind = "sit"; 146 }; 147 tunnelConfig = 148 (optionalAttrs (sit.remote != null) { 149 Remote = sit.remote; 150 }) // (optionalAttrs (sit.local != null) { 151 Local = sit.local; 152 }) // (optionalAttrs (sit.ttl != null) { 153 TTL = sit.ttl; 154 }); 155 }; 156 networks = mkIf (sit.dev != null) { 157 "40-${sit.dev}" = (mkMerge [ (genericNetwork (mkOverride 999)) { 158 tunnel = [ name ]; 159 } ]); 160 }; 161 }))) 162 (mkMerge (flip mapAttrsToList cfg.vlans (name: vlan: { 163 netdevs."40-${name}" = { 164 netdevConfig = { 165 Name = name; 166 Kind = "vlan"; 167 }; 168 vlanConfig.Id = vlan.id; 169 }; 170 networks."40-${vlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) { 171 vlan = [ name ]; 172 } ]); 173 }))) 174 ]; 175 176 # We need to prefill the slaved devices with networking options 177 # This forces the network interface creator to initialize slaves. 178 networking.interfaces = listToAttrs (map (i: nameValuePair i { }) slaves); 179 180 }; 181 182}