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

{
  imports =
    [
      ./hardware-configuration.nix
    ];

  profiles.clerie.mercury-vm.enable = true;
  profiles.clerie.common-networking.enable = true;

  boot.loader.grub.enable = true;
  boot.loader.grub.device = "/dev/vda";

  systemd.network.networks."10-wan" = {
    matchConfig.Name = "ens20";
    address = [
      "2001:638:904:ffcb::4/64"
    ];
    routes = [
      { Gateway = "2001:638:904:ffcb::1"; }
    ];
    linkConfig.RequiredForOnline = "routable";
  };
  systemd.network.networks."10-nat-netz-mercury" = {
    matchConfig.Name = "ens18";
    address = [
      "192.168.10.27/24"
    ];
    routes = [
      { Gateway = "192.168.10.1"; }
    ];
    linkConfig.RequiredForOnline = "routable";
  };
  systemd.network.networks."10-dn42-ildix" = {
    matchConfig.Name = "ens19";
    address = [
      "fd81:edb3:71d8:ffff::13/64"
    ];
    routes = [
      # Route to dn42-ildix-service
      { Destination = "fd81:edb3:71d8::/48"; Gateway = "fd81:edb3:71d8:ffff:2953::1"; }
    ];
    linkConfig.RequiredForOnline = "no";
  };

  # Open Firewall for BGP
  networking.firewall.allowedTCPPorts = [ 179 ];
  # Open Fireall for OSPF
  networking.firewall.extraCommands = ''
  ip6tables -A INPUT -p ospfigp -j ACCEPT
  iptables -A INPUT -p ospfigp -j ACCEPT
  '';

  services.bird.enable = true;
  services.bird.package = pkgs.bird2;
  services.bird.config = ''
  router id 192.168.10.27;

  protocol direct {
    interface "ens19";
    ipv6 {
      table master6;
    };
  }

  roa6 table r6;

  protocol rpki {
    debug all;

    roa6 { table r6; };

    remote fd81:edb3:71d8:ffff::20 port 8282;

    retry keep 5;
    refresh keep 30;
    expire 600;
  }


  filter import_dn42 {
    if (roa_check(r6, net, bgp_path.last) = ROA_INVALID) then reject;
    if net ~ [fd81:edb3:71d8::/48{48,128}] then reject;
    if net ~ [fd00::/8{8,64}] then accept;
    reject;
  }

  filter export_dn42 {
    if net ~ [fd81:edb3:71d8:ffff::/64{64,128}] then reject;
    if net ~ [fd00::/8{8,64}] then accept;
    reject;
  }

  template bgp bgp_peer {
    local as 4242422953;
    graceful restart on;
    rs client;
    source address fd81:edb3:71d8:ffff::13;
    ipv6 {
      table master6;
      next hop keep;
      import keep filtered;
      import filter import_dn42;
      export filter export_dn42;
    };
  }

  protocol bgp peer_1307_max_dn42_1 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:1307::1 as 4242421307;
  }

  protocol bgp peer_3012_dn42_c_1 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:3012::2 as 4242423012;
  }

  protocol bgp peer_3012_dn42_c_2 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:3012::3 as 4242423012;
  }

  protocol bgp peer_2574_dn42_il_gw5 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:2574::5 as 4242422574;
  }

  protocol bgp peer_2574_dn42_il_gw6 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:2574::6 as 4242422574;
  }

  protocol bgp peer_3929_v0tti_dn42 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:3929::1 as 4242423929;
  }

  protocol bgp peer_2619_frainz_dn42 from bgp_peer {
    neighbor fd81:edb3:71d8:ffff:2619::1 as 4242422619;
  }

  # Internal
  protocol bgp peer_2953_dn42_ildix_service {
    local as 4242422953;
    neighbor fd81:edb3:71d8:ffff:2953::1 port 1179 as 4242422953;
    source address fd81:edb3:71d8:ffff::13;
    multihop 64;
    rr client;
    ipv6 {
      table master6;
      next hop keep;
      add paths tx;
      import filter {
        reject;
      };
      export filter {
        accept;
      };
    };
  }

  protocol device {
    scan time 10;
  }
  '';

  clerie.system-auto-upgrade = {
    allowReboot = true;
    autoUpgrade = true;
  };

  clerie.monitoring = {
    enable = true;
    id = "399";
    pubkey = "K7NkCFKSnMIgC0D5wejSpty56AYacfxE+feMsfWtHSo=";
    bird = true;
  };

  system.stateVersion = "21.03";
}