diff options
author | Netix (Espinet François) <dev.espinetfrancois@gmail.com> | 2018-12-29 11:16:51 +0100 |
---|---|---|
committer | Netix (Espinet François) <dev.espinetfrancois@gmail.com> | 2019-12-15 21:16:26 +0100 |
commit | cd3597b4864935a8dc978b711a4847a6132b8a2c (patch) | |
tree | 2929b85e5b29fe4e2c4095b75a4b3ff22257b670 /nixos/modules/tasks/network-interfaces-systemd.nix | |
parent | aa4a1b01d5180f9ceee99b16dd007672aa3f2dee (diff) | |
download | nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.tar nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.tar.gz nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.tar.bz2 nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.tar.lz nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.tar.xz nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.tar.zst nixpkgs-cd3597b4864935a8dc978b711a4847a6132b8a2c.zip |
openvswitch: better integration with systemd
Systemd dependencies for scripted mode were refactored according to analysis in #34586. networking.vswitches can now be used with systemd-networkd, although they are not supported by the daemon, a nixos receipe creates the switch and attached required interfaces (just like the scripted version). Vlans and internal interfaces are implemented following the template format i.e. each interface is described using an attributeSet (vlan and type at the moment). If vlan is present, then interface is added to the vswitch with given tag (access mode). Type internal enabled vswitch to create interfaces (see openvswitch docs). Added configuration for configuring supported openFlow version on the vswitch This commit is a split from the original PR #35127.
Diffstat (limited to 'nixos/modules/tasks/network-interfaces-systemd.nix')
-rw-r--r-- | nixos/modules/tasks/network-interfaces-systemd.nix | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index 9ffa1089ee6..37b42c010a6 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -1,4 +1,4 @@ -{ config, lib, utils, ... }: +{ config, lib, utils, pkgs, ... }: with utils; with lib; @@ -18,7 +18,10 @@ let concatLists (map (bond: bond.interfaces) (attrValues cfg.bonds)) ++ concatLists (map (bridge: bridge.interfaces) (attrValues cfg.bridges)) ++ map (sit: sit.dev) (attrValues cfg.sits) - ++ map (vlan: vlan.interface) (attrValues cfg.vlans); + ++ map (vlan: vlan.interface) (attrValues cfg.vlans) + # add dependency to physical or independently created vswitch member interface + # TODO: warn the user that any address configured on those interfaces will be useless + ++ concatMap (i: attrNames (filterAttrs (_: config: config.type != "internal") i.interfaces)) (attrValues cfg.vswitches); in @@ -51,11 +54,6 @@ in networking.dhcpcd.enable = mkDefault false; - systemd.services.network-local-commands = { - after = [ "systemd-networkd.service" ]; - bindsTo = [ "systemd-networkd.service" ]; - }; - systemd.network = let domains = cfg.search ++ (optional (cfg.domain != null) cfg.domain); @@ -233,6 +231,63 @@ in # This forces the network interface creator to initialize slaves. networking.interfaces = listToAttrs (map (i: nameValuePair i { }) slaves); + systemd.services = let + # We must escape interfaces due to the systemd interpretation + subsystemDevice = interface: + "sys-subsystem-net-devices-${escapeSystemdPath interface}.device"; + # support for creating openvswitch switches + createVswitchDevice = n: v: nameValuePair "${n}-netdev" + (let + deps = map subsystemDevice (attrNames (filterAttrs (_: config: config.type != "internal") v.interfaces)); + ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules; + in + { description = "Open vSwitch Interface ${n}"; + wantedBy = [ "network.target" (subsystemDevice n) ]; + # and create bridge before systemd-networkd starts because it might create internal interfaces + before = [ "systemd-networkd.service" ]; + # shutdown the bridge when network is shutdown + partOf = [ "network.target" ]; + # requires ovs-vswitchd to be alive at all times + bindsTo = [ "ovs-vswitchd.service" ]; + # start switch after physical interfaces and vswitch daemon + after = [ "network-pre.target" "ovs-vswitchd.service" ] ++ deps; + wants = deps; # if one or more interface fails, the switch should continue to run + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + path = [ pkgs.iproute config.virtualisation.vswitch.package ]; + preStart = '' + echo "Resetting Open vSwitch ${n}..." + ovs-vsctl --if-exists del-br ${n} -- add-br ${n} \ + -- set bridge ${n} protocols=${concatStringsSep "," v.supportedOpenFlowVersions} + ''; + script = '' + echo "Configuring Open vSwitch ${n}..." + ovs-vsctl ${concatStrings (mapAttrsToList (name: config: " -- add-port ${n} ${name}" + optionalString (config.vlan != null) " tag=${toString config.vlan}") v.interfaces)} \ + ${concatStrings (mapAttrsToList (name: config: optionalString (config.type != null) " -- set interface ${name} type=${config.type}") v.interfaces)} \ + ${concatMapStrings (x: " -- set-controller ${n} " + x) v.controllers} \ + ${concatMapStrings (x: " -- " + x) (splitString "\n" v.extraOvsctlCmds)} + + + echo "Adding OpenFlow rules for Open vSwitch ${n}..." + ovs-ofctl --protocols=${v.openFlowVersion} add-flows ${n} ${ofRules} + ''; + postStop = '' + echo "Cleaning Open vSwitch ${n}" + echo "Shuting down internal ${n} interface" + ip link set ${n} down || true + echo "Deleting flows for ${n}" + ovs-ofctl --protocols=${v.openFlowVersion} del-flows ${n} || true + echo "Deleting Open vSwitch ${n}" + ovs-vsctl --if-exists del-br ${n} || true + ''; + }); + in mapAttrs' createVswitchDevice cfg.vswitches + // { + "network-local-commands" = { + after = [ "systemd-networkd.service" ]; + bindsTo = [ "systemd-networkd.service" ]; + }; + }; }; } |