# SPDX-FileCopyrightText: 2020 Luke Granger-Brown # # SPDX-License-Identifier: Apache-2.0 { lib, config, ... }: with lib; { 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::ffff"; }; 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:ffff: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.mgmtGateway = 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; }; }; 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; }; }; ''; }; }; }