router id 103.147.22.92;
roa4 table r4;
roa6 table r6;
ipv6 table bgp_v6; #For allowed to carry downstream
ipv6 table bgp_v6_own; #For not allowed to carry downstream
log syslog all;
define LOCAL_ASN = 141011;
protocol static BGP_Prefix{
ipv6;
route 2a0c:e640:1019::/48 reject;
#route 2a0c:e640:1011::/48 via 2a0c:e640:1011::1;
}
protocol kernel { # For bgp that allow downstream
kernel table 147;
ipv6 {
table bgp_v6;
export filter {
krt_realm = 3;
accept;
};
import all;
};
}
protocol kernel { # For bgp that don't allow downstream
kernel table 247;
ipv6 {
table bgp_v6_own;
export filter {
krt_realm = 1;
accept;
};
import all;
};
}
protocol kernel {
learn;
# persist;
ipv6 {
import all;
export filter {
#krt_prefsrc = 2a0c:e640:101a::1;
accept;
};
};
}
protocol device {
scan time 60;
}
protocol direct {
#interface "dummy*";
ipv6 {
import all;
export all;
};
}
function net_len_too_long(){
case net.type {
NET_IP4: return net.len > 24; # IPv4 CIDR 大于 /24 为太长
NET_IP6: return net.len > 48; # IPv6 CIDR 大于 /48 为太长
else: print "net_len_too_long: unexpected net.type ", net.type, " ", net; return false;
}
}
define BOGON_ASNS = [
0, # RFC 7607
23456, # RFC 4893 AS_TRANS
64496..64511, # RFC 5398 and documentation/example ASNs
64512..65534, # RFC 6996 Private ASNs
65535, # RFC 7300 Last 16 bit ASN
65536..65551, # RFC 5398 and documentation/example ASNs
65552..131071, # RFC IANA reserved ASNs
4200000000..4294967294, # RFC 6996 Private ASNs
4294967295 # RFC 7300 Last 32 bit ASN
];
define BOGON_PREFIXES_V4 = [
192.88.99.0/24+,
# RFC 7526 deprecated 6to4 relay anycast. If you wish to allow this, change `24+` to `24{25,32}`(no more specific) ];
define BOGON_PREFIXES_V6 = [
::/8+, # RFC 4291 IPv4-compatible, loopback, et al
0100::/64+, # RFC 6666 Discard-Only
2001::/32{33,128}, # RFC 4380 Teredo, no more specific
2001:2::/48+, # RFC 5180 BMWG
2001:10::/28+, # RFC 4843 ORCHID
2001:db8::/32+, # RFC 3849 documentation
2002::/16+, # RFC 7526 deprecated 6to4 relay anycast. If you wish to allow this, change `16+` to `16{17,128}`(no more specific)
3ffe::/16+, # RFC 3701 old 6bone
fc00::/7+, # RFC 4193 unique local unicast
fe80::/10+, # RFC 4291 link local unicast
fec0::/10+, # RFC 3879 old site local unicast
ff00::/8+ # RFC 4291 multicast
];
function is_bogon_prefix() {
case net.type {
NET_IP4: return net ~ BOGON_PREFIXES_V4;
NET_IP6: return net ~ BOGON_PREFIXES_V6;
else: print "is_bogon_prefix: unexpected net.type ", net.type, " ", net; return false;
}
}
function is_bogon_asn() {
if bgp_path ~ BOGON_ASNS then return true;
return false;
}
protocol rpki {
# debug all;
roa4 { table r4; };
roa6 { table r6; };
retry keep 5;
refresh keep 30;
expire 600;
}
filter peer_in_v6 {
if is_bogon_asn() then {
print "is bogon asn", net, " for ASN ", bgp_path.last;
reject;
}
if is_bogon_prefix() then {
print "is bogon prefix", net, " for ASN ", bgp_path.last;
reject;
}
if (roa_check(r6, net, bgp_path.last) = ROA_INVALID) then
{
print "Ignore RPKI invalid ", net, " for ASN ", bgp_path.last;
reject;
}
accept;
}
function my_opt_prefix()
prefix set allowed_prefix;
int set allowed_prefix_origins;
{
include "/etc/bird/filters/allowed_prefix.conf";
if net ~ allowed_prefix then return true;
else return false;
}
function is_bogon() {
if is_bogon_asn() then return true;
if is_bogon_prefix() then return true;
if net_len_too_long() then return true;
return false;
}
function bgp_export()
prefix set allowed_prefix;
int set allowed_prefix_origins;
{
include "/etc/bird/filters/allowed_prefix.conf";
# print AS_HUIZE;
if net !~ allowed_prefix then {
# if net ~ OUR_PREFIXES then print " net",net," is not echo to AS_HUIZE";
return false;
}
if is_bogon() then return false;
if bgp_large_community ~ [(141011, 4, 23000)] then return false;
if proto = "BGP_Prefix" then return true;
if source != RTS_BGP then return false;
if bgp_large_community !~ [(141011, 2, 1)] then return false;
return true;
}
function bgp_export_all() {
if bgp_export() then return true;
if is_bogon_asn() then return false;
if is_bogon_prefix() then return false;
if source != RTS_BGP then return false;
return true;
}
function bgp_export_downstream() {
if is_bogon_asn() then return false;
if is_bogon_prefix() then return false;
if source != RTS_BGP then return false;
if bgp_large_community ~ [(141011, 4, 31000)] then return false;
if bgp_large_community !~ [(141011, 2, 100)] then return false;
return true;
}
template bgp tpl_bgp {
allow bgp_local_pref on;
graceful restart on;
local as LOCAL_ASN;
ipv6 {
table bgp_v6;
preference 110;
next hop self;
import filter{
if is_bogon_asn() then {
print "is bogon asn", net, " for ASN ", bgp_path.last;
reject;
}
if is_bogon_prefix() then {
print "is bogon prefix", net, " for ASN ", bgp_path.last;
reject;
}
if (roa_check(r6, net, bgp_path.last) = ROA_INVALID) then
{
print "Ignore RPKI invalid ", net, " for ASN ", bgp_path.last;
reject;
}
bgp_large_community.delete([(141011, 2, *)]);
bgp_large_community.delete([(141011, 1, *)]);
bgp_large_community.delete([(141011, 3, *)]);
bgp_large_community.add((141011, 3, 31000));
accept;
};
export filter{
#if my_opt_prefix() then bgp_path.prepend(LOCAL_ASN);
if bgp_export() then accept;
if bgp_export_downstream() then accept;
else reject;
};
};
}
template bgp tpl_bgp_own {
allow bgp_local_pref on;
graceful restart on;
local as LOCAL_ASN;
ipv6 {
table bgp_v6_own;
preference 110;
next hop self;
import filter{
if is_bogon_asn() then {
print "is bogon asn", net, " for ASN ", bgp_path.last;
reject;
}
if is_bogon_prefix() then {
print "is bogon prefix", net, " for ASN ", bgp_path.last;
reject;
}
if (roa_check(r6, net, bgp_path.last) = ROA_INVALID) then
{
print "Ignore RPKI invalid ", net, " for ASN ", bgp_path.last;
reject;
}
bgp_large_community.delete([(141011, 2, *)]);
bgp_large_community.delete([(141011, 1, *)]);
bgp_large_community.delete([(141011, 3, *)]);
bgp_large_community.add((141011, 1, 31000));
accept;
};
export filter{
#if my_opt_prefix() then bgp_path.prepend(LOCAL_ASN);
if bgp_export() then accept;
#if bgp_export_downstream() then accept;
else reject;
};
};
}
template bgp tpl_ibgp {
local as LOCAL_ASN;
graceful restart;
rr client;
direct;
ipv6 {
table bgp_v6;
next hop self;
import filter {
#if bgp_path ~ [= 141011 =] then bgp_path.delete(141011);
if is_bogon_asn() then {
print "is bogon asn", net, " for ASN ", bgp_path.last;
reject;
}
if is_bogon_prefix() then {
print "is bogon prefix", net, " for ASN ", bgp_path.last;
reject;
}
# if bgp_path ~ [= =] then {
# #bgp_path.prepend(LOCAL_ASN);
# if my_opt_prefix() then bgp_path.prepend(LOCAL_ASN);
# }
accept;
};
export filter {
if net ~ 2a0c:e640:1011::/48 then bgp_large_community.add((141011, 4, 27000));
if net ~ 2a0c:e640:1011::/48 then bgp_large_community.add((141011, 4, 24000));
if net ~ 2a0c:e640:1011::/48 then bgp_large_community.add((141011, 4, 21000));
#if net ~ 2a0c:e640:101a::/48 then bgp_large_community.add((141011, 4, 24000));
#if net ~ 2a0c:e640:101a::/48 then bgp_large_community.add((141011, 4, 21000));
#if net ~ 2a0c:e640:101a::/48 then bgp_large_community.add((141011, 4, 27000));
#if net ~ 2a0c:e640:101a::/48 then bgp_large_community.add((141011, 2, 1));
if proto = "BGP_Prefix" then bgp_large_community.add((141011, 2, 1));
# if my_opt_prefix() then bgp_path.prepend(LOCAL_ASN);
if bgp_export_all() then accept;
reject;
};
};
}
template bgp tpl_ibgp_own {
# ibgp transfer table which cannot have downstream
local as LOCAL_ASN;
graceful restart;
rr client;
direct;
ipv6 {
table bgp_v6_own;
next hop self;
import filter {
#if bgp_path ~ [= 141011 =] then bgp_path.delete(141011);
if is_bogon_asn() then {
print "is bogon asn", net, " for ASN ", bgp_path.last;
reject;
}
if is_bogon_prefix() then {
print "is bogon prefix", net, " for ASN ", bgp_path.last;
reject;
}
# if bgp_path ~ [= =] then {
# #bgp_path.prepend(LOCAL_ASN);
# if my_opt_prefix() then bgp_path.prepend(LOCAL_ASN);
# }
accept;
};
export filter {
if proto = "BGP_Prefix" then bgp_large_community.add((141011, 2, 1));
if bgp_export_all() then accept;
reject;
};
};
}
protocol pipe { # Synchronize the routing table that can carry downstream and cannot be written to the main routing table
table bgp_v6;
peer table master6;
export all;
import where proto = "BGP_Prefix" ; #Synchronize the prefixes that the local machine needs to announce into 2 tables for BGP
}
protocol pipe {
table bgp_v6_own;
peer table master6;
export all;
import where proto = "BGP_Prefix";
}
include "/etc/bird/peers/*";