lol

networking.networkd: adjust autmatic mapping of bonds

Since the bonds interface changed to a lot more possible values we create a
mapping of kernel bond attribute names and values to networkd attributes.
Those match for the most part, but have to transformed slightly.

There is also an assert that unknown options won’t slip through silently.

+59 -11
+1 -1
nixos/modules/system/boot/networkd.nix
··· 79 79 checkBond = checkUnitConfig "Bond" [ 80 80 (assertOnlyFields [ 81 81 "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec" 82 - "UpDelaySec" "DownDelaySec" 82 + "UpDelaySec" "DownDelaySec" "GratuitousARP" 83 83 ]) 84 84 (assertValueOneOf "Mode" [ 85 85 "balance-rr" "active-backup" "balance-xor"
+58 -10
nixos/modules/tasks/network-interfaces-systemd.nix
··· 115 115 Name = name; 116 116 Kind = "bond"; 117 117 }; 118 - bondConfig = 119 - (optionalAttrs (bond.lacp_rate != null) { 120 - LACPTransmitRate = bond.lacp_rate; 121 - }) // (optionalAttrs (bond.miimon != null) { 122 - MIIMonitorSec = bond.miimon; 123 - }) // (optionalAttrs (bond.mode != null) { 124 - Mode = bond.mode; 125 - }) // (optionalAttrs (bond.xmit_hash_policy != null) { 126 - TransmitHashPolicy = bond.xmit_hash_policy; 127 - }); 118 + bondConfig = let 119 + # manual mapping as of 2017-02-03 120 + # man 5 systemd.netdev [BOND] 121 + # to https://www.kernel.org/doc/Documentation/networking/bonding.txt 122 + # driver options. 123 + driverOptionMapping = let 124 + trans = f: optName: { valTransform = f; optNames = [optName]; }; 125 + simp = trans id; 126 + ms = trans (v: v + "ms"); 127 + in { 128 + Mode = simp "mode"; 129 + TransmitHashPolixy = simp "xmit_hash_policy"; 130 + LACPTransmitRate = simp "lacp_rate"; 131 + MIIMonitorSec = ms "miimon"; 132 + UpDelaySec = ms "updelay"; 133 + DownDelaySec = ms "downdelay"; 134 + LearnPacketIntervalSec = simp "lp_interval"; 135 + AdSelect = simp "ad_select"; 136 + FailOverMACPolicy = simp "fail_over_mac"; 137 + ARPValidate = simp "arp_validate"; 138 + # apparently in ms for this value?! Upstream bug? 139 + ARPIntervalSec = simp "arp_interval"; 140 + ARPIPTargets = simp "arp_ip_target"; 141 + ARPAllTargets = simp "arp_all_targets"; 142 + PrimaryReselectPolicy = simp "primary_reselect"; 143 + ResendIGMP = simp "resend_igmp"; 144 + PacketsPerSlave = simp "packets_per_slave"; 145 + GratuitousARP = { valTransform = id; 146 + optNames = [ "num_grat_arp" "num_unsol_na" ]; }; 147 + AllSlavesActive = simp "all_slaves_active"; 148 + MinLinks = simp "min_links"; 149 + }; 150 + 151 + do = bond.driverOptions; 152 + assertNoUnknownOption = let 153 + knownOptions = flatten (mapAttrsToList (_: kOpts: kOpts.optNames) 154 + driverOptionMapping); 155 + # options that apparently don’t exist in the networkd config 156 + unknownOptions = [ "primary" ]; 157 + assertTrace = bool: msg: if bool then true else builtins.trace msg false; 158 + in assert all (driverOpt: assertTrace 159 + (elem driverOpt (knownOptions ++ unknownOptions)) 160 + "The bond.driverOption `${driverOpt}` cannot be mapped to the list of known networkd bond options. Please add it to the mapping above the assert or to `unknownOptions` should it not exist in networkd.") 161 + (mapAttrsToList (k: _: k) do); ""; 162 + # get those driverOptions that have been set 163 + filterSystemdOptions = filterAttrs (sysDOpt: kOpts: 164 + any (kOpt: do ? "${kOpt}") kOpts.optNames); 165 + # build final set of systemd options to bond values 166 + buildOptionSet = mapAttrs (_: kOpts: with kOpts; 167 + # we simply take the first set kernel bond option 168 + # (one option has multiple names, which is silly) 169 + head (map (optN: valTransform (do."${optN}")) 170 + # only map those that exist 171 + (filter (o: do ? "${o}") optNames))); 172 + in seq assertNoUnknownOption 173 + (buildOptionSet (filterSystemdOptions driverOptionMapping)); 174 + 128 175 }; 176 + 129 177 networks = listToAttrs (flip map bond.interfaces (bi: 130 178 nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) { 131 179 DHCP = mkOverride 0 (dhcpStr false);