summary refs log tree commit diff
path: root/nixos/modules/services/networking/gvpe.nix
blob: 4fad37ba15eef19bf0bf096c61393301a41faa2b (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
# GNU Virtual Private Ethernet

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

let
  inherit (lib) mkOption mkIf types;

  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.iproute2}/sbin

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

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

{
  options = {
    services.gvpe = {
      enable = lib.mkEnableOption "gvpe";

      nodename = mkOption {
        default = null;
        type = types.nullOr types.str;
        description =''
          GVPE node name
        '';
      };
      configText = mkOption {
        default = null;
        type = types.nullOr types.lines;
        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;
        type = types.nullOr types.path;
        example = "/root/my-gvpe-conf";
        description = ''
          GVPE config file, if already present
        '';
      };
      ipAddress = mkOption {
        default = null;
        type = types.nullOr types.str;
        description = ''
          IP address to assign to GVPE interface
        '';
      };
      subnet = mkOption {
        default = null;
        type = types.nullOr types.str;
        example = "10.0.0.0/8";
        description = ''
          IP subnet assigned to GVPE network
        '';
      };
      customIFSetup = mkOption {
        default = "";
        type = types.lines;
        description = ''
          Additional commands to apply in ifup script
        '';
      };
    };
  };
  config = mkIf cfg.enable {
    systemd.services.gvpe = {
      description = "GNU Virtual Private Ethernet node";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];

      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
      '';

      script = "${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";

      serviceConfig.Restart = "always";
    };
  };
}