From bb797c1390971753f17f33882cfd477bc0f6d186 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Fri, 3 Feb 2017 02:20:47 +0100 Subject: [PATCH] networking.networkd: adjust autmatic mapping of bonds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- nixos/modules/system/boot/networkd.nix | 2 +- .../tasks/network-interfaces-systemd.nix | 68 ++++++++++++++++--- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index be70bdbf0a9..f96dde15361 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -79,7 +79,7 @@ let checkBond = checkUnitConfig "Bond" [ (assertOnlyFields [ "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec" - "UpDelaySec" "DownDelaySec" + "UpDelaySec" "DownDelaySec" "GratuitousARP" ]) (assertValueOneOf "Mode" [ "balance-rr" "active-backup" "balance-xor" diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index cd599d8b894..736292400fd 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -115,17 +115,65 @@ in Name = name; Kind = "bond"; }; - bondConfig = - (optionalAttrs (bond.lacp_rate != null) { - LACPTransmitRate = bond.lacp_rate; - }) // (optionalAttrs (bond.miimon != null) { - MIIMonitorSec = bond.miimon; - }) // (optionalAttrs (bond.mode != null) { - Mode = bond.mode; - }) // (optionalAttrs (bond.xmit_hash_policy != null) { - TransmitHashPolicy = bond.xmit_hash_policy; - }); + bondConfig = let + # manual mapping as of 2017-02-03 + # man 5 systemd.netdev [BOND] + # to https://www.kernel.org/doc/Documentation/networking/bonding.txt + # driver options. + driverOptionMapping = let + trans = f: optName: { valTransform = f; optNames = [optName]; }; + simp = trans id; + ms = trans (v: v + "ms"); + in { + Mode = simp "mode"; + TransmitHashPolixy = simp "xmit_hash_policy"; + LACPTransmitRate = simp "lacp_rate"; + MIIMonitorSec = ms "miimon"; + UpDelaySec = ms "updelay"; + DownDelaySec = ms "downdelay"; + LearnPacketIntervalSec = simp "lp_interval"; + AdSelect = simp "ad_select"; + FailOverMACPolicy = simp "fail_over_mac"; + ARPValidate = simp "arp_validate"; + # apparently in ms for this value?! Upstream bug? + ARPIntervalSec = simp "arp_interval"; + ARPIPTargets = simp "arp_ip_target"; + ARPAllTargets = simp "arp_all_targets"; + PrimaryReselectPolicy = simp "primary_reselect"; + ResendIGMP = simp "resend_igmp"; + PacketsPerSlave = simp "packets_per_slave"; + GratuitousARP = { valTransform = id; + optNames = [ "num_grat_arp" "num_unsol_na" ]; }; + AllSlavesActive = simp "all_slaves_active"; + MinLinks = simp "min_links"; + }; + + do = bond.driverOptions; + assertNoUnknownOption = let + knownOptions = flatten (mapAttrsToList (_: kOpts: kOpts.optNames) + driverOptionMapping); + # options that apparently don’t exist in the networkd config + unknownOptions = [ "primary" ]; + assertTrace = bool: msg: if bool then true else builtins.trace msg false; + in assert all (driverOpt: assertTrace + (elem driverOpt (knownOptions ++ unknownOptions)) + "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.") + (mapAttrsToList (k: _: k) do); ""; + # get those driverOptions that have been set + filterSystemdOptions = filterAttrs (sysDOpt: kOpts: + any (kOpt: do ? "${kOpt}") kOpts.optNames); + # build final set of systemd options to bond values + buildOptionSet = mapAttrs (_: kOpts: with kOpts; + # we simply take the first set kernel bond option + # (one option has multiple names, which is silly) + head (map (optN: valTransform (do."${optN}")) + # only map those that exist + (filter (o: do ? "${o}") optNames))); + in seq assertNoUnknownOption + (buildOptionSet (filterSystemdOptions driverOptionMapping)); + }; + networks = listToAttrs (flip map bond.interfaces (bi: nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) { DHCP = mkOverride 0 (dhcpStr false);