at v206 5.4 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 description = '' 35 Open vSwitch package to use. 36 ''; 37 }; 38 39 ipsec = mkOption { 40 type = types.bool; 41 default = false; 42 description = '' 43 Whether to start racoon service for openvswitch. 44 ''; 45 }; 46 }; 47 48 config = mkIf cfg.enable (let 49 50 # Where the communication sockets live 51 runDir = "/var/run/openvswitch"; 52 53 # Where the config database live (can't be in nix-store) 54 stateDir = "/var/db/openvswitch"; 55 56 # The path to the an initialized version of the database 57 db = pkgs.stdenv.mkDerivation { 58 name = "vswitch.db"; 59 unpackPhase = "true"; 60 buildPhase = "true"; 61 buildInputs = with pkgs; [ 62 cfg.package 63 ]; 64 installPhase = "mkdir -p $out"; 65 }; 66 67 in (mkMerge [{ 68 69 environment.systemPackages = [ cfg.package pkgs.ipsecTools ]; 70 71 boot.kernelModules = [ "tun" "openvswitch" ]; 72 73 boot.extraModulePackages = [ cfg.package ]; 74 75 systemd.services.ovsdb = { 76 description = "Open_vSwitch Database Server"; 77 wantedBy = [ "multi-user.target" ]; 78 after = [ "systemd-udev-settle.service" ]; 79 path = [ cfg.package ]; 80 restartTriggers = [ db cfg.package ]; 81 # Create the config database 82 preStart = 83 '' 84 mkdir -p ${runDir} 85 mkdir -p /var/db/openvswitch 86 chmod +w /var/db/openvswitch 87 ${optionalString cfg.resetOnStart "rm -f /var/db/openvswitch/conf.db"} 88 if [[ ! -e /var/db/openvswitch/conf.db ]]; then 89 ${cfg.package}/bin/ovsdb-tool create \ 90 "/var/db/openvswitch/conf.db" \ 91 "${cfg.package}/share/openvswitch/vswitch.ovsschema" 92 fi 93 chmod -R +w /var/db/openvswitch 94 ''; 95 serviceConfig = { 96 ExecStart = 97 '' 98 ${cfg.package}/bin/ovsdb-server \ 99 --remote=punix:${runDir}/db.sock \ 100 --private-key=db:Open_vSwitch,SSL,private_key \ 101 --certificate=db:Open_vSwitch,SSL,certificate \ 102 --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \ 103 --unixctl=ovsdb.ctl.sock \ 104 --pidfile=/var/run/openvswitch/ovsdb.pid \ 105 --detach \ 106 /var/db/openvswitch/conf.db 107 ''; 108 Restart = "always"; 109 RestartSec = 3; 110 PIDFile = "/var/run/openvswitch/ovsdb.pid"; 111 # Use service type 'forking' to correctly determine when ovsdb-server is ready. 112 Type = "forking"; 113 }; 114 postStart = '' 115 ${cfg.package}/bin/ovs-vsctl --timeout 3 --retry --no-wait init 116 ''; 117 }; 118 119 systemd.services.vswitchd = { 120 description = "Open_vSwitch Daemon"; 121 wantedBy = [ "multi-user.target" ]; 122 bindsTo = [ "ovsdb.service" ]; 123 after = [ "ovsdb.service" ]; 124 path = [ cfg.package ]; 125 serviceConfig = { 126 ExecStart = '' 127 ${cfg.package}/bin/ovs-vswitchd \ 128 --pidfile=/var/run/openvswitch/ovs-vswitchd.pid \ 129 --detach 130 ''; 131 PIDFile = "/var/run/openvswitch/ovs-vswitchd.pid"; 132 # Use service type 'forking' to correctly determine when vswitchd is ready. 133 Type = "forking"; 134 }; 135 }; 136 137 } 138 (mkIf cfg.ipsec { 139 services.racoon.enable = true; 140 services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf"; 141 142 networking.firewall.extraCommands = '' 143 iptables -I INPUT -t mangle -p esp -j MARK --set-mark 1/1 144 iptables -I INPUT -t mangle -p udp --dport 4500 -j MARK --set-mark 1/1 145 ''; 146 147 systemd.services.ovs-monitor-ipsec = { 148 description = "Open_vSwitch Ipsec Daemon"; 149 wantedBy = [ "multi-user.target" ]; 150 requires = [ "ovsdb.service" ]; 151 before = [ "vswitchd.service" "racoon.service" ]; 152 environment.UNIXCTLPATH = "/tmp/ovsdb.ctl.sock"; 153 serviceConfig = { 154 ExecStart = '' 155 ${cfg.package}/bin/ovs-monitor-ipsec \ 156 --root-prefix ${runDir}/ipsec \ 157 --pidfile /var/run/openvswitch/ovs-monitor-ipsec.pid \ 158 --monitor --detach \ 159 unix:/var/run/openvswitch/db.sock 160 ''; 161 PIDFile = "/var/run/openvswitch/ovs-monitor-ipsec.pid"; 162 # Use service type 'forking' to correctly determine when ovs-monitor-ipsec is ready. 163 Type = "forking"; 164 }; 165 166 preStart = '' 167 rm -r ${runDir}/ipsec/etc/racoon/certs || true 168 mkdir -p ${runDir}/ipsec/{etc/racoon,etc/init.d/,usr/sbin/} 169 ln -fs ${pkgs.ipsecTools}/bin/setkey ${runDir}/ipsec/usr/sbin/setkey 170 ln -fs ${pkgs.writeScript "racoon-restart" '' 171 #!${pkgs.stdenv.shell} 172 /var/run/current-system/sw/bin/systemctl $1 racoon 173 ''} ${runDir}/ipsec/etc/init.d/racoon 174 ''; 175 }; 176 })])); 177 178}