bgpwtf/machines: init edge01.waw

This configures our WAW edge router using NixOS. This replaces our
previous Ubuntu installation.

Change-Id: Ibd72bde66ec413164401da407c5b268ad83fd3af
diff --git a/bgpwtf/machines/modules/eoip.nix b/bgpwtf/machines/modules/eoip.nix
new file mode 100644
index 0000000..5ce04f3
--- /dev/null
+++ b/bgpwtf/machines/modules/eoip.nix
@@ -0,0 +1,75 @@
+# A small Ethernet-over-IP service implementation.
+# Yes, that's the Mikrotik EoIP implementation. This one is somewhat sketchy
+# (notably, it pumps huge zero-padded frames into tap), so doesn't use it for
+# production. We currently only use it in the edge01.waw test framework to
+# bring vlans across test VMs.
+
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  eoip = pkgs.stdenv.mkDerivation {
+    pname = "eoip";
+    version = "20180119";
+    nativeBuildInputs = with pkgs; [ cmake ];
+    src = pkgs.fetchFromGitHub {
+      owner = "amphineko";
+      repo = "eoiptapd";
+      rev = "5573a905bcbc001b503308665f098e82f451dc33";
+      sha256 = "0np9dzcw5w6jarzdv2yh3mbzz0wgw10sjqyi6pxan4ipr75v1b8s";
+    };
+    installPhase = ''
+      mkdir -p $out/bin
+      cp eoiptapd $out/bin/eoiptapd
+    '';
+  };
+
+  cfg = config.hscloud.eoip;
+
+in {
+  options.hscloud.eoip = {
+    interfaces = mkOption {
+      type = with types; attrsOf (submodule {
+        options = {
+          localV4 = mkOption {
+            type = types.str;
+            description = "Local outer IPv4 address";
+          };
+          remoteV4 = mkOption {
+            type = types.str;
+            description = "Remote outer IPv4 address";
+          };
+          id = mkOption {
+            type = types.int;
+            description = "Tunnel ID";
+          };
+          parent = mkOption {
+            type = types.str;
+            description = "Parent/outer device";
+          };
+        };
+      });
+      description = ''
+        EoIP interfaces to create.
+      '';
+    };
+  };
+
+  config.systemd.services = mapAttrs' (name: value: nameValuePair "${name}-eoip" {
+    wantedBy = [ "network.target" ];
+    wants = [
+      "${name}-netdev.service"
+      "network-addresses-${value.parent}.service"
+    ];
+    after = [
+      "network-addresses-${value.parent}.service"
+    ];
+    serviceConfig = {
+      Type = "simple";
+      ExecStart = "${eoip}/bin/eoiptapd -i ${name} -l ${value.localV4} -r ${value.remoteV4} -t ${toString value.id}";
+      Restart = "always";
+      RestartSec = "1";
+    };
+  }) cfg.interfaces;
+}