# SPDX-FileCopyrightText: 2020 Luke Granger-Brown # # SPDX-License-Identifier: Apache-2.0 { lib, config, pkgs, ... }: with lib; let notifyBird = pkgs.writeScript "blade-router-vrrp-bird.sh" '' #!${pkgs.runtimeShell} ENDSTATE=$3 NAME=$2 TYPE=$1 BIRDC=${pkgs.bird2}/bin/birdc case $ENDSTATE in "MASTER") $BIRDC enable export4 $BIRDC enable export6 exit 0 ;; *) $BIRDC disable export4 $BIRDC disable export6 exit 0 ;; esac ''; in { imports = [ ../lib/bgp.nix ]; options.my.blade-router = { addresses.linknet.v4 = { local = mkOption { type = types.str; }; remote = mkOption { type = types.str; }; prefixLength = mkOption { type = types.int; default = 31; }; }; addresses.linknet.v6 = { local = mkOption { type = types.str; }; remote = mkOption { type = types.str; }; prefixLength = mkOption { type = types.int; default = 126; }; }; addresses.br-public.v4 = { addr = mkOption { type = types.str; }; prefixLength = mkOption { type = types.int; default = 24; }; }; addresses.br-public.v6 = { addr = mkOption { type = types.str; }; prefixLength = mkOption { type = types.int; default = 48; }; }; addresses.br-public-vip.v4 = { addr = mkOption { type = types.str; default = "92.118.28.1"; }; prefixLength = mkOption { type = types.int; default = 24; }; }; addresses.br-public-vip.v6 = { addr = mkOption { type = types.str; default = "2a09:a441::1"; }; prefixLength = mkOption { type = types.int; default = 48; }; }; addresses.br-public-vip.v6-ll = { addr = mkOption { type = types.str; default = "fe80::f00f"; }; prefixLength = mkOption { type = types.int; default = 64; }; }; addresses.br-public-radvd-prefix = { addr = mkOption { type = types.str; default = "2a09:a441:0:ffff::"; }; prefixLength = mkOption { type = types.int; default = 64; }; }; vrrp.priority = mkOption { type = types.int; }; }; config = { boot.kernel.sysctl."net.ipv4.ip_forward" = 1; boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1; networking = { interfaces.br-public.ipv4.addresses = [{ address = config.my.blade-router.addresses.br-public.v4.addr; prefixLength = config.my.blade-router.addresses.br-public.v4.prefixLength; }]; interfaces.br-public.ipv6.addresses = [{ address = config.my.blade-router.addresses.br-public.v6.addr; prefixLength = config.my.blade-router.addresses.br-public.v6.prefixLength; }]; interfaces.en-internet.ipv4.addresses = [{ address = config.my.blade-router.addresses.linknet.v4.local; prefixLength = config.my.blade-router.addresses.linknet.v4.prefixLength; }]; interfaces.en-internet.ipv6.addresses = [{ address = config.my.blade-router.addresses.linknet.v6.local; prefixLength = config.my.blade-router.addresses.linknet.v6.prefixLength; }]; defaultGateway = config.my.blade-router.addresses.linknet.v4.remote; defaultGateway6 = config.my.blade-router.addresses.linknet.v6.remote; firewall.extraCommands = '' iptables -A INPUT -p vrrp -i br-mgmt -j ACCEPT ip6tables -A INPUT -p vrrp -i br-mgmt -j ACCEPT ''; }; services.lukegbgp = { enable = true; config = { local.routerID = config.my.blade-router.addresses.linknet.v4.local; peering.veloxserv = { local = { asn = 205479; v4 = config.my.blade-router.addresses.linknet.v4.local; v6 = config.my.blade-router.addresses.linknet.v6.local; }; remote = { asn = 3170; export_community = 4001; routers = [{ v4 = config.my.blade-router.addresses.linknet.v4.remote; v6 = config.my.blade-router.addresses.linknet.v6.remote; }]; }; }; export.v4 = [ "92.118.28.0/24" ]; export.v6 = [ "2a09:a441::/32" ]; }; }; services.keepalived = let mgmtBase = { interface = "br-mgmt"; state = "MASTER"; priority = config.my.blade-router.vrrp.priority; }; in { enable = true; vrrpInstances.mgmtGateway4 = mgmtBase // { virtualIps = [ { addr = "10.100.0.1/23"; } { addr = "${config.my.blade-router.addresses.br-public-vip.v4.addr}/${toString config.my.blade-router.addresses.br-public-vip.v4.prefixLength}"; dev = "br-public"; } ]; virtualRouterId = 1; }; vrrpInstances.mgmtGateway6 = mgmtBase // { virtualIps = [ { addr = "${config.my.blade-router.addresses.br-public-vip.v6-ll.addr}/${toString config.my.blade-router.addresses.br-public-vip.v6-ll.prefixLength}"; dev = "br-public"; } { addr = "${config.my.blade-router.addresses.br-public-vip.v6.addr}/${toString config.my.blade-router.addresses.br-public-vip.v6.prefixLength}"; dev = "br-public"; } ]; virtualRouterId = 2; }; extraGlobalDefs = '' enable_script_security script_user root ''; extraConfig = '' vrrp_sync_group mgmtGateway { group { mgmtGateway4 mgmtGateway6 } notify ${notifyBird} bird2 } ''; }; services.radvd = { enable = true; config = '' interface br-public { AdvSendAdvert on; MinRtrAdvInterval 30; MaxRtrAdvInterval 100; AdvRASrcAddress { ${config.my.blade-router.addresses.br-public-vip.v6-ll.addr}; }; prefix ${config.my.blade-router.addresses.br-public-radvd-prefix.addr}/${toString config.my.blade-router.addresses.br-public-radvd-prefix.prefixLength} { AdvOnLink on; AdvAutonomous on; AdvRouterAddr off; }; }; ''; }; }; }