Missing route that is shown in filter used by eBGP

Nico Schottelius nico.schottelius at ungleich.ch
Fri Nov 21 09:29:12 CET 2025


Good morning Maria,

thanks for the reply, but I am a bit puzzled, in multiple cases:


- a) active vs. all routes
  I was under the impression that filtering allows me to select the best
  route, i.e. filters apply on "all routes", not on "best routes".

  Shouldn't it be the case that filters in general operate on all, not
  already filtered routes?

- b) filter output vs. export reality
  Independent of whether we filter on "all best" or "all routes", in the
  CLI the filter output shown does include the route - if the filter
  does not match, it also should not print it

- Route attribute background

  Maybe for understanding *why* the route exists as it exists:

  - Using a match on RTS_STATIC is somewhat universal and can be used in
    all of our data centers, as *if* we define a static route, we do
    want to eBGP export it
  - The main reason why it was defined in this case to be static is to
    allow the filter to grab it - otherwise it would actually not be
    needed at all
  - The main motivation is to reduce the number of special cases for
    selecting internet facing routes in the same way everywhere

- c) Multi attribute matching
  So the effective route is seen via direct, static and babel.
  My assumption in bird would be that I can select (filter) the route
  using one of the three protocol RTS_ matches to find and export the
  route.

  So what I am trying to say is that as a user I'd expect the union of
  attributes to be matching and not only the the current/best selected.

  Which seems to be what the filter output in the CLI is doing, versus
  what bird exports.

Does it make sense?

Best regards,

Nico


Maria Matejka via Bird-users <bird-users at network.cz> writes:

> Hello Nico,
>
> unless you have BGP TX Add-Path, you are exporting only the best route, which is the direct one in this case, and that’s filtered out.
>
> I would suggest to drop the direct protocol preference under the static protocol, at least for this route. Or raising the preference in the static, you may
> say something like
>
> route 185.203.114.0/23 dev eth4 { preference = 250; };
>
> for just this one route and i hope that i haven’t botched our own syntax.
>
> This should make it work.
>
> Maria
>
> On Thu, Nov 20, 2025 at 01:59:48PM +0100, Nico Schottelius via Bird-users wrote:
>
>  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
>
> -------------------------------------------------------------------------------------------------------------------------
>
>  1 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>
>
>  2 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 …
>
>  3 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
>
>> Maria Matejka (she/her) | BIRD Team Leader | CZ.NIC, z.s.p.o.
-------------- next part --------------

--
Sustainable and modern Infrastructures by ungleich.ch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 873 bytes
Desc: not available
URL: <http://trubka.network.cz/pipermail/bird-users/attachments/20251121/3410da05/attachment.sig>


More information about the Bird-users mailing list