summary refs log tree commit diff
path: root/nixos/modules/services/networking/gvpe.nix
blob: c633ffedef4919802c07af5be49d5f521176e919 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# GNU Virtual Private Ethernet

{config, pkgs, lib, ...}:

let
  inherit (lib) mkOption mkIf;

  cfg = config.services.gvpe;

  finalConfig = if cfg.configFile != null then
    cfg.configFile
  else if cfg.configText != null then
    pkgs.writeTextFile {
      name = "gvpe.conf";
      text = cfg.configText;
    }
  else
    throw "You must either specify contents of the config file or the config file itself for GVPE";

  ifupScript = if cfg.ipAddress == null || cfg.subnet == null then
     throw "Specify IP address and subnet (with mask) for GVPE"
   else if cfg.nodename == null then
     throw "You must set node name for GVPE"
   else
   (pkgs.writeTextFile {
    name = "gvpe-if-up";
    text = ''
      #! /bin/sh

      export PATH=$PATH:${pkgs.iproute}/sbin

      ip link set $IFNAME up
      ip address add ${cfg.ipAddress} dev $IFNAME
      ip route add ${cfg.subnet} dev $IFNAME

      ${cfg.customIFSetup}
    '';
    executable = true;
  });

  exec = "${pkgs.gvpe}/sbin/gvpe -c /var/gvpe -D ${cfg.nodename} "
    + " ${cfg.nodename}.pid-file=/var/gvpe/gvpe.pid"
    + " ${cfg.nodename}.if-up=if-up"
    + " &> /var/log/gvpe";

  inherit (cfg) startOn stopOn;
in

{
  options = {
    services.gvpe = {
      enable = mkOption {
        default = false;
        description = ''
          Whether to run gvpe
        '';
      };
      startOn = mkOption {
        default = "started network-interfaces";
        description = ''
          Condition to start GVPE
        '';
      };
      stopOn = mkOption {
        default = "stopping network-interfaces";
        description = ''
          Condition to stop GVPE
        '';
      };
      nodename = mkOption {
        default = null;
        description =''
          GVPE node name
        '';
      };
      configText = mkOption {
        default = null;
        example = ''
          tcp-port = 655
          udp-port = 655
          mtu = 1480
          ifname = vpn0

          node = alpha
          hostname = alpha.example.org
          connect = always
          enable-udp = true
          enable-tcp = true
          on alpha if-up = if-up-0
          on alpha pid-file = /var/gvpe/gvpe.pid
        '';
        description = ''
          GVPE config contents
        '';
      };
      configFile = mkOption {
        default = null;
        example = "/root/my-gvpe-conf";
        description = ''
          GVPE config file, if already present
        '';
      };
      ipAddress = mkOption {
        default = null;
        description = ''
          IP address to assign to GVPE interface
        '';
      };
      subnet = mkOption {
        default = null;
        example = "10.0.0.0/8";
        description = ''
          IP subnet assigned to GVPE network
        '';
      };
      customIFSetup = mkOption {
        default = "";
        description = ''
          Additional commands to apply in ifup script
        '';
      };
    };
  };
  config = mkIf cfg.enable {
    jobs.gvpe = {
      description = "GNU Virtual Private Ethernet node";

      inherit startOn stopOn;

      preStart = ''
        mkdir -p /var/gvpe
        mkdir -p /var/gvpe/pubkey
        chown root /var/gvpe
        chmod 700 /var/gvpe
        cp ${finalConfig} /var/gvpe/gvpe.conf
        cp ${ifupScript} /var/gvpe/if-up
      '';

      inherit exec;

      respawn = true;
    };
  };
}