1# GNU Virtual Private Ethernet
2
3{config, pkgs, lib, ...}:
4
5let
6 inherit (lib) mkOption mkIf types;
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.iproute2}/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 });
40in
41
42{
43 options = {
44 services.gvpe = {
45 enable = lib.mkEnableOption (lib.mdDoc "gvpe");
46
47 nodename = mkOption {
48 default = null;
49 type = types.nullOr types.str;
50 description =lib.mdDoc ''
51 GVPE node name
52 '';
53 };
54 configText = mkOption {
55 default = null;
56 type = types.nullOr types.lines;
57 example = ''
58 tcp-port = 655
59 udp-port = 655
60 mtu = 1480
61 ifname = vpn0
62
63 node = alpha
64 hostname = alpha.example.org
65 connect = always
66 enable-udp = true
67 enable-tcp = true
68 on alpha if-up = if-up-0
69 on alpha pid-file = /var/gvpe/gvpe.pid
70 '';
71 description = lib.mdDoc ''
72 GVPE config contents
73 '';
74 };
75 configFile = mkOption {
76 default = null;
77 type = types.nullOr types.path;
78 example = "/root/my-gvpe-conf";
79 description = lib.mdDoc ''
80 GVPE config file, if already present
81 '';
82 };
83 ipAddress = mkOption {
84 default = null;
85 type = types.nullOr types.str;
86 description = lib.mdDoc ''
87 IP address to assign to GVPE interface
88 '';
89 };
90 subnet = mkOption {
91 default = null;
92 type = types.nullOr types.str;
93 example = "10.0.0.0/8";
94 description = lib.mdDoc ''
95 IP subnet assigned to GVPE network
96 '';
97 };
98 customIFSetup = mkOption {
99 default = "";
100 type = types.lines;
101 description = lib.mdDoc ''
102 Additional commands to apply in ifup script
103 '';
104 };
105 };
106 };
107 config = mkIf cfg.enable {
108 systemd.services.gvpe = {
109 description = "GNU Virtual Private Ethernet node";
110 after = [ "network.target" ];
111 wantedBy = [ "multi-user.target" ];
112
113 preStart = ''
114 mkdir -p /var/gvpe
115 mkdir -p /var/gvpe/pubkey
116 chown root /var/gvpe
117 chmod 700 /var/gvpe
118 cp ${finalConfig} /var/gvpe/gvpe.conf
119 cp ${ifupScript} /var/gvpe/if-up
120 '';
121
122 script = "${pkgs.gvpe}/sbin/gvpe -c /var/gvpe -D ${cfg.nodename} "
123 + " ${cfg.nodename}.pid-file=/var/gvpe/gvpe.pid"
124 + " ${cfg.nodename}.if-up=if-up"
125 + " &> /var/log/gvpe";
126
127 serviceConfig.Restart = "always";
128 };
129 };
130}