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 = lib.mdDoc ''
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 = lib.mdDoc ''
26 Whether to reset the Open vSwitch configuration database to a default
27 configuration on every start of the systemd `ovsdb.service`.
28 '';
29 };
30
31 package = mkOption {
32 type = types.package;
33 default = pkgs.openvswitch;
34 defaultText = literalExpression "pkgs.openvswitch";
35 description = lib.mdDoc ''
36 Open vSwitch package to use.
37 '';
38 };
39 };
40
41 config = mkIf cfg.enable (let
42
43 # Where the communication sockets live
44 runDir = "/run/openvswitch";
45
46 # The path to the an initialized version of the database
47 db = pkgs.stdenv.mkDerivation {
48 name = "vswitch.db";
49 dontUnpack = true;
50 buildPhase = "true";
51 buildInputs = with pkgs; [
52 cfg.package
53 ];
54 installPhase = "mkdir -p $out";
55 };
56
57 in {
58 environment.systemPackages = [ cfg.package ];
59 boot.kernelModules = [ "tun" "openvswitch" ];
60
61 boot.extraModulePackages = [ cfg.package ];
62
63 systemd.services.ovsdb = {
64 description = "Open_vSwitch Database Server";
65 wantedBy = [ "multi-user.target" ];
66 after = [ "systemd-udev-settle.service" ];
67 path = [ cfg.package ];
68 restartTriggers = [ db cfg.package ];
69 # Create the config database
70 preStart =
71 ''
72 mkdir -p ${runDir}
73 mkdir -p /var/db/openvswitch
74 chmod +w /var/db/openvswitch
75 ${optionalString cfg.resetOnStart "rm -f /var/db/openvswitch/conf.db"}
76 if [[ ! -e /var/db/openvswitch/conf.db ]]; then
77 ${cfg.package}/bin/ovsdb-tool create \
78 "/var/db/openvswitch/conf.db" \
79 "${cfg.package}/share/openvswitch/vswitch.ovsschema"
80 fi
81 chmod -R +w /var/db/openvswitch
82 if ${cfg.package}/bin/ovsdb-tool needs-conversion /var/db/openvswitch/conf.db | grep -q "yes"
83 then
84 echo "Performing database upgrade"
85 ${cfg.package}/bin/ovsdb-tool convert /var/db/openvswitch/conf.db
86 else
87 echo "Database already up to date"
88 fi
89 '';
90 serviceConfig = {
91 ExecStart =
92 ''
93 ${cfg.package}/bin/ovsdb-server \
94 --remote=punix:${runDir}/db.sock \
95 --private-key=db:Open_vSwitch,SSL,private_key \
96 --certificate=db:Open_vSwitch,SSL,certificate \
97 --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \
98 --unixctl=ovsdb.ctl.sock \
99 --pidfile=/run/openvswitch/ovsdb.pid \
100 --detach \
101 /var/db/openvswitch/conf.db
102 '';
103 Restart = "always";
104 RestartSec = 3;
105 PIDFile = "/run/openvswitch/ovsdb.pid";
106 # Use service type 'forking' to correctly determine when ovsdb-server is ready.
107 Type = "forking";
108 };
109 postStart = ''
110 ${cfg.package}/bin/ovs-vsctl --timeout 3 --retry --no-wait init
111 '';
112 };
113
114 systemd.services.ovs-vswitchd = {
115 description = "Open_vSwitch Daemon";
116 wantedBy = [ "multi-user.target" ];
117 bindsTo = [ "ovsdb.service" ];
118 after = [ "ovsdb.service" ];
119 path = [ cfg.package ];
120 serviceConfig = {
121 ExecStart = ''
122 ${cfg.package}/bin/ovs-vswitchd \
123 --pidfile=/run/openvswitch/ovs-vswitchd.pid \
124 --detach
125 '';
126 PIDFile = "/run/openvswitch/ovs-vswitchd.pid";
127 # Use service type 'forking' to correctly determine when vswitchd is ready.
128 Type = "forking";
129 Restart = "always";
130 RestartSec = 3;
131 };
132 };
133
134 });
135
136 imports = [
137 (mkRemovedOptionModule [ "virtualisation" "vswitch" "ipsec" ] ''
138 OpenVSwitch IPSec functionality has been removed, because it depended on racoon,
139 which was removed from nixpkgs, because it was abanoded upstream.
140 '')
141 ];
142
143 meta.maintainers = with maintainers; [ netixx ];
144
145}