1# GNU Virtual Private Ethernet
2
3{config, pkgs, lib, ...}:
4
5let
6 inherit (lib) mkOption mkIf;
7
8 cfg = config.services.gvpe;
9
10 finalConfig = if cfg.configFile != null then
11 cfg.configFile
12 else if cfg.configText != null then
13 pkgs.writeTextFile {
14 name = "gvpe.conf";
15 text = cfg.configText;
16 }
17 else
18 throw "You must either specify contents of the config file or the config file itself for GVPE";
19
20 ifupScript = if cfg.ipAddress == null || cfg.subnet == null then
21 throw "Specify IP address and subnet (with mask) for GVPE"
22 else if cfg.nodename == null then
23 throw "You must set node name for GVPE"
24 else
25 (pkgs.writeTextFile {
26 name = "gvpe-if-up";
27 text = ''
28 #! /bin/sh
29
30 export PATH=$PATH:${pkgs.iproute}/sbin
31
32 ip link set $IFNAME up
33 ip address add ${cfg.ipAddress} dev $IFNAME
34 ip route add ${cfg.subnet} dev $IFNAME
35
36 ${cfg.customIFSetup}
37 '';
38 executable = true;
39 });
40
41 exec = "${pkgs.gvpe}/sbin/gvpe -c /var/gvpe -D ${cfg.nodename} "
42 + " ${cfg.nodename}.pid-file=/var/gvpe/gvpe.pid"
43 + " ${cfg.nodename}.if-up=if-up"
44 + " &> /var/log/gvpe";
45
46 inherit (cfg) startOn stopOn;
47in
48
49{
50 options = {
51 services.gvpe = {
52 enable = mkOption {
53 default = false;
54 description = ''
55 Whether to run gvpe
56 '';
57 };
58 startOn = mkOption {
59 default = "started network-interfaces";
60 description = ''
61 Condition to start GVPE
62 '';
63 };
64 stopOn = mkOption {
65 default = "stopping network-interfaces";
66 description = ''
67 Condition to stop GVPE
68 '';
69 };
70 nodename = mkOption {
71 default = null;
72 description =''
73 GVPE node name
74 '';
75 };
76 configText = mkOption {
77 default = null;
78 example = ''
79 tcp-port = 655
80 udp-port = 655
81 mtu = 1480
82 ifname = vpn0
83
84 node = alpha
85 hostname = alpha.example.org
86 connect = always
87 enable-udp = true
88 enable-tcp = true
89 on alpha if-up = if-up-0
90 on alpha pid-file = /var/gvpe/gvpe.pid
91 '';
92 description = ''
93 GVPE config contents
94 '';
95 };
96 configFile = mkOption {
97 default = null;
98 example = "/root/my-gvpe-conf";
99 description = ''
100 GVPE config file, if already present
101 '';
102 };
103 ipAddress = mkOption {
104 default = null;
105 description = ''
106 IP address to assign to GVPE interface
107 '';
108 };
109 subnet = mkOption {
110 default = null;
111 example = "10.0.0.0/8";
112 description = ''
113 IP subnet assigned to GVPE network
114 '';
115 };
116 customIFSetup = mkOption {
117 default = "";
118 description = ''
119 Additional commands to apply in ifup script
120 '';
121 };
122 };
123 };
124 config = mkIf cfg.enable {
125 jobs.gvpe = {
126 description = "GNU Virtual Private Ethernet node";
127
128 inherit startOn stopOn;
129
130 preStart = ''
131 mkdir -p /var/gvpe
132 mkdir -p /var/gvpe/pubkey
133 chown root /var/gvpe
134 chmod 700 /var/gvpe
135 cp ${finalConfig} /var/gvpe/gvpe.conf
136 cp ${ifupScript} /var/gvpe/if-up
137 '';
138
139 inherit exec;
140
141 respawn = true;
142 };
143 };
144}