at 15.09-beta 6.0 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 } ] ++ flip mapAttrsToList cfg.bridges (n: { rstp, ... }: { 39 assertion = !rstp; 40 message = "networking.bridges.${n}.rstp is not supported by networkd."; 41 }); 42 43 systemd.services.dhcpcd.enable = mkDefault false; 44 45 systemd.services.network-local-commands = { 46 after = [ "systemd-networkd.service" ]; 47 bindsTo = [ "systemd-networkd.service" ]; 48 }; 49 50 systemd.network = 51 let 52 domains = cfg.search ++ (optional (cfg.domain != null) cfg.domain); 53 genericNetwork = override: { 54 DHCP = override (dhcpStr cfg.useDHCP); 55 } // optionalAttrs (cfg.defaultGateway != null) { 56 gateway = override [ cfg.defaultGateway ]; 57 } // optionalAttrs (cfg.defaultGateway6 != null) { 58 gateway = override [ cfg.defaultGateway6 ]; 59 } // optionalAttrs (domains != [ ]) { 60 domains = override domains; 61 }; 62 in mkMerge [ { 63 enable = true; 64 networks."99-main" = genericNetwork mkDefault; 65 } 66 (mkMerge (flip map interfaces (i: { 67 netdevs = mkIf i.virtual ( 68 let 69 devType = if i.virtualType != null then i.virtualType 70 else (if hasPrefix "tun" i.name then "tun" else "tap"); 71 in { 72 "40-${i.name}" = { 73 netdevConfig = { 74 Name = i.name; 75 Kind = devType; 76 }; 77 "${devType}Config" = optionalAttrs (i.virtualOwner != null) { 78 User = i.virtualOwner; 79 }; 80 }; 81 }); 82 networks."40-${i.name}" = mkMerge [ (genericNetwork mkDefault) { 83 name = mkDefault i.name; 84 DHCP = mkForce (dhcpStr 85 (if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ])); 86 address = flip map (interfaceIps i) 87 (ip: "${ip.address}/${toString ip.prefixLength}"); 88 } ]; 89 }))) 90 (mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: { 91 netdevs."40-${name}" = { 92 netdevConfig = { 93 Name = name; 94 Kind = "bridge"; 95 }; 96 }; 97 networks = listToAttrs (flip map bridge.interfaces (bi: 98 nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) { 99 DHCP = mkOverride 0 (dhcpStr false); 100 networkConfig.Bridge = name; 101 } ]))); 102 }))) 103 (mkMerge (flip mapAttrsToList cfg.bonds (name: bond: { 104 netdevs."40-${name}" = { 105 netdevConfig = { 106 Name = name; 107 Kind = "bond"; 108 }; 109 bondConfig = 110 (optionalAttrs (bond.lacp_rate != null) { 111 LACPTransmitRate = bond.lacp_rate; 112 }) // (optionalAttrs (bond.miimon != null) { 113 MIIMonitorSec = bond.miimon; 114 }) // (optionalAttrs (bond.mode != null) { 115 Mode = bond.mode; 116 }) // (optionalAttrs (bond.xmit_hash_policy != null) { 117 TransmitHashPolicy = bond.xmit_hash_policy; 118 }); 119 }; 120 networks = listToAttrs (flip map bond.interfaces (bi: 121 nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) { 122 DHCP = mkOverride 0 (dhcpStr false); 123 networkConfig.Bond = name; 124 } ]))); 125 }))) 126 (mkMerge (flip mapAttrsToList cfg.macvlans (name: macvlan: { 127 netdevs."40-${name}" = { 128 netdevConfig = { 129 Name = name; 130 Kind = "macvlan"; 131 }; 132 macvlanConfig = optionalAttrs (macvlan.mode != null) { Mode = macvlan.mode; }; 133 }; 134 networks."40-${macvlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) { 135 macvlan = [ name ]; 136 } ]); 137 }))) 138 (mkMerge (flip mapAttrsToList cfg.sits (name: sit: { 139 netdevs."40-${name}" = { 140 netdevConfig = { 141 Name = name; 142 Kind = "sit"; 143 }; 144 tunnelConfig = 145 (optionalAttrs (sit.remote != null) { 146 Remote = sit.remote; 147 }) // (optionalAttrs (sit.local != null) { 148 Local = sit.local; 149 }) // (optionalAttrs (sit.ttl != null) { 150 TTL = sit.ttl; 151 }); 152 }; 153 networks = mkIf (sit.dev != null) { 154 "40-${sit.dev}" = (mkMerge [ (genericNetwork (mkOverride 999)) { 155 tunnel = [ name ]; 156 } ]); 157 }; 158 }))) 159 (mkMerge (flip mapAttrsToList cfg.vlans (name: vlan: { 160 netdevs."40-${name}" = { 161 netdevConfig = { 162 Name = name; 163 Kind = "vlan"; 164 }; 165 vlanConfig.Id = vlan.id; 166 }; 167 networks."40-${vlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) { 168 vlan = [ name ]; 169 } ]); 170 }))) 171 ]; 172 173 # We need to prefill the slaved devices with networking options 174 # This forces the network interface creator to initialize slaves. 175 networking.interfaces = listToAttrs (map (i: nameValuePair i { }) slaves); 176 177 }; 178 179}