nix/hosts/prefect/dn42/bird.conf

315 lines
8.9 KiB
Text

log stderr all;
debug protocols all;
timeformat protocol iso long;
################################################
# Variable header #
################################################
define OWNAS = 4242422459;
define OWNIP = 172.20.43.96;
define OWNIPv6 = fd21:1500:66b0::1;
define OWNNET = 172.20.43.96/27;
define OWNNETv6 = fd21:1500:66b0::/48;
define OWNNETSET = [172.20.43.96/29+];
define OWNNETSETv6 = [fd21:1500:66b0::/48+];
define DN42_REGION = 42;
################################################
# Header end #
################################################
router id OWNIP;
protocol device {
scan time 10;
}
/*
* Utility functions
*/
function is_self_net() {
return net ~ OWNNETSET;
}
function is_self_net_v6() {
return net ~ OWNNETSETv6;
}
function is_valid_network() {
return net ~ [
172.20.0.0/14{21,29}, # dn42
172.20.0.0/24{28,32}, # dn42 Anycast
172.21.0.0/24{28,32}, # dn42 Anycast
172.22.0.0/24{28,32}, # dn42 Anycast
172.23.0.0/24{28,32}, # dn42 Anycast
172.31.0.0/16+, # ChaosVPN
10.100.0.0/14+, # ChaosVPN
10.127.0.0/16{16,32}, # neonetwork
10.0.0.0/8{15,24} # Freifunk.net
];
}
roa4 table dn42_roa;
roa6 table dn42_roa_v6;
protocol static {
roa4 { table dn42_roa; };
include "/etc/bird/roa_dn42.conf";
};
protocol static {
roa6 { table dn42_roa_v6; };
include "/etc/bird/roa_dn42_v6.conf";
};
function is_valid_network_v6() {
return net ~ [
fd00::/8{44,64} # ULA address space as per RFC 4193
];
}
protocol kernel {
scan time 20;
ipv6 {
import none;
export filter {
if source = RTS_STATIC then reject;
krt_prefsrc = OWNIPv6;
accept;
};
};
};
protocol kernel {
scan time 20;
ipv4 {
import none;
export filter {
if source = RTS_STATIC then reject;
krt_prefsrc = OWNIP;
accept;
};
};
}
protocol static {
route OWNNET reject;
ipv4 {
import all;
export none;
};
}
protocol static {
route OWNNETv6 reject;
ipv6 {
import all;
export none;
};
}
template bgp dnpeers {
local as OWNAS;
path metric 1;
}
protocol ospf v3 {
ipv4 {
export filter {
if source = RTS_STATIC || source = RTS_BGP then reject;
accept;
};
};
area 0 {
interface "lo" {
stub;
};
interface "ospf_*"{
type pointopoint;
};
};
}
protocol ospf v3 {
ipv6 {
export filter {
if source = RTS_STATIC || source = RTS_BGP then reject;
accept;
};
};
area 0 {
interface "lo" {
stub;
};
interface "ospf_*" {
type pointopoint;
};
};
}
function update_latency(int link_latency) {
bgp_community.add((64511, link_latency));
if (64511, 9) ~ bgp_community then { bgp_community.delete([(64511, 1..8)]); return 9; }
else if (64511, 8) ~ bgp_community then { bgp_community.delete([(64511, 1..7)]); return 8; }
else if (64511, 7) ~ bgp_community then { bgp_community.delete([(64511, 1..6)]); return 7; }
else if (64511, 6) ~ bgp_community then { bgp_community.delete([(64511, 1..5)]); return 6; }
else if (64511, 5) ~ bgp_community then { bgp_community.delete([(64511, 1..4)]); return 5; }
else if (64511, 4) ~ bgp_community then { bgp_community.delete([(64511, 1..3)]); return 4; }
else if (64511, 3) ~ bgp_community then { bgp_community.delete([(64511, 1..2)]); return 3; }
else if (64511, 2) ~ bgp_community then { bgp_community.delete([(64511, 1..1)]); return 2; }
else return 1;
}
function update_bandwidth(int link_bandwidth) {
bgp_community.add((64511, link_bandwidth));
if (64511, 21) ~ bgp_community then { bgp_community.delete([(64511, 22..29)]); return 21; }
else if (64511, 22) ~ bgp_community then { bgp_community.delete([(64511, 23..29)]); return 22; }
else if (64511, 23) ~ bgp_community then { bgp_community.delete([(64511, 24..29)]); return 23; }
else if (64511, 24) ~ bgp_community then { bgp_community.delete([(64511, 25..29)]); return 24; }
else if (64511, 25) ~ bgp_community then { bgp_community.delete([(64511, 26..29)]); return 25; }
else if (64511, 26) ~ bgp_community then { bgp_community.delete([(64511, 27..29)]); return 26; }
else if (64511, 27) ~ bgp_community then { bgp_community.delete([(64511, 28..29)]); return 27; }
else if (64511, 28) ~ bgp_community then { bgp_community.delete([(64511, 29..29)]); return 28; }
else return 29;
}
function update_crypto(int link_crypto) {
bgp_community.add((64511, link_crypto));
if (64511, 31) ~ bgp_community then { bgp_community.delete([(64511, 32..34)]); return 31; }
else if (64511, 32) ~ bgp_community then { bgp_community.delete([(64511, 33..34)]); return 32; }
else if (64511, 33) ~ bgp_community then { bgp_community.delete([(64511, 34..34)]); return 33; }
else return 34;
}
function get_region() {
if (64511, 41) ~ bgp_community then { return 41; }
else if (64511, 42) ~ bgp_community then { return 42; }
else if (64511, 43) ~ bgp_community then { return 43; }
else if (64511, 44) ~ bgp_community then { return 44; }
else if (64511, 45) ~ bgp_community then { return 45; }
else if (64511, 46) ~ bgp_community then { return 46; }
else if (64511, 47) ~ bgp_community then { return 47; }
else if (64511, 48) ~ bgp_community then { return 48; }
else if (64511, 49) ~ bgp_community then { return 49; }
else if (64511, 50) ~ bgp_community then { return 50; }
else if (64511, 51) ~ bgp_community then { return 51; }
else if (64511, 52) ~ bgp_community then { return 52; }
else if (64511, 53) ~ bgp_community then { return 53; }
else return DN42_REGION;
}
function calculate_local_pref(int dn42_latency)
int pref;
{
pref = 100;
if (is_self_net() || is_self_net_v6()) then {
pref = 2000;
}
else if (bgp_path.len = 1) then {
pref = 1000;
}
else if (DN42_REGION = get_region()) then {
pref= 500;
}
else {
if (DN42_REGION > get_region()) then {
pref = 500 - ((DN42_REGION - get_region()) * 10);
}
else {
pref = 500 - ((get_region() - DN42_REGION) * 10);
}
}
pref = pref - 10*dn42_latency - 10* bgp_path.len;
if pref > 2000 then {
pref = 10;
}
return pref;
}
function update_flags(int link_latency; int link_bandwidth; int link_crypto)
int dn42_latency;
int dn42_bandwidth;
int dn42_crypto;
{
dn42_latency = update_latency(link_latency);
dn42_bandwidth = update_bandwidth(link_bandwidth) - 20;
dn42_crypto = update_crypto(link_crypto) - 30;
if dn42_bandwidth > 5 then dn42_bandwidth = 5;
bgp_local_pref = calculate_local_pref(dn42_latency);
return true;
}
function dn42_import_filter(int link_latency; int link_bandwidth; int link_crypto) {
if (is_valid_network() && !is_self_net()) || (is_valid_network_v6() && !is_self_net_v6()) then {
if roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID && roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID then {
print "[dn42] Import : ROA check failed for ", net, " ASN ", bgp_path.last, " on ", proto;
reject;
}
update_flags(link_latency, link_bandwidth, link_crypto);
if (65535, 666) ~ bgp_community then dest = RTD_BLACKHOLE;
accept;
}
print "[dn42] Import : Invalid Network for ", net, " ASN ", bgp_path.last, " on ", proto;
reject;
}
function dn42_export_filter(int link_latency; int link_bandwith; int link_crypto) {
if is_valid_network() || is_valid_network_v6() then {
# if roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID && roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID then {
# print "[dn42] Export : ROA check failed for ", net, " ASN ", bgp_path.last, " on ", proto;
# reject;
# }
if source = RTS_STATIC then bgp_community.add((64511, DN42_REGION));
update_flags(link_latency, link_bandwith, link_crypto);
accept;
}
reject;
}
protocol bgp route_collector from dnpeers {
neighbor fd42:4242:2601:ac12::1 as 4242422602;
multihop;
ipv4 {
# export all available paths to the collector
add paths tx;
# import/export filters
import none;
export filter {
# export all valid routes
if ( is_valid_network() && source ~ [ RTS_STATIC, RTS_BGP ] )
then {
accept;
}
reject;
};
};
ipv6 {
# export all available paths to the collector
add paths tx;
# import/export filters
import none;
export filter {
# export all valid routes
if ( is_valid_network_v6() && source ~ [ RTS_STATIC, RTS_BGP ] )
then {
accept;
}
reject;
};
};
}