cofractal-ams01: bgp-over-ipv4
This commit is contained in:
parent
756c1a3dd2
commit
9213875d8b
2 changed files with 65 additions and 19 deletions
|
@ -6,6 +6,7 @@
|
|||
{
|
||||
imports = [
|
||||
../lib/zfs.nix
|
||||
../lib/bgp.nix
|
||||
];
|
||||
|
||||
# Otherwise _this_ machine won't enumerate things properly.
|
||||
|
@ -136,5 +137,31 @@
|
|||
(bindMountSvc "/var/lib/tailscale" "tailscaled.service")
|
||||
];
|
||||
|
||||
services.lukegbgp = let
|
||||
local.asn = 205479;
|
||||
in {
|
||||
enable = true;
|
||||
config = {
|
||||
local = {
|
||||
routerID = "199.19.152.160";
|
||||
};
|
||||
export.v4 = [ ];
|
||||
peering.cofractal = {
|
||||
local = local // {
|
||||
v6 = "2a09:a446:1337:ffff::10";
|
||||
};
|
||||
remote = {
|
||||
asn = 26073;
|
||||
export_community = 6000;
|
||||
routers = [{
|
||||
v6 = "2a09:a446:1337:ffff::2";
|
||||
} {
|
||||
v6 = "2a09:a446:1337:ffff::3";
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "23.05";
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
let
|
||||
generateSnippet = base: args: lib.concatStringsSep "\n" (lib.mapAttrsToList ( ixName: ix: generateSnippetForIX (args // { ixName = ixName; ix = ix; }) ) base );
|
||||
generateSnippetForIX = { ixName, ix, ... }@args: ''
|
||||
${lib.optionalString (doesIPv4 ix) ''
|
||||
ipv4 table ${ixName}4;
|
||||
ipv6 table ${ixName}6;
|
||||
filter bgp_in_${ixName}4
|
||||
prefix set allnet;
|
||||
int set allas;
|
||||
|
@ -19,35 +19,38 @@ let
|
|||
bgp_local_pref = ${toString ix.remote.bgp_local_pref};
|
||||
accept;
|
||||
}
|
||||
filter bgp_in_${ixName}6
|
||||
prefix set allnet;
|
||||
int set allas;
|
||||
{
|
||||
if ! (avoid_martians6()) then reject;
|
||||
${if ix.remote.must_be_next_hop then "if (bgp_path.first != ${toString ix.remote.asn}) then reject;" else "# no next-hop requirement"}
|
||||
${lib.concatMapStringsSep "\n" (asn: "if (bgp_path ~ [= * ${toString asn} * =]) then reject;") ix.remote.drop_asns}
|
||||
if (bgp_path ~ [= * 16276 * =] && gw = 2001:7f8:4::3f94:2) then gw = 2001:7f8:4::3f94:1; # OVH must go via router 1; router 2 is bork.
|
||||
bgp_local_pref = ${toString ix.remote.bgp_local_pref};
|
||||
accept;
|
||||
}
|
||||
filter bgp_export_${ixName}4
|
||||
{
|
||||
if ! ((ro, ${toString ix.local.asn}, 1000) ~ bgp_ext_community) then reject;
|
||||
bgp_ext_community.delete([(ro, ${toString ix.local.asn}, *)]);
|
||||
accept;
|
||||
}
|
||||
filter bgp_export_${ixName}6
|
||||
{
|
||||
if ! ((ro, ${toString ix.local.asn}, 1000) ~ bgp_ext_community) then reject;
|
||||
bgp_ext_community.delete([(ro, ${toString ix.local.asn}, *)]);
|
||||
accept;
|
||||
}
|
||||
protocol pipe ${ixName}pipe_4 {
|
||||
table ${ixName}4;
|
||||
peer table master4;
|
||||
import ${if ix.remote.is_route_collector then "all" else "where ((ro, ${toString ix.local.asn}, ${toString ix.remote.export_community}) ~ bgp_ext_community)"};
|
||||
export filter bgp_in_${ixName}4;
|
||||
};
|
||||
''}
|
||||
|
||||
ipv6 table ${ixName}6;
|
||||
filter bgp_in_${ixName}6
|
||||
prefix set allnet;
|
||||
int set allas;
|
||||
{
|
||||
if ! (avoid_martians6()) then reject;
|
||||
${if ix.remote.must_be_next_hop then "if (bgp_path.first != ${toString ix.remote.asn}) then reject;" else "# no next-hop requirement"}
|
||||
${lib.concatMapStringsSep "\n" (asn: "if (bgp_path ~ [= * ${toString asn} * =]) then reject;") ix.remote.drop_asns}
|
||||
if (bgp_path ~ [= * 16276 * =] && gw = 2001:7f8:4::3f94:2) then gw = 2001:7f8:4::3f94:1; # OVH must go via router 1; router 2 is bork.
|
||||
bgp_local_pref = ${toString ix.remote.bgp_local_pref};
|
||||
accept;
|
||||
}
|
||||
filter bgp_export_${ixName}6
|
||||
{
|
||||
if ! ((ro, ${toString ix.local.asn}, 1000) ~ bgp_ext_community) then reject;
|
||||
bgp_ext_community.delete([(ro, ${toString ix.local.asn}, *)]);
|
||||
accept;
|
||||
}
|
||||
protocol pipe ${ixName}pipe_6 {
|
||||
table ${ixName}6;
|
||||
peer table master6;
|
||||
|
@ -55,12 +58,14 @@ let
|
|||
export filter bgp_in_${ixName}6;
|
||||
};
|
||||
'' + lib.concatImapStringsSep "\n" ( i: v: generateSnippetForRouter (args // { routerNum = i; router = v; }) ) ix.remote.routers;
|
||||
doesIPv4 = ix: (ix.local.v4 != null) || ix.v4onv6;
|
||||
enabledSnippet = { enabled ? true, ... }: "disabled ${if enabled then "off" else "on"};";
|
||||
passwordSnippet = { password ? null, ... }: if password == null then "# no password" else "password \"${password}\";";
|
||||
multihopSnippet = { multihop ? null, ... }: if multihop == null then "# not multihop" else "multihop ${toString multihop};";
|
||||
passiveSnippet = { passive, ... }: "passive ${if passive then "on" else "off"};";
|
||||
prefixLimitSnippet = limit: if limit == null then "# no import limit" else "import limit ${toString limit} action restart;";
|
||||
generateSnippetForRouter = { ixName, ix, routerNum, router, ... }: ''
|
||||
${lib.optionalString (ix.local.v4 != null) ''
|
||||
protocol bgp ${ixName}${toString routerNum}_4 {
|
||||
${enabledSnippet router}
|
||||
${passwordSnippet router}
|
||||
|
@ -77,6 +82,7 @@ let
|
|||
${prefixLimitSnippet ix.remote.prefix_limit.v4}
|
||||
};
|
||||
};
|
||||
''}
|
||||
protocol bgp ${ixName}${toString routerNum}_6 {
|
||||
${enabledSnippet router}
|
||||
${passwordSnippet router}
|
||||
|
@ -86,6 +92,14 @@ let
|
|||
neighbor ${router.v6} as ${toString ix.remote.asn};
|
||||
graceful restart on;
|
||||
long lived graceful restart on;
|
||||
${lib.optionalString (ix.v4onv6) ''
|
||||
ipv4 {
|
||||
table ${ixName}4;
|
||||
import all;
|
||||
export ${if ix.remote.is_route_collector then "all" else "filter bgp_export_${ixName}4"};
|
||||
${prefixLimitSnippet ix.remote.prefix_limit.v4}
|
||||
};
|
||||
''}
|
||||
ipv6 {
|
||||
table ${ixName}6;
|
||||
import all;
|
||||
|
@ -124,7 +138,8 @@ in {
|
|||
type = int;
|
||||
};
|
||||
v4 = mkOption { # lukegbgp.config.peering.<foo>.local.v4
|
||||
type = str;
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
v6 = mkOption { # lukegbgp.config.peering.<foo>.local.v6
|
||||
type = str;
|
||||
|
@ -132,6 +147,10 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
v4onv6 = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
remote = mkOption { # lukegbgp.config.peering.<foo>.remote
|
||||
type = submodule {
|
||||
options = {
|
||||
|
|
Loading…
Reference in a new issue