at 22.05-pre 6.0 kB view raw
1# Systemd services for openvswitch 2 3{ config, lib, pkgs, ... }: 4 5with lib; 6 7let 8 cfg = config.virtualisation.vswitch; 9 10in { 11 12 options.virtualisation.vswitch = { 13 enable = mkOption { 14 type = types.bool; 15 default = false; 16 description = '' 17 Whether to enable Open vSwitch. A configuration daemon (ovs-server) 18 will be started. 19 ''; 20 }; 21 22 resetOnStart = mkOption { 23 type = types.bool; 24 default = false; 25 description = '' 26 Whether to reset the Open vSwitch configuration database to a default 27 configuration on every start of the systemd <literal>ovsdb.service</literal>. 28 ''; 29 }; 30 31 package = mkOption { 32 type = types.package; 33 default = pkgs.openvswitch; 34 defaultText = literalExpression "pkgs.openvswitch"; 35 description = '' 36 Open vSwitch package to use. 37 ''; 38 }; 39 40 ipsec = mkOption { 41 type = types.bool; 42 default = false; 43 description = '' 44 Whether to start racoon service for openvswitch. 45 Supported only if openvswitch version is less than 2.6.0. 46 Use <literal>virtualisation.vswitch.package = pkgs.openvswitch-lts</literal> 47 for a version that supports ipsec over GRE. 48 ''; 49 }; 50 }; 51 52 config = mkIf cfg.enable (let 53 54 # Where the communication sockets live 55 runDir = "/run/openvswitch"; 56 57 # The path to the an initialized version of the database 58 db = pkgs.stdenv.mkDerivation { 59 name = "vswitch.db"; 60 dontUnpack = true; 61 buildPhase = "true"; 62 buildInputs = with pkgs; [ 63 cfg.package 64 ]; 65 installPhase = "mkdir -p $out"; 66 }; 67 68 in (mkMerge [{ 69 environment.systemPackages = [ cfg.package ]; 70 boot.kernelModules = [ "tun" "openvswitch" ]; 71 72 boot.extraModulePackages = [ cfg.package ]; 73 74 systemd.services.ovsdb = { 75 description = "Open_vSwitch Database Server"; 76 wantedBy = [ "multi-user.target" ]; 77 after = [ "systemd-udev-settle.service" ]; 78 path = [ cfg.package ]; 79 restartTriggers = [ db cfg.package ]; 80 # Create the config database 81 preStart = 82 '' 83 mkdir -p ${runDir} 84 mkdir -p /var/db/openvswitch 85 chmod +w /var/db/openvswitch 86 ${optionalString cfg.resetOnStart "rm -f /var/db/openvswitch/conf.db"} 87 if [[ ! -e /var/db/openvswitch/conf.db ]]; then 88 ${cfg.package}/bin/ovsdb-tool create \ 89 "/var/db/openvswitch/conf.db" \ 90 "${cfg.package}/share/openvswitch/vswitch.ovsschema" 91 fi 92 chmod -R +w /var/db/openvswitch 93 if ${cfg.package}/bin/ovsdb-tool needs-conversion /var/db/openvswitch/conf.db | grep -q "yes" 94 then 95 echo "Performing database upgrade" 96 ${cfg.package}/bin/ovsdb-tool convert /var/db/openvswitch/conf.db 97 else 98 echo "Database already up to date" 99 fi 100 ''; 101 serviceConfig = { 102 ExecStart = 103 '' 104 ${cfg.package}/bin/ovsdb-server \ 105 --remote=punix:${runDir}/db.sock \ 106 --private-key=db:Open_vSwitch,SSL,private_key \ 107 --certificate=db:Open_vSwitch,SSL,certificate \ 108 --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \ 109 --unixctl=ovsdb.ctl.sock \ 110 --pidfile=/run/openvswitch/ovsdb.pid \ 111 --detach \ 112 /var/db/openvswitch/conf.db 113 ''; 114 Restart = "always"; 115 RestartSec = 3; 116 PIDFile = "/run/openvswitch/ovsdb.pid"; 117 # Use service type 'forking' to correctly determine when ovsdb-server is ready. 118 Type = "forking"; 119 }; 120 postStart = '' 121 ${cfg.package}/bin/ovs-vsctl --timeout 3 --retry --no-wait init 122 ''; 123 }; 124 125 systemd.services.ovs-vswitchd = { 126 description = "Open_vSwitch Daemon"; 127 wantedBy = [ "multi-user.target" ]; 128 bindsTo = [ "ovsdb.service" ]; 129 after = [ "ovsdb.service" ]; 130 path = [ cfg.package ]; 131 serviceConfig = { 132 ExecStart = '' 133 ${cfg.package}/bin/ovs-vswitchd \ 134 --pidfile=/run/openvswitch/ovs-vswitchd.pid \ 135 --detach 136 ''; 137 PIDFile = "/run/openvswitch/ovs-vswitchd.pid"; 138 # Use service type 'forking' to correctly determine when vswitchd is ready. 139 Type = "forking"; 140 Restart = "always"; 141 RestartSec = 3; 142 }; 143 }; 144 145 } 146 (mkIf (cfg.ipsec && (versionOlder cfg.package.version "2.6.0")) { 147 environment.systemPackages = [ pkgs.ipsecTools ]; 148 149 services.racoon.enable = true; 150 services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf"; 151 152 networking.firewall.extraCommands = '' 153 iptables -I INPUT -t mangle -p esp -j MARK --set-mark 1/1 154 iptables -I INPUT -t mangle -p udp --dport 4500 -j MARK --set-mark 1/1 155 ''; 156 157 systemd.services.ovs-monitor-ipsec = { 158 description = "Open_vSwitch Ipsec Daemon"; 159 wantedBy = [ "multi-user.target" ]; 160 requires = [ "ovsdb.service" ]; 161 before = [ "vswitchd.service" "racoon.service" ]; 162 environment.UNIXCTLPATH = "/tmp/ovsdb.ctl.sock"; 163 serviceConfig = { 164 ExecStart = '' 165 ${cfg.package}/bin/ovs-monitor-ipsec \ 166 --root-prefix ${runDir}/ipsec \ 167 --pidfile /run/openvswitch/ovs-monitor-ipsec.pid \ 168 --monitor --detach \ 169 unix:/run/openvswitch/db.sock 170 ''; 171 PIDFile = "/run/openvswitch/ovs-monitor-ipsec.pid"; 172 # Use service type 'forking' to correctly determine when ovs-monitor-ipsec is ready. 173 Type = "forking"; 174 }; 175 176 preStart = '' 177 rm -r ${runDir}/ipsec/etc/racoon/certs || true 178 mkdir -p ${runDir}/ipsec/{etc/racoon,etc/init.d/,usr/sbin/} 179 ln -fs ${pkgs.ipsecTools}/bin/setkey ${runDir}/ipsec/usr/sbin/setkey 180 ln -fs ${pkgs.writeScript "racoon-restart" '' 181 #!${pkgs.runtimeShell} 182 /run/current-system/sw/bin/systemctl $1 racoon 183 ''} ${runDir}/ipsec/etc/init.d/racoon 184 ''; 185 }; 186 })])); 187 188 meta.maintainers = with maintainers; [ netixx ]; 189 190}