From eb6f5dabcf5283835a5436025bafa22c4b16c89a Mon Sep 17 00:00:00 2001 From: 186526 Date: Mon, 26 Dec 2022 23:41:18 +0800 Subject: [PATCH] Init --- bird.conf | 4 ++ config.conf | 9 ++++ constant.conf | 43 +++++++++++++++ lib/community-net186.conf | 45 ++++++++++++++++ lib/community-peer.conf | 25 +++++++++ lib/community-transit.conf | 93 ++++++++++++++++++++++++++++++++ lib/util.conf | 35 +++++++++++++ protocol/external_network.conf | 25 +++++++++ protocol/internal_network.conf | 21 ++++++++ protocol/kernel.conf | 21 ++++++++ protocol/rpki.conf | 26 +++++++++ readme.md | 96 ++++++++++++++++++++++++++++++++++ 12 files changed, 443 insertions(+) create mode 100644 bird.conf create mode 100644 config.conf create mode 100644 constant.conf create mode 100644 lib/community-net186.conf create mode 100644 lib/community-peer.conf create mode 100644 lib/community-transit.conf create mode 100644 lib/util.conf create mode 100644 protocol/external_network.conf create mode 100644 protocol/internal_network.conf create mode 100644 protocol/kernel.conf create mode 100644 protocol/rpki.conf create mode 100644 readme.md diff --git a/bird.conf b/bird.conf new file mode 100644 index 0000000..4035486 --- /dev/null +++ b/bird.conf @@ -0,0 +1,4 @@ +include "./lib/*.conf"; +include "./config.conf"; +include "./protcol/*.conf"; +include "./bird/*.conf"; \ No newline at end of file diff --git a/config.conf b/config.conf new file mode 100644 index 0000000..bc911f0 --- /dev/null +++ b/config.conf @@ -0,0 +1,9 @@ +define LOCAL_ASN 200536; + +define DOWNSTREAM_ASN [ 140506, 200536 ]; + +define POP 101; + +define REGION 100; + +define SELFASN 4200000101; \ No newline at end of file diff --git a/constant.conf b/constant.conf new file mode 100644 index 0000000..502cccc --- /dev/null +++ b/constant.conf @@ -0,0 +1,43 @@ +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 = [ + 0.0.0.0/8+, # RFC 1122 'this' network + 10.0.0.0/8+, # RFC 1918 private space + 100.64.0.0/10+, # RFC 6598 Carrier grade nat space + 127.0.0.0/8+, # RFC 1122 localhost + 169.254.0.0/16+, # RFC 3927 link local + 172.16.0.0/12+, # RFC 1918 private space + 192.0.2.0/24+, # RFC 5737 TEST-NET-1 + 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) + 192.168.0.0/16+, # RFC 1918 private space + 198.18.0.0/15+, # RFC 2544 benchmarking + 198.51.100.0/24+, # RFC 5737 TEST-NET-2 + 203.0.113.0/24+, # RFC 5737 TEST-NET-3 + 224.0.0.0/4+, # multicast + 240.0.0.0/4+ # reserved +]; +define BOGON_PREFIXES_V6 = [ + ::/8+, # RFC 4291 IPv4-compatible, loopback, et al + 0064:ff9b::/96+, # RFC 6052 IPv4/IPv6 Translation + 0064:ff9b:1::/48+, # RFC 8215 Local-Use IPv4/IPv6 Translation + 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+, 5f00::/8+, # 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 +]; \ No newline at end of file diff --git a/lib/community-net186.conf b/lib/community-net186.conf new file mode 100644 index 0000000..82b5792 --- /dev/null +++ b/lib/community-net186.conf @@ -0,0 +1,45 @@ +filter net186_import_filter(int POPID) + int viaRegion; + bgppath public_bgp_path; +{ + public_bgp_path = delete(bgp_path, [4200000000..4225479999]); + + if filter(bgp_large_community, [(LOCAL_ASN, 120, *)]).len != 0 then bgp_large_community.add((LOCAL_ASN, 120, POP)); + if filter(bgp_large_community, [(LOCAL_ASN, 121, *)]).len != 0 then bgp_large_community.add((LOCAL_ASN, 121, REGION)); + if (LOCAL_ASN, 122, REGION) ~ bgp_large_community then bgp_large_community.add((LOCAL_ASN, 122, REGION)); + # ROUTE_DECIDER Start + if (LOCAL_ASN, 110, 2) ~ bgp_large_community then bgp_local_pref = 500; + else if (LOCAL_ASN, 110, 1) ~ bgp_large_community then bgp_local_pref = 400; + else bgp_local_pref = 300; + + viaRegion = 0; + # Route is via Europe & Africa & Middle East + if bgp_large_community ~ [(LOCAL_ASN, 122, 100), (LOCAL_ASN, 122, 300..310), (LOCAL_ASN, 122, 600)] then viaRegion = viaRegion + 1; + # Route is via America + if bgp_large_community ~ [(LOCAL_ASN, 122, 200..299)] then viaRegion = viaRegion + 1; + # Route is via East Asia & Oceania + if bgp_large_community ~ [(LOCAL_ASN, 122, 400..500)] then viaRegion = viaRegion + 1; + + if viaRegion > 2 then reject; + else if viaRegion = 2 then bgp_local_pref = bgp_local_pref - 50; + else if viaRegion then bgp_local_pref = 0; + + # Route is via China mainland but not advertise in China mainland. + if (LOCAL_ASN, 122, 430) ~ bgp_large_community && REGION != 430 && (LOCAL_ASN, 120, 430) ~ bgp_large_community then { + reject; + } + + bgp_local_pref = bgp_local_pref - filter(bgp_large_community, [(LOCAL_ASN, 122, *)]).len * 10; +}; + +filtet net186_export_filter(int POPID) { + if (65535, 65282) ~ bgp_community then { + reject; + } + + if (65535, 65283) ~ bgp_community then { + if (POPID % 10) != (POP % 10) then { + reject; + } + } +}; \ No newline at end of file diff --git a/lib/community-peer.conf b/lib/community-peer.conf new file mode 100644 index 0000000..49b88a1 --- /dev/null +++ b/lib/community-peer.conf @@ -0,0 +1,25 @@ +function is_peer_route() { + if (LOCAL_ASN, 110, 0) ~ bgp_large_community then return false; + if (LOCAL_ASN, 110, 10) ~ bgp_large_community then return false; + if bgp_path ~ [ 7018, 3320, 3257, 6830, 3356, 2914, 5511, 3491, 1239, 6453, 6762, 1299, 12956, 701, 6461, 174, 6939] then { + return false; + } + return true; +} + +filter direct_peer_import_filter(int ASN) { + if !is_valid() then reject; + pub_add_communities(ASN, 0); + pub_preprocess_communities(); + if !is_peer_route() then reject; + accept; +} + +filter direct_peer_export_filter(int ASN) { + if !is_valid() then reject; + # Delete Self eBGP Confed Path. + bgp_path.delete([4200000000..4225479999]); + pub_process_communities(ASN, 10); + if !is_peer_route() then reject; + accept; +} \ No newline at end of file diff --git a/lib/community-transit.conf b/lib/community-transit.conf new file mode 100644 index 0000000..2ebc0e7 --- /dev/null +++ b/lib/community-transit.conf @@ -0,0 +1,93 @@ + +function pub_add_communities(int ASN, int type) { + + # DIRECT PEER + if (type=0) then { + bgp_large_community.add((LOCAL_ASN, 110, 0)); + bgp_large_community.add((LOCAL_ASN, 110, 2)); + + # PEER via IX + } else if (type=1) then { + bgp_large_community.add((LOCAL_ASN, 110, 0)); + bgp_large_community.add((LOCAL_ASN, 110, 1)); +j + # UPSTREAM + }else if (type=10) then { + bgp_large_community.add((LOCAL_ASN, 110, 10)); + + # DOWNSTREAM + } else if (type=20) then { + bgp_large_community.add((LOCAL_ASN, 110, 20)); + } + + # Finished (LOCAL_ASN, 110, *); + + if (LOCAL_ASN, 120, POP) ~ bgp_large_community then bgp_large_community.add((LOCAL_ASN, 120, POP)); + if (LOCAL_ASN, 121, REGION) ~ bgp_large_community then bgp_large_community.add((LOCAL_ASN, 121, REGION)); + + # Finished (LOCAL_ASN, 120~130, *); +} + +function pub_preprocess_communities() { + if (LOCAL_ASN, 115, 1) ~ bgp_large_community then bgp_path.prepend(bgp_path.last); + if (LOCAL_ASN, 115, 3) ~ bgp_large_community then { + bgp_path.prepend(bgp_path.last); + bgp_path.prepend(bgp_path.last); + bgp_path.prepend(bgp_path.last); + } + if (LOCAL_ASN, 115, 5) ~ bgp_large_community then { + bgp_path.prepend(bgp_path.last); + bgp_path.prepend(bgp_path.last); + bgp_path.prepend(bgp_path.last); + bgp_path.prepend(bgp_path.last); + bgp_path.prepend(bgp_path.last); + } + # Finished (LOCAL_ASN, 115, *); +} + +function pub_process_communities(int ASN, int type) { + + if (LOCAL_ASN, 125, POP) ~ bgp_large_community then { + bgp_community.add((65535, 65282)); + } + + if (LOCAL_ASN, 126, REGION) ~ bgp_large_community then { + bgp_community.add((65535, 65283)); + } + + if (65535, 65281) ~ bgp_community then reject; + if (65535, 65282) ~ bgp_community then reject; + if (65535, 65283) ~ bgp_community then reject; + + if (LOCAL_ASN, 2, ASN) ~ bgp_large_community then reject + + # PEER + if (type<10) then { + if (LOCAL_ASN, 1, 1) ~ bgp_large_community then reject; + + # UPSTREAM + } else if (type=10) then { + if (LOCAL_ASN, 1, 0) ~ bgp_large_community then reject; + + # DOWNSTREAM + } else if (type=20) then { + if (LOCAL_ASN, 1, 2) ~ bgp_large_community then reject; + } + +} + +filter transit_import_filter(int ASN) { + if !is_valid() then reject; + pub_add_communities(ASN, 10); + pub_preprocess_communities(); + accept; +} + +filter transit_export_filter(int ASN) { + if !is_valid() then reject; + # Delete Self eBGP Confed Path. + bgp_path.delete([4200000000..4225479999]); + pub_process_communities(ASN, 10); + if bgp_path.last !~ DOWNSTREAM_ASN then reject; + accept; +} \ No newline at end of file diff --git a/lib/util.conf b/lib/util.conf new file mode 100644 index 0000000..44de865 --- /dev/null +++ b/lib/util.conf @@ -0,0 +1,35 @@ +include "./constant.conf"; + +function pub_is_invalid_net_length(){ + case net.type { + NET_IP4: return net.len > 24; + NET_IP6: return net.len > 48; + else: print "pub_is_valid_net_length: unexpected net.type ", net.type, " ", net; return false; + } +} + +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; +} + +function is_downstream_asn() { + if bgp_path.last ~ DOWNSTREAM_ASN then return true; + return false; +} + +function is_valid() { + if pub_is_invalid_net_length() then return false; + if is_bogon_prefix() then return false; + if is_bogon_asn() then return false; + if is_rpki_invalid() then return false; + return true; +} diff --git a/protocol/external_network.conf b/protocol/external_network.conf new file mode 100644 index 0000000..872711d --- /dev/null +++ b/protocol/external_network.conf @@ -0,0 +1,25 @@ +template bgp pub_transit { + local as LOCAL_ASN; + ipv6 { + import filter transit_import_filter(6939); + export filter transit_export_filter(6939); + } +} + +template bgp pub_peer { + local as LOCAL_ASN; + + ipv6 { + import filter direct_peer_import_filter(6939); + export filter direct_peer_export_filter(6939); + } +} + +template bgp pub_downstream { + local as LOCAL_ASN; + + ipv6 { + import filter downstream_import_filter(6939); + export filter downstream_export_filter(6939); + } +} \ No newline at end of file diff --git a/protocol/internal_network.conf b/protocol/internal_network.conf new file mode 100644 index 0000000..32b681e --- /dev/null +++ b/protocol/internal_network.conf @@ -0,0 +1,21 @@ +template bgp net186 { + local as SELFASN; + + interpret communities off; + + bfd on; + + ipv6 { + next hop self; + + gateway direct; + + import filter { + + }; + + export filter { + + }; + } +} \ No newline at end of file diff --git a/protocol/kernel.conf b/protocol/kernel.conf new file mode 100644 index 0000000..c3eaacb --- /dev/null +++ b/protocol/kernel.conf @@ -0,0 +1,21 @@ +protocol device { + scan time 5; +} + +protocol kernel { + scan time 20; + + ipv6 { + import none; + export filter { + # Blackhole (65535, 666) + if (65535, 666) ~ bgp_community then dest = RTD_BLACKHOLE; + # Blackhole (LOCAL_ASN, 0, 666) + if (LOCAL_ASN, 0, 666) ~ bgp_large_community then dest = RTD_BLACKHOLE; + # Only Announced (LOCAL_ASN, 0, 665) + if (LOCAL_ASN, 0, 665) ~ bgp_large_community then reject; + krt_prefsrc = ROUTER_IP; + accept; + } + } +} diff --git a/protocol/rpki.conf b/protocol/rpki.conf new file mode 100644 index 0000000..a91d330 --- /dev/null +++ b/protocol/rpki.conf @@ -0,0 +1,26 @@ +roa6 table pub_roa6; +roa4 table pub_roa4; + +protocol rpki pub_rpki { + roa4 { + table pub_roa4; + }; + roa6 { + table pub_roa6; + }; + remote "172.65.0.2" port 8282; + retry keep 5; + refresh keep 30; + expire 600; + transport tcp; +} + +function is_rpki_invalid() { + if (net.type = NET_IP4 && roa_check(pub_roa4, net, bgp_path.last) = ROA_INVALID ) then { + return true; + } else if (net.type = NET_IP6 && roa_check(pub_roa6, net, bgp_path.last) = ROA_INVALID) then { + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..64cac8f --- /dev/null +++ b/readme.md @@ -0,0 +1,96 @@ +# 186526 Network + +- Experimental global network +- Maintained by 186526 (@real186526) + +## BGP Communities + +### Well known BGP Communities + +| Community | Description | Action | +| -------------- | ------------ | ------------------------------------------------------------------- | +| (65535, 65281) | No Export | Prefix should not be exported outside of 186526 Network (LOCAL_ASN) | +| (65535, 65282) | No Advertise | Prefix should not be exported outside of this PoP | +| (65535, 65283) | Local AS | Prefix should not be exported outside of this region | +| (65535, 666) | Blackhole | Prefix should be blackholed at our PoP | + +### Specific BGP Communities + +> 186526 Network implements large BGP communities. + +#### System-controllable Community + +| Community | Description | +| ------------------------------- | ------------------------------------------------------- | +| (LOCAL_ASN, 110, 0) | Route learn from peer | +| (LOCAL_ASN, 110, 1) | Route learn from IX | +| (LOCAL_ASN, 110, 2) | Route learn from direct peer | +| (LOCAL_ASN, 110, 10) | Route learn from upstream | +| (LOCAL_ASN, 110, 20) | Route learn from downstream | +| (LOCAL_ASN, 120, `this PoP`) | Route learn on `this PoP` | +| (LOCAL_ASN, 121, `this region`) | Route learn in `this region` | +| (LOCAL_ASN, 122, `this region`) | Route is passed through `this region` in 186526 Network | + +#### User-controllable Community + +| Community | Action | +| ------------------------------- | -------------------------------------------------------------------------------- | +| (LOCAL_ASN, 0, 665) | Prefix should only be announced, not written to our routing table | +| (LOCAL_ASN, 0, 666) | Prefix should be blackholed at our PoP | +| (LOCAL_ASN, 1, 0) | Prefix should not be exported to all upstream | +| (LOCAL_ASN, 1, 1) | Prefix should not be exported to all peers | +| (LOCAL_ASN, 1, 2) | Prefix should not be exported to all downstream | +| (LOCAL_ASN, 2, `ASN`) | Prefix should not be exported to all `ASN` BGP sessions | +| (LOCAL_ASN, 3, `this region`) | Prefix should not be exported outside 186526 Network in `this region` | +| (LOCAL_ASN, 115, 1) | Route should be prepend 1x outside 186526 Network | +| (LOCAL_ASN, 115, 3) | Route should be prepend 3x outside 186526 Network | +| (LOCAL_ASN, 115, 5) | Route should be prepend 5x outside 186526 Network | +| (LOCAL_ASN, 125, `this PoP`) | Route should not be exported on `this PoP` to other PoPs in 186526 Network | +| (LOCAL_ASN, 126, `this region`) | Route should not be exported in `this region` to other regions in 186526 Network | + + +## Region & PoP + +### Regions + +| Name | Code | +| ---------------------------------- | ---- | +| Europe | 100 | +| East Coast of North America | 200 | +| Central North America | 210 | +| West Coast of North America | 220 | +| Central America | 230 | +| Eastern South America | 240 | +| West South America | 250 | +| North Africa | 300 | +| Southern Africa | 310 | +| East Asia (without China mainland) | 400 | +| Southeast Asia | 410 | +| South Asia | 420 | +| China mainland | 430 | +| Oceania | 500 | +| Middle East | 600 | + +### PoP + +| Name | Location | Code | Type | +| ------- | --------------------- | ---- | ---- | +| Europe | ---- | ---- | +| de-fra1 | Frankfurt am Main, DE | 101 | Core | +| uk-lhr1 | London, GB | 102 | Edge | +| nl-ams1 | Amsterdam, NL | 103 | Edge | +| lu-lux1 | Roost, LU | 104 | Core | +| America | ---- | ---- | +| us-iad1 | Ashburn, VA, US | 201 | Core | +| us-sjc1 | Fremont, CA, US | 221 | Core | +| us-lax1 | Los Angeles, CA, US | 222 | Edge | +| br-gru1 | Sao Paulo, BR | 241 | Edge | +| APAC | ---- | ---- | +| cn-hkg1 | Hong Kong SAR | 401 | Core | +| cn-tpe1 | Taipei, CN | 402 | Edge | +| jp-tyo1 | Tokyo, JP | 403 | Edge | +| sg-sin1 | Singapore | 410 | Core | +| cn-pek1 | Beijing, CN | 431 | Core | +| cn-pek2 | Beijing, CN | 432 | Edge | +| cn-can1 | Guangzhou, CN | 433 | Edge | +| au-syd1 | Sydney, AU | 501 | Core |