diff --git a/docs/lab/prod/bird-ferrix.conf b/docs/lab/prod/bird-ferrix.conf index a229df9..59bc30d 100644 --- a/docs/lab/prod/bird-ferrix.conf +++ b/docs/lab/prod/bird-ferrix.conf @@ -93,8 +93,9 @@ protocol bgp ferrix # 3. 210036:0:0 announce to nobody # 4. (nothing) announce to everyone <- default # -# is the AS number on the session's "neighbor ... as N" line. For a +# is the AS a session's wrapper filter passes in (see below). For a # route server that is the route server's AS, e.g. 42476 for SwissIX. +# Sessions without their own wrapper cannot be selected individually. # # "Only to SwissIX": 210036:0:0 210036:1:42476 # "...and there only to SWITCH": add 42476:0:0 42476:1:559 @@ -107,23 +108,47 @@ function lab_export_allowed(int peer_as) return true; } -# In the export filter of EVERY eBGP session (transit, IXP route servers, -# bilateral peers), before its final reject, add this block with that -# session's neighbour AS in place of 42476: +# Wiring it into a shared export filter +# ------------------------------------- +# BIRD export filters cannot see which neighbour they are exporting to, and +# filters take no arguments; functions do. So the shared filter's body lives +# in a function taking the neighbour AS, and named filters are thin wrappers +# around it. Sessions that should be individually selectable get their own +# wrapper; every other session keeps using "peers_out" unchanged and is +# evaluated with AS 0, which means it obeys 210036:0:0 but cannot be singled +# out. Add a wrapper per neighbour as the need arises. # -# if proto = "ferrix" then { -# if !lab_export_allowed(42476) then reject; -# # Origin must appear as AS210036, matching the route6 objects. -# bgp_path.delete([ 64512..65534, 4200000000..4294967294 ]); -# # Our action communities have done their job; do not leak them. -# bgp_large_community.delete([ (MY_ASN, 0..1, *) ]); -# accept; +# function peers_out_fn(int peer_as) +# { +# bgp_med = 0; +# bgp_large_community.add((210036, 10, 2)); +# if (net = 193.36.104.0/24) then return true; +# if (net = 2a0d:d740::/48) then return true; +# if (net = 2a0d:d740:105::/48) then return true; +# if proto = "delroth_v6" then return true; +# if proto = "pkern_v6" then return true; +# if proto = "home_v4" then return true; +# if proto = "ferrix" then { +# if !lab_export_allowed(peer_as) then return false; +# # Origin must appear as AS210036, matching the route6 objects. +# bgp_path.delete([ 64512..65534, 4200000000..4294967294 ]); +# # Our action communities have done their job; do not leak them. +# bgp_large_community.delete([ (MY_ASN, 0..1, *) ]); +# return true; +# } +# return false; # } # -# The block only ever applies to routes learned from ferrix, so these +# filter peers_out { if peers_out_fn(0) then accept; reject; } +# filter peers_out_swissix { if peers_out_fn(42476) then accept; reject; } +# +# Then only the SwissIX route-server sessions change, to +# export filter peers_out_swissix; +# +# lab_export_allowed() must be defined above peers_out_fn in the file. +# +# The ferrix branch only ever applies to routes learned from ferrix, so these # communities cannot be used by anyone else to steer your other exports. -# A session that lacks the block never announces lab routes at all, which is -# the safe failure. # # Check what a session would send, without waiting for a looking glass: # birdc show route 2a0d:d741:1::/48 export all