Writing filters that change output depending on peer

Nico Schottelius nico.schottelius at ungleich.ch
Fri Sep 12 19:56:59 CEST 2025


Hello,

we are having a bit of a "special case" on various ASNs that we'd like
to implement as clean as possible in bird:

For a number of ASNs that we control we would like to emit the same set
of networks (as in filtered, the actualy networks might be different)
PLUS a test network that allows us to verify that the specific link is
working from the outside.

Or in other words:

- ASN_A sends routes defined in filter "to_outside" to EXT_ASN_1 PLUS 2001:db8:1::/48
- ASN_A sends routes defined in filter "to_outside" to EXT_ASN_2 PLUS 2001:db8:2::/48

- ASN_B sends routes defined in filter "to_outside" to EXT_ASN_3 PLUS 2001:db8:3::/48
- ASN_B sends routes defined in filter "to_outside" to EXT_ASN_4 PLUS 2001:db8:4::/48

...

The routes defined in "to_outside" are basically all locally known /48's
of a specific /32.

What I was looking for is whether I can match on the peer in the filter,
something like that:

--------------------------------------------------------------------------------
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;
}

filter to_outside {
  if(!has_internet_length()) then reject;

  case peer in
    ext_asn_1: if(net ~ [ 2001:db8:1::/48 ]) then accept;
    ext_asn_2: if(net ~ [ 2001:db8:2::/48 ]) then accept;
    ext_asn_3: if(net ~ [ 2001:db8:3::/48 ]) then accept;
    ext_asn_4: if(net ~ [ 2001:db8:4::/48 ]) then accept;
  ...

  reject;
}
--------------------------------------------------------------------------------

Obviously above syntax is not bird syntax, but I think it is clear what
I mean.


It would be possible to write some functions and then for each peer
define a different filter only differing by a single line, but it "feels
wrong" to repeat all that code:

--------------------------------------------------------------------------------
filter asn_a_to_ext_asn_1 {
  if(some_main_function()) then accept;
  if(net ~ [ 2001:db8:1::/48 ]) then accept;
}
filter asn_a_to_ext_asn_2 {
  if(some_main_function()) then accept;
  if(net ~ [ 2001:db8:1::/48 ]) then accept;
}
filter asn_b_to_ext_asn_3 {
  if(some_main_function()) then accept;
  if(net ~ [ 2001:db8:3::/48 ]) then accept;
}
filter asn_b_to_ext_asn_3 {
  if(some_main_function()) then accept;
  if(net ~ [ 2001:db8:4::/48 ]) then accept;
}

--------------------------------------------------------------------------------

How would you solve that cleanly in bird? I'm looking forward to your ideas.

BR,

Nico

--
Sustainable and modern Infrastructures by ungleich.ch


More information about the Bird-users mailing list