Missing route that is shown in filter used by eBGP
Nico Schottelius
nico.schottelius at ungleich.ch
Thu Nov 20 13:59:48 CET 2025
Hello,
today I have a related issue with missing route export:
- In a bgp instance I use the filter "from_our_place_to_internet"
- If I run "show route filter from_our_place_to_internet" all correct
routes match
- However if I check on the other eBGP end, the route is actually *not*
received (it's not filtered, it is really not received)
- If I "hack" the filter as follows, bird DOES export the route:
# Hack 2025-11-20
if ( net ~ [ 185.203.114.0/23+ ] ) then {
print "Exporting 185.203.114.0 to internet";
accept;
}
- Some thoughts:
- The route is direct, static and babel received
- Our filter matches RTS_STATIC
- However bird seems to "prefer" the direct route
- We do not export direct marked routes, but static routes
- Is that the cause of the problem? But it is also static...
However it does not make sense to me, thus wondering:
- Why does bird show the route in the filter output?
- Why does bird show not export it via eBGP?
- Why does my hack then make it work in the end?
Details below, any help appreciated as this is driving me nuts.
Best regards,
Nico
--------------------------------------------------------------------------------
a) the affected route
bird> show route all 185.203.114.0/23
Table master4:
185.203.114.0/23 unicast [direct1 2025-11-07] * (240)
dev eth4
Type: device univ
unicast [place6_10_v4 2025-11-07] (200)
dev eth4
Type: static univ
unicast [babel1 12:47:44.565 from fe80::3eec:efff:fecb:d81b] (130/96) [00:00:00:00:93:4e:c2:43]
via 147.78.194.67 on eth1
Type: Babel univ
Babel.metric: 96
Babel.router_id: 00:00:00:00:93:4e:c2:43
bird>
b) the show route output
bird> show route filter from_our_place_to_internet
Table master4:
185.203.114.0/23 unicast [place6_10_v4 2025-11-07] (200)
dev eth4
...
c) the filter itself
filter from_our_place_to_internet {
if(!has_internet_length()) then reject;
if(is_default_route()) then reject;
if(is_from_local_asn() ||
is_emitted_by_one_of_our_asn_directly() ||
should_export_to_internet_from_customer()
) then accept;
reject;
}
... where the related functions are:
function has_internet_length() -> bool
{
if ((net.type = NET_IP6 && net.len > 48) ||
(net.type = NET_IP4 && net.len > 24)) then {
return false;
}
return true;
}
function is_v6_default() -> bool
{
if (net = ::/0) then return true;
return false;
}
function is_v4_default() -> bool
{
if (net = 0.0.0.0/0) then return true;
return false;
}
function is_default_route() -> bool
{
if(is_v6_default() || is_v4_default()) then return true;
return false;
}
function is_from_local_asn() -> bool
{
if(source = RTS_STATIC) then return true;
if(source = RTS_BGP && bgp_path.len = 0) then return true;
return false;
}
function emitted_from_one_of_our_asn() -> bool
{
if(bgp_path.last ~ our_asn) then return true;
return false;
}
function should_export_to_internet_from_customer() -> bool
{
# We don't consider non-internet networks
if(!has_internet_length()) then return false;
if (
(bgp_path.first ~ our_asn) && # received from one of our asn
(bgp_path.len = 2) && # one of our ASNs received it
(bgp_path.last ~ customer_asn) # one of our customers emitted it and we accept it
) then return true;
if (
(bgp_path.len = 1) && # we ASNs received it directly
(bgp_path.last ~ customer_asn) # one of our customers emitted it and we accept it
) then return true;
return false;
}
--
Sustainable and modern Infrastructures by ungleich.ch
More information about the Bird-users
mailing list